Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .claude/commands/create-d2-diagram.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Create D2 Diagram with Theme Import

You are helping create D2 diagrams in the pgflow documentation that use the shared pgflow theme.

## Quick Reference

### Basic D2 Code Block with Import

````markdown
```d2
...@../../assets/pgflow-theme.d2

direction: right

nodeA: "Node A"
nodeB: "Node B"
nodeA -> nodeB
```
````

**CRITICAL**: There MUST be a blank line after the code fence and before the import line!

## Theme File Location

The shared theme is at: `pkgs/website/src/assets/pgflow-theme.d2`

## Path Resolution

From content files, use relative path: `...@../../assets/pgflow-theme.d2`

- From `src/content/docs/*.mdx` → `../../assets/pgflow-theme.d2`
- From `src/content/docs/subdir/*.mdx` → `../../../assets/pgflow-theme.d2`

## How It Works

1. The `...@path` syntax tells D2 to import and merge the theme configuration
2. The astro-d2 plugin processes this during build
3. D2 resolves the relative path from the markdown file's location
4. The theme vars are merged with your diagram code

## Common Patterns

### Simple Workflow
````markdown
```d2
...@../../assets/pgflow-theme.d2

direction: right
start -> process -> end
```
````

### With Custom Styling
````markdown
```d2
...@../../assets/pgflow-theme.d2

direction: down

start: "Start" {
style: {
fill: "#003b34"
stroke: "#00574d"
font-color: "#a3d4cb"
}
}
```
````

## Troubleshooting

**Diagram shows code instead of rendering?**
- Ensure blank line after ` ```d2 `
- Check relative path is correct from file location

**Import not found?**
- Verify theme file exists at `src/assets/pgflow-theme.d2`
- Count directory levels correctly (`../` for each parent)
23 changes: 23 additions & 0 deletions .github/actions/setup-d2/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: 'Setup D2'
description: 'Install D2 diagramming tool with retry logic'

runs:
using: 'composite'
steps:
- name: Install D2
shell: bash
run: |
for i in 1 2 3 4 5; do
echo "Attempt $i to install D2..."
if curl -fsSL https://d2lang.com/install.sh | sh -s --; then
echo "D2 installed successfully"
break
else
if [ $i -eq 5 ]; then
echo "Failed to install D2 after 5 attempts"
exit 1
fi
echo "Install failed, retrying in 5 seconds..."
sleep 5
fi
done
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
- name: Verify NX_BASE and NX_HEAD are set
run: echo "BASE=$NX_BASE HEAD=$NX_HEAD"

- uses: ./.github/actions/setup-d2

- name: Quality gate (lint + typecheck + test)
run: pnpm nx affected -t lint typecheck test --parallel --configuration=production --base="$NX_BASE" --head="$NX_HEAD"

Expand Down Expand Up @@ -119,6 +121,8 @@ jobs:
- name: Verify NX_BASE and NX_HEAD are set
run: echo "BASE=$NX_BASE HEAD=$NX_HEAD"

- uses: ./.github/actions/setup-d2

- name: Check if website is affected
id: check-affected
run: |
Expand Down
3 changes: 3 additions & 0 deletions pkgs/website/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ pnpm-debug.log*

# macOS-specific files
.DS_Store

# generated files
public/edge-worker/
public/d2/
2 changes: 2 additions & 0 deletions pkgs/website/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import starlightSidebarTopics from 'starlight-sidebar-topics';
import robotsTxt from 'astro-robots-txt';
import starlightLlmsTxt from 'starlight-llms-txt';
import starlightContextualMenu from 'starlight-contextual-menu';
import d2 from 'astro-d2';
import { fileURLToPath } from 'url';
import path from 'path';

Expand Down Expand Up @@ -54,6 +55,7 @@ export default defineConfig({
redirects,

integrations: [
d2(),
react({
include: ['**/components/**/*.tsx'],
exclude: ['**/pages/**/*'],
Expand Down
1 change: 1 addition & 0 deletions pkgs/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@types/react-dom": "^19.1.7",
"@vercel/analytics": "^1.5.0",
"astro": "^5.7.14",
"astro-d2": "^0.8.0",
"astro-robots-txt": "^1.0.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
Expand Down
32 changes: 32 additions & 0 deletions pkgs/website/src/assets/pgflow-theme.d2
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
vars: {
d2-config: {
theme-id: 0
dark-theme-overrides: {
# Canvas background
N7: "#121a19"

# Neutrals - desaturated grays for default nodes
N1: "#e8eced"
N2: "#c5cacc"
N3: "#95a0a3"
N4: "#4a5759"
N5: "#2d3739"
N6: "#1a2324"

# Borders - neutral grays
B1: "#3a4547"
B2: "#4a5759"
B3: "#5a6769"
B4: "#1a2324"
B5: "#2d3739"
B6: "#4a5759"

# Semantic colors - intentional states
AA2: "#d97706"
AA4: "#dc2626"
AA5: "#92400e"
AB4: "#059669"
AB5: "#2563eb"
}
}
}
85 changes: 85 additions & 0 deletions pkgs/website/src/components/D2.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
import { execSync } from 'node:child_process';

const {
padding = 100,
sketch = false,
theme = 0,
darkTheme = 200,
code,
layout = 'dagre',
} = Astro.props;

// Theme configuration that will be prepended to all diagrams
const themeConfig = `vars: {
d2-config: {
theme-id: ${theme}
theme-overrides: {
# Neutrals - desaturated grays for default nodes
N1: "#e8eced"
N2: "#c5cacc"
N3: "#95a0a3"
N4: "#4a5759"
N5: "#2d3739"
N6: "#1a2324"
N7: "#ffffff"

# Borders - neutral grays
B1: "#3a4547"
B2: "#4a5759"
B3: "#5a6769"
B4: "#1a2324"
B5: "#2d3739"
B6: "#4a5759"

# Semantic colors - intentional states
AA2: "#d97706"
AA4: "#dc2626"
AA5: "#92400e"
AB4: "#059669"
AB5: "#2563eb"
}
dark-theme-overrides: {
# Neutrals - desaturated grays for default nodes
N1: "#e8eced"
N2: "#c5cacc"
N3: "#95a0a3"
N4: "#4a5759"
N5: "#2d3739"
N6: "#1a2324"
N7: "#121a19"

# Borders - neutral grays
B1: "#3a4547"
B2: "#4a5759"
B3: "#5a6769"
B4: "#1a2324"
B5: "#2d3739"
B6: "#4a5759"

# Semantic colors - intentional states
AA2: "#d97706"
AA4: "#dc2626"
AA5: "#92400e"
AB4: "#059669"
AB5: "#2563eb"
}
}
}

`;

// Prepend theme config to the user's diagram code
const fullCode = themeConfig + code;

// Generate the diagram SVG
const output = execSync(
`d2 --layout=${layout} --theme=${theme} --sketch=${sketch} --pad=${padding} --dark-theme=${darkTheme} - -`,
{
input: fullCode,
encoding: 'utf8',
}
);
---

<Fragment set:html={output} />
Loading
Loading