Skip to content

Commit 37925d6

Browse files
feat(workflows): enhance comment generation in code implementation
- Extract approach from code using docstrings and comments - Include key imports in the generated comment - Limit approach bullet points to a maximum of 6 - Update workflow documentation for parallel code generation
1 parent 48ec2c9 commit 37925d6

5 files changed

Lines changed: 198 additions & 67 deletions

File tree

.github/copilot-instructions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
This file provides guidance to GitHub Copilot when working with code in this repository.
44

5+
## Important Rules
6+
7+
- **No Co-authored-by in commit messages** - Never add `Co-authored-by:` lines to commit messages. Keep commit messages clean without AI attribution footers.
8+
59
## Project Overview
610

711
**pyplots** is an AI-powered platform for Python data visualization that automatically discovers, generates, tests, and maintains plotting examples. The platform is specification-driven: every plot starts as a library-agnostic Markdown spec, then AI generates implementations for all supported libraries.

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

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -201,23 +201,65 @@ jobs:
201201
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
202202
PR_LINK=$([[ -n "$PR_NUMBER" ]] && echo "#$PR_NUMBER" || echo "Not created")
203203
204-
# Use Python to safely create the comment with code
204+
# Extract approach from code (docstring + key comments)
205205
python3 << PYEOF
206-
code = '''$CODE'''
207-
comment = f"""## Attempt $ATTEMPT/3 - {TIMESTAMP}
208-
209-
### Generated Code
210-
\`\`\`python
211-
{code}
212-
\`\`\`
206+
import re
213207
214-
### Status
215-
- **PR:** {PR_LINK}
216-
- **File:** \`$PLOT_FILE\`
217-
- **Workflow:** [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
208+
code = '''$CODE'''
218209
219-
---
220-
"""
210+
# Extract approach bullet points
211+
approach_lines = []
212+
213+
# 1. Get module docstring (first line after triple quotes)
214+
docstring_match = re.search(r'^"""(.*?)"""', code, re.DOTALL)
215+
if docstring_match:
216+
doc = docstring_match.group(1).strip()
217+
# Get first meaningful line (title/description)
218+
for line in doc.split('\n'):
219+
line = line.strip()
220+
if line and not line.startswith('Library:'):
221+
approach_lines.append(f"- {line}")
222+
break
223+
224+
# 2. Extract structural comments as approach steps
225+
for line in code.split('\n'):
226+
line = line.strip()
227+
# Look for section comments like "# Create figure", "# Plot data"
228+
if line.startswith('# ') and not line.startswith('# Input') and not line.startswith('# Sample'):
229+
comment = line[2:].strip()
230+
if comment and len(comment) > 3 and comment[0].isupper():
231+
approach_lines.append(f"- {comment}")
232+
233+
# 3. Extract key imports
234+
imports = []
235+
for line in code.split('\n'):
236+
if line.startswith('import ') or line.startswith('from '):
237+
if 'matplotlib' in line or 'seaborn' in line or 'plotly' in line or 'bokeh' in line or 'altair' in line or 'plotnine' in line or 'pygal' in line or 'highcharts' in line:
238+
imports.append(line.split()[1].split('.')[0])
239+
240+
if imports:
241+
approach_lines.insert(0, f"- Using: {', '.join(set(imports))}")
242+
243+
# Limit to 6 bullet points
244+
approach_lines = approach_lines[:6]
245+
246+
if not approach_lines:
247+
approach_lines = ["- See PR for implementation details"]
248+
249+
approach_text = '\n'.join(approach_lines)
250+
251+
comment = f"""## Attempt $ATTEMPT/3 - $TIMESTAMP
252+
253+
### Approach
254+
{approach_text}
255+
256+
### Status
257+
- **PR:** $PR_LINK
258+
- **File:** \`$PLOT_FILE\`
259+
- **Workflow:** [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
260+
261+
---
262+
"""
221263
with open('/tmp/attempt_comment.md', 'w') as f:
222264
f.write(comment)
223265
PYEOF

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
- **Do NOT commit or push in interactive sessions** - When working with a user interactively, never run `git commit` or `git push` automatically. Always let the user review changes and commit/push manually.
88
- **GitHub Actions workflows ARE allowed to commit/push** - When running as part of `spec-to-code.yml` or other automated workflows, creating branches, commits, and PRs is expected and required.
9+
- **No Co-authored-by in commit messages** - Never add `Co-authored-by:` lines to commit messages. Keep commit messages clean without AI attribution footers.
910

1011
## Project Overview
1112

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**AI-powered Python plotting library that works with YOUR data.**
44

5-
[![Python 3.14+](https://img.shields.io/badge/python-3.14+-blue.svg)](https://www.python.org/)
5+
[![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/)
66
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
77
[![Tests](https://github.com/MarkusNeusinger/pyplots/actions/workflows/ci-unittest.yml/badge.svg?branch=main)](https://github.com/MarkusNeusinger/pyplots/actions/workflows/ci-unittest.yml)
88
[![Ruff](https://github.com/MarkusNeusinger/pyplots/actions/workflows/ci-lint.yml/badge.svg?branch=main)](https://github.com/MarkusNeusinger/pyplots/actions/workflows/ci-lint.yml)
@@ -64,11 +64,10 @@ specs/scatter-basic-001.md → plots/matplotlib/scatter/scatter-basic-001/defau
6464
→ plots/plotly/scatter/scatter-basic-001/default.py
6565
```
6666

67-
**Issue-based workflow**: GitHub Issues as state machine for plot lifecycle. All quality feedback documented as bot
68-
comments - no clutter in repo.
67+
**Issue-based workflow**: GitHub Issues as state machine for plot lifecycle. Each plot request spawns **8 parallel sub-issues** (one per library) for independent tracking.
6968

7069
**Multi-LLM quality checks**: Claude + Gemini + GPT evaluate generated plots. Score ≥ 85 required (median). Automatic
71-
feedback loops (max 3 attempts).
70+
feedback loops (max 3 attempts per library).
7271

7372
See [docs/architecture/](docs/architecture/) for details.
7473

@@ -139,8 +138,7 @@ We welcome contributions! **All code is AI-generated** - you propose ideas, AI i
139138

140139
**The workflow**:
141140

142-
- You create Issue with plot idea → AI generates spec → AI generates code for all libraries → Multi-LLM quality check →
143-
Deployed
141+
- You create Issue with plot idea → AI generates spec → **8 parallel sub-issues** spawn (one per library) → Each library generates independently → Multi-LLM quality check per library → Merged & Deployed
144142

145143
**Important**: Don't submit code directly! If a plot has quality issues, it means the spec needs improvement, not the
146144
code.

docs/workflow.md

Lines changed: 133 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,25 @@ graph TB
8787
### Flow 1: Discovery & Ideation
8888
n8n monitors social media daily → AI extracts plot ideas → Creates GitHub issues with draft specs → Human reviews and approves
8989

90-
### Flow 2: Code Generation
91-
Approved issue → Claude generates implementation code with self-review loop (max 3 attempts) → Creates Pull Request
90+
### Flow 2: Parallel Code Generation
91+
92+
Approved issue triggers **parallel generation pipeline**:
93+
94+
1. **Orchestrator** (`gen-new-plot.yml`) creates 8 sub-issues (one per library)
95+
2. **8 parallel jobs** run simultaneously via `gen-library-impl.yml`:
96+
- Each library has isolated dependencies
97+
- Separate Claude context (no syntax confusion)
98+
- Independent PR per library
99+
3. **Per-library tracking**: Each sub-issue documents attempts and status
100+
4. **Partial success possible**: Some libraries can merge while others retry
101+
102+
```
103+
Main Issue (#53)
104+
├── Sub-Issue: [spec-id] matplotlib implementation (#54) → PR #62
105+
├── Sub-Issue: [spec-id] seaborn implementation (#55) → PR #63
106+
├── Sub-Issue: [spec-id] plotly implementation (#56) → PR #64
107+
└── ... (8 total)
108+
```
92109

93110
### Flow 3: Multi-Version Testing
94111
PR created → `ci-plottest.yml` runs tests across Python 3.11+ → Reports results
@@ -102,8 +119,16 @@ PR merged with `ai-approved` → `bot-auto-tag.yml` triggers → AI analyzes cod
102119
### Flow 5: AI Review
103120
Previews generated → `bot-ai-review.yml` triggers → Claude evaluates Spec ↔ Code ↔ Preview → **Posts results to Issue** (permanent knowledge base) → Score ≥7/10 on all criteria required → Labels: `ai-approved` or `ai-rejected`
104121

105-
### Flow 5.5: Repair Loop (NEW)
106-
PR labeled `ai-rejected``gen-update-plot.yml` triggers → Reads feedback from Issue → Regenerates improved code → Pushes to PR → Re-triggers ci-plottest → Max 3 attempts → After 3 failures: `ai-failed` label (manual review needed)
122+
### Flow 5.5: Per-Library Repair Loop
123+
PR labeled `ai-rejected``gen-update-plot.yml` triggers for that **specific library**:
124+
125+
1. Reads all previous attempts from sub-issue (for context/learning)
126+
2. Regenerates improved code with feedback
127+
3. Pushes to PR → Re-triggers tests
128+
4. Max 3 attempts per library
129+
5. After 3 failures: `not-feasible` label (library marked as not implementable for this spec)
130+
131+
**Note**: Each library repairs independently - matplotlib can be on attempt 3 while plotly already merged
107132

108133
### Flow 5.6: Auto-Merge
109134
PR labeled `ai-approved``bot-auto-merge.yml` triggers → Automatic squash merge
@@ -116,65 +141,121 @@ Deployed plot → Added to promotion queue (prioritized by quality score) → n8
116141

117142
---
118143

144+
## Sub-Issue Architecture
145+
146+
Each plot request spawns **8 parallel sub-issues** (one per library), enabling:
147+
148+
- **~8x faster** generation (parallel execution)
149+
- **No context pollution** (separate Claude sessions per library)
150+
- **Per-library dependencies** (seaborn can use older matplotlib if needed)
151+
- **Partial success** (5/8 can merge while 3/8 retry)
152+
- **Independent tracking** (each library has its own status)
153+
154+
### Sub-Issue Lifecycle
155+
156+
```mermaid
157+
graph LR
158+
A[Main Issue<br/>plot-request + approved] --> B[Orchestrator]
159+
B --> C1[Sub-Issue<br/>matplotlib]
160+
B --> C2[Sub-Issue<br/>seaborn]
161+
B --> C3[Sub-Issue<br/>...]
162+
163+
C1 --> D1{generating}
164+
D1 --> E1{testing}
165+
E1 --> F1{reviewing}
166+
F1 -->|Score ≥85| G1[ai-approved]
167+
F1 -->|Score <85| H1[ai-rejected]
168+
H1 -->|Attempt <3| D1
169+
H1 -->|Attempt =3| I1[not-feasible]
170+
G1 --> J1[merged]
171+
```
172+
173+
### Sub-Issue Labels
174+
175+
| Label | Meaning |
176+
|-------|---------|
177+
| `sub-issue` | Identifies as child of main issue |
178+
| `library:{name}` | Which library (matplotlib, seaborn, etc.) |
179+
| `generating` | Code being generated |
180+
| `testing` | Tests running |
181+
| `reviewing` | AI quality review in progress |
182+
| `ai-approved` | Passed review (score ≥85) |
183+
| `ai-rejected` | Failed review, will retry |
184+
| `not-feasible` | 3x failed, not implementable in this library |
185+
| `merged` | Successfully merged to main |
186+
187+
### Attempt Documentation
188+
189+
Each attempt is documented in the sub-issue with:
190+
191+
```markdown
192+
## Attempt 1/3 - 2025-11-30T12:00:00Z
193+
194+
### Approach
195+
- Using: seaborn
196+
- heatmap-correlation: Correlation Matrix Heatmap
197+
- Create figure with figsize
198+
- Plot data using heatmap
199+
- Configure colorbar
200+
201+
### Status
202+
- **PR:** #123
203+
- **File:** `plots/seaborn/heatmap/heatmap-correlation/default.py`
204+
- **Workflow:** [link]
205+
```
206+
207+
This enables learning from previous attempts during repair loops.
208+
209+
---
210+
119211
## Flow Integration
120212

121213
```mermaid
122214
graph TD
123215
A[Flow 1: Discovery] -->|GitHub Issue| B{Manual/Auto Approval?}
124216
B -->|Manual| C[Human Reviews Issue]
125-
B -->|Auto| D[Flow 2: Code Generation<br/>with Self-Review Loop]
217+
B -->|Auto| D[Flow 2: Parallel Generation]
126218
C -->|Approved| D
127219
C -->|Rejected| Z[End]
128220
129-
D -->|Self-Review Pass<br/>Max 3 Attempts| E{Code Quality OK?}
130-
E -->|Yes| F[Flow 3: Multi-Version Testing]
131-
E -->|No after 3 tries| W[Mark Library as Not Feasible]
132-
W --> Z
133-
134-
F -->|Tests Passed| G[Flow 4: Preview Generation]
135-
F -->|Tests Failed| D
136-
137-
G -->|PNG in GCS| H{Flow 5: Quality Check}
138-
H -->|Routine Plot| I[Claude Evaluation]
139-
H -->|Critical Plot| J[Multi-LLM Consensus]
140-
141-
I -->|Score ≥85| K{Attempt Count}
142-
J -->|Majority Approved| K
221+
D -->|Create 8 Sub-Issues| D1[Orchestrator]
222+
D1 --> D2[8 Parallel Jobs]
223+
D2 -->|Per Library| E{Tests Pass?}
143224
144-
I -->|Score <85| L[Store Feedback]
145-
J -->|Rejected| L
225+
E -->|Yes| F[Flow 4: Preview Generation]
226+
E -->|No| D2
146227
147-
L --> M{Attempts < 3?}
148-
M -->|Yes| N[Feed Feedback to Generator]
149-
N --> D
150-
M -->|No| O[Mark as Quality-Failed]
151-
O --> Z
228+
F -->|PNG in GCS| G{Flow 5: AI Review}
229+
G -->|Score ≥85| H[ai-approved]
230+
G -->|Score <85| I[ai-rejected]
152231
153-
K -->|Approved| P[Flow 6: Deploy to Website]
154-
P --> Q[🌐 Publicly Visible]
155-
P --> U[Flow 7: Add to Promotion Queue]
232+
I --> J{Attempts < 3?}
233+
J -->|Yes| K[Repair Loop]
234+
K --> D2
235+
J -->|No| L[not-feasible]
236+
L --> Z
156237
157-
U --> V{Daily Post Limit?}
158-
V -->|< 2 posts today| X[Generate & Post to X]
159-
V -->|Limit reached| Y[Wait in Queue]
160-
X --> Z
161-
Y -.->|Next day| V
238+
H --> M[Auto-Merge]
239+
M --> N[Flow 6: Deploy]
240+
N --> O[🌐 Publicly Visible]
241+
N --> P[Flow 7: Promotion Queue]
162242
163-
R[Event: LLM/Library Update] -->|Trigger| S[Flow 6: Maintenance]
164-
S -->|Check Improvements| T{Better?}
165-
T -->|Yes + Re-approved| P
166-
T -->|No| Z
243+
P --> Q{Daily Limit?}
244+
Q -->|< 2 posts| R[Post to X]
245+
Q -->|Limit| S[Wait]
246+
R --> Z
247+
S -.->|Next day| Q
167248
168249
style A fill:#e1f5ff
169250
style D fill:#fff4e1
170-
style H fill:#f0e1ff
171-
style P fill:#e1ffe1
172-
style Q fill:#90EE90
173-
style R fill:#ffe1e1
174-
style L fill:#FFB6C1
175-
style O fill:#FF6B6B
176-
style U fill:#E6E6FA
177-
style X fill:#98FB98
251+
style D1 fill:#fff4e1
252+
style D2 fill:#fff4e1
253+
style G fill:#f0e1ff
254+
style N fill:#e1ffe1
255+
style O fill:#90EE90
256+
style L fill:#FF6B6B
257+
style P fill:#E6E6FA
258+
style R fill:#98FB98
178259
```
179260

180261
---
@@ -386,8 +467,13 @@ Via **GitHub Issue Labels**:
386467
This workflow ensures:
387468

388469
**Fully Automated** pipeline from discovery to deployment to promotion
470+
**Parallel Per-Library Generation**:
471+
- 8 libraries generated simultaneously (~8x faster)
472+
- Isolated dependencies per library
473+
- Independent tracking via sub-issues
474+
- Partial success possible (some merge while others retry)
389475
**Multi-Layer Quality Control**:
390-
- Self-review loop in code generation (max 3 attempts)
476+
- Self-review loop in code generation (max 3 attempts per library)
391477
- Multi-version testing across Python 3.11-3.14 (3.14 primary)
392478
- Multi-LLM consensus validation (Claude + Gemini + GPT)
393479
- Feedback-driven optimization on rejection

0 commit comments

Comments
 (0)