Skip to content

Commit 109a8fa

Browse files
feat(workflows): unified plot-prepare workflow (#535)
## Summary - Merge `bot-validate-request` + `gen-create-spec` into single `plot-prepare.yml` - Disable old workflows (renamed to `.yml.disabled`) - Add update request analysis (validates if update reason is sensible) - Update issue templates for clearer workflow ## New Workflow Flow ``` User creates Issue + plot-request label ↓ [plot-prepare.yml] (1 Claude Opus Call) ├── NEW: Duplicate check → Generate spec-id → Create branch → Create spec.md └── UPDATE: Validate spec exists → Analyze update reason → Create branch ↓ Comment with spec content + recommendation ↓ STOP ← waits for `approved` label ``` ## Test Plan - [ ] Create new plot request issue → verify spec is generated - [ ] Create update request issue → verify analysis is posted - [ ] Verify old workflows don't trigger (disabled) --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6fa3d30 commit 109a8fa

File tree

139 files changed

+2197
-1694
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+2197
-1694
lines changed

.github/ISSUE_TEMPLATE/plot-request.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Plot Request
22
description: Propose a new plot type for pyplots
3-
title: "Plot: "
3+
title: ""
44
labels: ["plot-request"]
55
body:
66
- type: markdown
@@ -11,9 +11,9 @@ body:
1111
Describe the plot you'd like to see. Our AI will:
1212
1. Check for similar existing plots
1313
2. Assign a descriptive spec ID (e.g., `scatter-regression-linear`)
14-
3. Generate implementations once approved
14+
3. Create the specification for review
1515
16-
**No need to specify an ID** - just describe what you want!
16+
**After submission:** A maintainer will review and add the `approved` label to start code generation.
1717
1818
- type: textarea
1919
id: description

.github/ISSUE_TEMPLATE/plot-update.yml

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,37 @@
11
name: Plot Update
22
description: Request updates or regeneration of an existing plot
3-
title: "[spec-id] [update] "
3+
title: "[SPEC-ID] [update] "
44
labels: ["plot-request", "update"]
55
body:
66
- type: markdown
77
attributes:
88
value: |
99
## Plot Update Request
1010
11-
Use this form to update or regenerate an existing plot.
11+
Use this to update or regenerate an existing plot.
1212
13-
**Title Format:**
14-
- `[scatter-basic] [update] Regenerate` → Regenerate all 9 libraries
15-
- `[scatter-basic] [update:seaborn] Fix colors` → Regenerate only seaborn
13+
**Important:** Replace `SPEC-ID` in the title with the actual spec ID!
1614
17-
Replace `[spec-id]` in the title with the actual spec ID (e.g., `scatter-basic`).
15+
**Title Examples:**
16+
- `[scatter-basic] [update] Regenerate all` - All 9 libraries
17+
- `[scatter-basic] [update:seaborn] Fix colors` - Only seaborn
1818
19-
After submitting, a maintainer will add the `approved` label to trigger regeneration.
19+
**After submission:** A maintainer will review and add the `approved` label to start regeneration.
20+
21+
- type: input
22+
id: spec_id
23+
attributes:
24+
label: Spec ID
25+
description: "The spec ID to update (e.g., scatter-basic). Must match the title!"
26+
placeholder: "scatter-basic"
27+
validations:
28+
required: true
2029

2130
- type: dropdown
2231
id: target_library
2332
attributes:
24-
label: Target Library (optional)
25-
description: Update only a specific library, or leave empty for all. If you select a specific library, change [update] to [update:library] in the title.
33+
label: Target Library
34+
description: "Update specific library or all? If specific, change [update] to [update:library] in title."
2635
options:
2736
- All libraries
2837
- matplotlib
@@ -35,7 +44,7 @@ body:
3544
- highcharts
3645
- letsplot
3746
validations:
38-
required: false
47+
required: true
3948

4049
- type: dropdown
4150
id: update_type
@@ -54,7 +63,7 @@ body:
5463
id: changes
5564
attributes:
5665
label: Requested Changes
57-
description: Describe the changes to the spec or implementation (Claude will update the spec first if needed)
66+
description: Describe the changes to the spec or implementation
5867
placeholder: |
5968
- Add grid lines for better readability
6069
- Change default color scheme to colorblind-friendly

.github/workflows/bot-ai-review.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,12 @@ jobs:
202202
203203
### Your Task
204204
205-
1. **Read the spec file**: `specs/${{ steps.pr.outputs.spec_id }}.md`
205+
1. **Read the spec file**: `plots/${{ steps.pr.outputs.spec_id }}/spec.md`
206206
- Note all quality criteria listed
207207
- Understand the expected visual output
208208
209209
2. **Read the ${{ steps.pr.outputs.library }} implementation**:
210-
- `plots/${{ steps.pr.outputs.library }}/*/${{ steps.pr.outputs.spec_id }}/default.py`
210+
- `plots/${{ steps.pr.outputs.spec_id }}/implementations/${{ steps.pr.outputs.library }}.py`
211211
212212
3. **Read library-specific rules**:
213213
- `prompts/library/${{ steps.pr.outputs.library }}.md`

.github/workflows/bot-auto-merge.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ jobs:
282282
- **Not Feasible:** $NOT_FEASIBLE
283283
284284
### Links
285-
- **Spec:** \`specs/$SPEC_ID.md\`
285+
- **Spec:** \`plots/$SPEC_ID/spec.md\`
286286
- **Parent Issue:** #$MAIN_ISSUE
287287
288288
Closes #$MAIN_ISSUE
@@ -394,8 +394,8 @@ jobs:
394394
SPEC_ID="${{ steps.extract.outputs.spec_id }}"
395395
LIBRARY="${{ steps.extract.outputs.library }}"
396396
397-
# Find implementation file for this library
398-
IMPL_FILE=$(find plots/$LIBRARY -name "default.py" -path "*/$SPEC_ID/*" 2>/dev/null | head -1 || echo "")
397+
# Get implementation file path
398+
IMPL_FILE="plots/${SPEC_ID}/implementations/${LIBRARY}.py"
399399
echo "impl_file=$IMPL_FILE" >> $GITHUB_OUTPUT
400400
401401
- name: Update sub-issue to merged
@@ -621,8 +621,8 @@ jobs:
621621
exit 0
622622
fi
623623
624-
# Find implementation file
625-
IMPL_FILE=$(find plots/$LIBRARY -name "default.py" -path "*/${SPEC_ID}/*" 2>/dev/null | head -1 || echo "")
624+
# Get implementation file path
625+
IMPL_FILE="plots/${SPEC_ID}/implementations/${LIBRARY}.py"
626626
627627
# Update labels
628628
gh issue edit "$SUB_ISSUE" \
@@ -736,7 +736,7 @@ jobs:
736736
- **Not Feasible:** $NOT_FEASIBLE
737737
738738
### Links
739-
- **Spec:** \`specs/$SPEC_ID.md\`
739+
- **Spec:** \`plots/$SPEC_ID/spec.md\`
740740
- **Parent Issue:** #$MAIN_ISSUE
741741
742742
Closes #$MAIN_ISSUE

.github/workflows/bot-auto-tag.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ jobs:
9797
SPEC_ID="${{ steps.extract_spec.outputs.spec_id }}"
9898
9999
# Read spec file
100-
SPEC_FILE="specs/${SPEC_ID}.md"
100+
SPEC_FILE="plots/${SPEC_ID}/spec.md"
101101
if [ -f "$SPEC_FILE" ]; then
102102
SPEC_CONTENT=$(cat "$SPEC_FILE")
103103
echo "spec_exists=true" >> $GITHUB_OUTPUT
@@ -106,8 +106,8 @@ jobs:
106106
SPEC_CONTENT=""
107107
fi
108108
109-
# Find plot files
110-
PLOT_FILES=$(find plots -name "*.py" -path "*/${SPEC_ID}/*" 2>/dev/null | head -5)
109+
# Find implementation files
110+
PLOT_FILES=$(find "plots/${SPEC_ID}/implementations" -name "*.py" 2>/dev/null | head -5)
111111
echo "plot_files<<EOF" >> $GITHUB_OUTPUT
112112
echo "$PLOT_FILES" >> $GITHUB_OUTPUT
113113
echo "EOF" >> $GITHUB_OUTPUT
@@ -121,7 +121,7 @@ jobs:
121121
SPEC_ID="${{ steps.extract_spec.outputs.spec_id }}"
122122
123123
# Read spec content
124-
SPEC_CONTENT=$(cat "specs/${SPEC_ID}.md")
124+
SPEC_CONTENT=$(cat "plots/${SPEC_ID}/spec.md")
125125
126126
# Read first plot file as example
127127
PLOT_FILE=$(echo "${{ steps.read_files.outputs.plot_files }}" | head -1)

.github/workflows/bot-validate-request.yml renamed to .github/workflows/bot-validate-request.yml.disabled

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112

113113
### Process
114114
1. Read `prompts/spec-id-generator.md` for full instructions
115-
2. List all existing specs in `specs/` directory
115+
2. List all existing specs in `plots/` directory (each subfolder has a spec.md)
116116
3. Analyze the request and check for duplicates
117117
4. Post comment using `gh issue comment ${{ github.event.issue.number }} --body "..."`
118118
5. If NEW: Update title with `gh issue edit ${{ github.event.issue.number }} --title "..."`

.github/workflows/ci-plottest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
types: [ opened, synchronize, reopened ]
77
paths:
88
- 'plots/**/*.py'
9-
- 'specs/**/*.md'
9+
- 'plots/**/spec.md'
1010

1111
jobs:
1212
test-plots:

.github/workflows/gen-create-spec.yml renamed to .github/workflows/gen-create-spec.yml.disabled

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,14 @@ jobs:
143143
SPEC_ID: ${{ steps.extract_spec.outputs.spec_id }}
144144
IS_UPDATE: ${{ steps.check.outputs.is_update }}
145145
run: |
146-
if [ -f "specs/$SPEC_ID.md" ]; then
146+
if [ -f "plots/$SPEC_ID/spec.md" ]; then
147147
echo "exists=true" >> $GITHUB_OUTPUT
148-
echo "::notice::Spec file exists: specs/$SPEC_ID.md"
148+
echo "::notice::Spec file exists: plots/$SPEC_ID/spec.md"
149149
else
150150
echo "exists=false" >> $GITHUB_OUTPUT
151151
# For updates, spec MUST exist
152152
if [[ "$IS_UPDATE" == "true" ]]; then
153-
echo "::error::Update request but spec file does not exist: specs/$SPEC_ID.md"
153+
echo "::error::Update request but spec file does not exist: plots/$SPEC_ID/spec.md"
154154
exit 1
155155
fi
156156
echo "::notice::Spec file does not exist yet (will be created)"
@@ -222,23 +222,27 @@ jobs:
222222

223223
### Instructions
224224

225-
1. Read the template: `specs/.template.md`
226-
2. Read an example spec for reference: `specs/scatter-basic.md`
227-
3. Read the spec validator rules: `prompts/spec-validator.md`
225+
1. Read the template: `prompts/templates/spec.md`
226+
2. Read the metadata template: `prompts/templates/metadata.yaml`
227+
3. Read an example spec for reference: `plots/scatter-basic/spec.md`
228+
4. Read the spec validator rules: `prompts/spec-validator.md`
228229

229-
4. Create the spec file at: `specs/${{ steps.extract_spec.outputs.spec_id }}.md`
230+
5. Create the plot directory and files:
231+
- Create directory: `plots/${{ steps.extract_spec.outputs.spec_id }}/`
232+
- Create spec file: `plots/${{ steps.extract_spec.outputs.spec_id }}/spec.md`
233+
- Create metadata file: `plots/${{ steps.extract_spec.outputs.spec_id }}/metadata.yaml`
234+
- Create implementations folder: `plots/${{ steps.extract_spec.outputs.spec_id }}/implementations/`
230235
- Follow the template structure exactly
231-
- Keep it simple and focused (description, data, tags, use cases)
232-
- Include example data if helpful (inline or dataset reference)
236+
- Keep it simple and focused (Description, Applications, Data, Notes)
233237
- Include realistic use cases with domain context
234238

235-
5. Do NOT commit or push - just create the file
239+
6. Do NOT commit or push - just create the files
236240

237241
### Quality Requirements
238-
- All required sections: Title, Description, Data, Tags, Use Cases
242+
- Spec must have sections: Title, Description, Applications, Data, Notes
239243
- Description should clearly explain what the plot visualizes
240-
- Data section should list required columns with types
241-
- Use cases should be realistic and varied
244+
- Data section should list required variables with types
245+
- Applications should be realistic and varied
242246
- Keep it concise - AI uses central prompts for implementation details
243247

244248
- name: Commit and push spec file
@@ -261,9 +265,9 @@ jobs:
261265
exit 0
262266
fi
263267

264-
# For new specs: check if spec file was created
265-
if [ -f "specs/$SPEC_ID.md" ]; then
266-
git add "specs/$SPEC_ID.md"
268+
# For new specs: check if spec directory was created
269+
if [ -d "plots/$SPEC_ID" ] && [ -f "plots/$SPEC_ID/spec.md" ]; then
270+
git add "plots/$SPEC_ID/"
267271

268272
# Check if there are changes to commit
269273
if git diff --cached --quiet; then
@@ -273,10 +277,10 @@ jobs:
273277

274278
Created from issue #$ISSUE_NUMBER"
275279
git push -u origin "$BRANCH"
276-
echo "::notice::Pushed spec file to $BRANCH"
280+
echo "::notice::Pushed spec files to $BRANCH"
277281
fi
278282
else
279-
echo "::error::Spec file was not created by Claude"
283+
echo "::error::Spec directory was not created by Claude"
280284
exit 1
281285
fi
282286

@@ -313,7 +317,7 @@ jobs:
313317

314318
**Spec ID:** \`$SPEC_ID\`
315319
**Branch:** \`$BRANCH\`
316-
**File:** \`specs/$SPEC_ID.md\`
320+
**Directory:** \`plots/$SPEC_ID/\`
317321

318322
### Next Steps
319323
Triggering code generation for all 9 libraries...

.github/workflows/gen-library-impl.yml

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,29 +158,27 @@ jobs:
158158
2. `prompts/default-style-guide.md` - Visual style requirements (colors, fonts, dimensions)
159159
3. `prompts/quality-criteria.md` - Quality requirements
160160
4. `prompts/library/${{ inputs.library }}.md` - Library-specific rules
161-
5. `specs/${{ inputs.spec_id }}.md` - The specification
161+
5. `plots/${{ inputs.spec_id }}/spec.md` - The specification
162162
163163
### Step 2: Check for previous attempts
164164
${{ steps.previous_attempts.outputs.has_history == 'true' && 'IMPORTANT: There are previous failed attempts. Read /tmp/previous_attempts.md to understand what went wrong and avoid repeating the same mistakes.' || 'This is the first attempt for this library.' }}
165165
166166
### Step 3: Generate implementation
167167
Create the implementation file at the correct path:
168-
- `plots/${{ inputs.library }}/{plot_type}/${{ inputs.spec_id }}/default.py`
169-
170-
Determine {plot_type} from the spec (e.g., scatter, bar, line, heatmap).
168+
- `plots/${{ inputs.spec_id }}/implementations/${{ inputs.library }}.py`
171169
172170
### Step 4: Test the implementation
173171
Run the implementation to verify it works:
174172
```bash
175173
source .venv/bin/activate
176-
MPLBACKEND=Agg python plots/${{ inputs.library }}/{plot_type}/${{ inputs.spec_id }}/default.py
174+
MPLBACKEND=Agg python plots/${{ inputs.spec_id }}/implementations/${{ inputs.library }}.py
177175
```
178176
179177
### Step 5: Format the code
180178
IMPORTANT: Run ruff to format and lint the code before committing:
181179
```bash
182-
uv run ruff format plots/${{ inputs.library }}/{plot_type}/${{ inputs.spec_id }}/default.py
183-
uv run ruff check --fix plots/${{ inputs.library }}/{plot_type}/${{ inputs.spec_id }}/default.py
180+
uv run ruff format plots/${{ inputs.spec_id }}/implementations/${{ inputs.library }}.py
181+
uv run ruff check --fix plots/${{ inputs.spec_id }}/implementations/${{ inputs.library }}.py
184182
```
185183
186184
### Step 6: Create PR (only if implementation is successful)
@@ -200,7 +198,7 @@ jobs:
200198
**Attempt:** ${{ inputs.attempt }}/3
201199
202200
## Implementation
203-
- \`plots/${{ inputs.library }}/{plot_type}/${{ inputs.spec_id }}/default.py\`
201+
- \`plots/${{ inputs.spec_id }}/implementations/${{ inputs.library }}.py\`
204202
205203
Closes #${{ inputs.sub_issue_number }}"
206204
```
@@ -236,8 +234,8 @@ jobs:
236234
ATTEMPT="${{ inputs.attempt }}"
237235
PR_NUMBER="${{ steps.pr.outputs.pr_number }}"
238236
239-
# Find the generated plot file
240-
PLOT_FILE=$(find plots/$LIBRARY -name "default.py" -path "*/${SPEC_ID}/*" 2>/dev/null | head -1 || echo "")
237+
# Get the implementation file path
238+
PLOT_FILE="plots/${SPEC_ID}/implementations/${LIBRARY}.py"
241239
242240
# Read the code if it exists
243241
if [ -f "$PLOT_FILE" ]; then

.github/workflows/gen-new-plot.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565

6666
- name: Verify spec file exists
6767
run: |
68-
SPEC_FILE="specs/${{ inputs.spec_id }}.md"
68+
SPEC_FILE="plots/${{ inputs.spec_id }}/spec.md"
6969
if [ ! -f "$SPEC_FILE" ]; then
7070
echo "::error::Spec file not found: $SPEC_FILE"
7171
echo "::error::The feature branch should contain the spec file"
@@ -137,7 +137,7 @@ jobs:
137137
SUB_BODY="## [$SPEC_ID] $LIBRARY Implementation
138138
139139
**Parent Issue:** #$PARENT_NUM
140-
**Spec:** \`specs/$SPEC_ID.md\`
140+
**Spec:** \`plots/$SPEC_ID/spec.md\`
141141
**Library:** $LIBRARY
142142
**Feature Branch:** \`$FEATURE_BRANCH\`
143143

0 commit comments

Comments
 (0)