@pjmendonca/devflow 1.9.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/adversarial.md +10 -0
- package/.claude/commands/agent.md +10 -0
- package/.claude/commands/bugfix.md +8 -0
- package/.claude/commands/checkpoint.md +30 -0
- package/.claude/commands/collab.md +30 -0
- package/.claude/commands/costs.md +27 -0
- package/.claude/commands/develop.md +8 -0
- package/.claude/commands/devflow.md +6 -0
- package/.claude/commands/handoff.md +26 -0
- package/.claude/commands/memory.md +23 -0
- package/.claude/commands/pair.md +24 -0
- package/.claude/commands/personalize.md +15 -0
- package/.claude/commands/review.md +8 -0
- package/.claude/commands/route.md +26 -0
- package/.claude/commands/story.md +10 -0
- package/.claude/commands/swarm.md +22 -0
- package/.claude/skills/github-cli/SKILL.md +241 -0
- package/CHANGELOG.md +21 -1
- package/README.md +40 -122
- package/bin/create-devflow.js +141 -0
- package/lib/python-check.js +5 -5
- package/package.json +3 -1
- package/tooling/.automation/agents/dev.md +2 -2
- package/tooling/.automation/agents/reviewer.md +8 -8
- package/tooling/.automation/agents/sm.md +1 -1
- package/tooling/.automation/memory/knowledge/kg_integration-test.json +137 -1
- package/tooling/.automation/memory/knowledge/kg_test-story.json +438 -2
- package/tooling/.automation/memory/shared/shared_integration-test.json +25 -1
- package/tooling/.automation/memory/shared/shared_test-story.json +73 -1
- package/tooling/.automation/overrides/templates/reviewer/mentoring-reviewer.yaml +5 -5
- package/tooling/docs/DOC-STANDARD.md +21 -21
- package/tooling/docs/templates/bug-report.md +1 -1
- package/tooling/scripts/context_checkpoint.py +16 -16
- package/tooling/scripts/create-persona.py +7 -7
- package/tooling/scripts/create-persona.sh +4 -4
- package/tooling/scripts/init-project-workflow.sh +19 -19
- package/tooling/scripts/lib/__init__.py +1 -1
- package/tooling/scripts/lib/agent_handoff.py +4 -6
- package/tooling/scripts/lib/agent_router.py +6 -6
- package/tooling/scripts/lib/checkpoint-integration.sh +14 -14
- package/tooling/scripts/lib/claude-cli.sh +50 -50
- package/tooling/scripts/lib/cost_tracker.py +4 -4
- package/tooling/scripts/lib/errors.py +9 -9
- package/tooling/scripts/lib/pair_programming.py +5 -5
- package/tooling/scripts/lib/shared_memory.py +4 -4
- package/tooling/scripts/lib/swarm_orchestrator.py +18 -18
- package/tooling/scripts/new-doc.sh +12 -12
- package/tooling/scripts/personalize_agent.py +4 -4
- package/tooling/scripts/rollback-migration.sh +4 -4
- package/tooling/scripts/run-collab.ps1 +2 -2
- package/tooling/scripts/run-collab.py +13 -13
- package/tooling/scripts/run-story.py +1 -1
- package/tooling/scripts/run-story.sh +20 -20
- package/tooling/scripts/setup-checkpoint-service.sh +4 -4
- package/tooling/scripts/tech-debt-tracker.py +12 -12
- package/tooling/scripts/update_version.py +10 -10
- package/tooling/scripts/validate-overrides.py +10 -12
- package/tooling/scripts/validate-overrides.sh +7 -7
- package/tooling/scripts/validate_setup.py +8 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"story_key": "test-story",
|
|
3
|
-
"last_updated": "2025-12-
|
|
3
|
+
"last_updated": "2025-12-22T13:26:44.896715",
|
|
4
4
|
"entries": [
|
|
5
5
|
{
|
|
6
6
|
"id": "mem_94d28071",
|
|
@@ -73,6 +73,78 @@
|
|
|
73
73
|
],
|
|
74
74
|
"story_key": "test-story",
|
|
75
75
|
"references": []
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "mem_6ed43f6c",
|
|
79
|
+
"timestamp": "2025-12-22T13:25:54.043613",
|
|
80
|
+
"agent": "SM",
|
|
81
|
+
"content": "Handed off to DEV: Created story context",
|
|
82
|
+
"tags": [
|
|
83
|
+
"handoff",
|
|
84
|
+
"dev"
|
|
85
|
+
],
|
|
86
|
+
"story_key": "test-story",
|
|
87
|
+
"references": []
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "mem_a45e6ef0",
|
|
91
|
+
"timestamp": "2025-12-22T13:25:54.059350",
|
|
92
|
+
"agent": "DEV",
|
|
93
|
+
"content": "Handed off to REVIEWER: Implementation complete",
|
|
94
|
+
"tags": [
|
|
95
|
+
"handoff",
|
|
96
|
+
"reviewer"
|
|
97
|
+
],
|
|
98
|
+
"story_key": "test-story",
|
|
99
|
+
"references": []
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "mem_9c802d55",
|
|
103
|
+
"timestamp": "2025-12-22T13:25:54.074794",
|
|
104
|
+
"agent": "SM",
|
|
105
|
+
"content": "Handed off to DEV: Ready for development",
|
|
106
|
+
"tags": [
|
|
107
|
+
"handoff",
|
|
108
|
+
"dev"
|
|
109
|
+
],
|
|
110
|
+
"story_key": "test-story",
|
|
111
|
+
"references": []
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "mem_bd042810",
|
|
115
|
+
"timestamp": "2025-12-22T13:26:44.866120",
|
|
116
|
+
"agent": "SM",
|
|
117
|
+
"content": "Handed off to DEV: Created story context",
|
|
118
|
+
"tags": [
|
|
119
|
+
"handoff",
|
|
120
|
+
"dev"
|
|
121
|
+
],
|
|
122
|
+
"story_key": "test-story",
|
|
123
|
+
"references": []
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "mem_179756ec",
|
|
127
|
+
"timestamp": "2025-12-22T13:26:44.881680",
|
|
128
|
+
"agent": "DEV",
|
|
129
|
+
"content": "Handed off to REVIEWER: Implementation complete",
|
|
130
|
+
"tags": [
|
|
131
|
+
"handoff",
|
|
132
|
+
"reviewer"
|
|
133
|
+
],
|
|
134
|
+
"story_key": "test-story",
|
|
135
|
+
"references": []
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "mem_83f996a7",
|
|
139
|
+
"timestamp": "2025-12-22T13:26:44.896677",
|
|
140
|
+
"agent": "SM",
|
|
141
|
+
"content": "Handed off to DEV: Ready for development",
|
|
142
|
+
"tags": [
|
|
143
|
+
"handoff",
|
|
144
|
+
"dev"
|
|
145
|
+
],
|
|
146
|
+
"story_key": "test-story",
|
|
147
|
+
"references": []
|
|
76
148
|
}
|
|
77
149
|
]
|
|
78
150
|
}
|
|
@@ -38,8 +38,8 @@ model: "sonnet"
|
|
|
38
38
|
max_budget_usd: 8.00
|
|
39
39
|
|
|
40
40
|
feedback_style:
|
|
41
|
-
must_fix: "
|
|
42
|
-
should_fix: "
|
|
43
|
-
suggestion: "
|
|
44
|
-
question: "
|
|
45
|
-
praise: "
|
|
41
|
+
must_fix: "[MUST FIX] This needs to be fixed because..."
|
|
42
|
+
should_fix: "[SHOULD FIX] I'd recommend changing this because..."
|
|
43
|
+
suggestion: "[SUGGESTION] Consider... (optional but would improve...)"
|
|
44
|
+
question: "[QUESTION] I'm curious why... (just trying to understand)"
|
|
45
|
+
praise: "[PRAISE] Nice work on... (this is well done because...)"
|
|
@@ -39,7 +39,7 @@ This document defines the standard format, structure, and conventions for all do
|
|
|
39
39
|
|
|
40
40
|
### Examples
|
|
41
41
|
```
|
|
42
|
-
|
|
42
|
+
Good:
|
|
43
43
|
- GUIDE-context-checkpoint.md
|
|
44
44
|
- SPEC-epic-3-goals.md
|
|
45
45
|
- STATUS-checkpoint-integration.md
|
|
@@ -47,7 +47,7 @@ This document defines the standard format, structure, and conventions for all do
|
|
|
47
47
|
- STANDARD-documentation.md
|
|
48
48
|
- EXAMPLE-checkpoint-integration.md
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Bad:
|
|
51
51
|
- context-checkpoint-guide.md
|
|
52
52
|
- epic3spec.md
|
|
53
53
|
- checkpoint_status.md
|
|
@@ -215,23 +215,23 @@ Always include header separator:
|
|
|
215
215
|
Use these emoji conventions:
|
|
216
216
|
|
|
217
217
|
```markdown
|
|
218
|
-
|
|
218
|
+
**WARNING**: Important warning
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
**TIP**: Helpful tip
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
**NOTE**: Additional information
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
**CRITICAL**: Critical information
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
**SUCCESS**: Successful outcome
|
|
227
227
|
|
|
228
|
-
|
|
228
|
+
**ERROR**: Error or failure
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
**GOAL**: Objective or target
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
**DATA**: Data or statistics
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
**TECHNICAL**: Technical details
|
|
235
235
|
```
|
|
236
236
|
|
|
237
237
|
---
|
|
@@ -265,8 +265,8 @@ Always include:
|
|
|
265
265
|
|
|
266
266
|
**Expected Output**:
|
|
267
267
|
```
|
|
268
|
-
[09:04:45]
|
|
269
|
-
[09:04:45]
|
|
268
|
+
[09:04:45] Creating checkpoint: checkpoint_20251220_090445_1
|
|
269
|
+
[09:04:45] Checkpoint saved: checkpoint_20251220_090445_1.json
|
|
270
270
|
```
|
|
271
271
|
````
|
|
272
272
|
|
|
@@ -372,7 +372,7 @@ Format: `MAJOR.MINOR`
|
|
|
372
372
|
- **MAJOR**: Significant restructuring or breaking changes
|
|
373
373
|
- **MINOR**: Content updates, additions, clarifications
|
|
374
374
|
|
|
375
|
-
Example: `1.0`
|
|
375
|
+
Example: `1.0` -> `1.1` -> `2.0`
|
|
376
376
|
|
|
377
377
|
### Changelog
|
|
378
378
|
|
|
@@ -530,7 +530,7 @@ Check document compliance:
|
|
|
530
530
|
|
|
531
531
|
### Good Documentation
|
|
532
532
|
|
|
533
|
-
|
|
533
|
+
Clear title and metadata:
|
|
534
534
|
```markdown
|
|
535
535
|
# Context Checkpoint User Guide
|
|
536
536
|
|
|
@@ -541,7 +541,7 @@ Check document compliance:
|
|
|
541
541
|
**Status**: Active
|
|
542
542
|
```
|
|
543
543
|
|
|
544
|
-
|
|
544
|
+
Scannable sections:
|
|
545
545
|
```markdown
|
|
546
546
|
## Quick Start
|
|
547
547
|
|
|
@@ -556,7 +556,7 @@ python3 tooling/scripts/context_checkpoint.py --watch-log <file>
|
|
|
556
556
|
```
|
|
557
557
|
```
|
|
558
558
|
|
|
559
|
-
|
|
559
|
+
Complete examples:
|
|
560
560
|
```markdown
|
|
561
561
|
### Example: Resume from Checkpoint
|
|
562
562
|
|
|
@@ -576,21 +576,21 @@ python3 tooling/scripts/context_checkpoint.py --watch-log <file>
|
|
|
576
576
|
|
|
577
577
|
### Bad Documentation
|
|
578
578
|
|
|
579
|
-
|
|
579
|
+
Unclear title:
|
|
580
580
|
```markdown
|
|
581
581
|
# Checkpoint Stuff
|
|
582
582
|
|
|
583
583
|
Some information about checkpoints...
|
|
584
584
|
```
|
|
585
585
|
|
|
586
|
-
|
|
586
|
+
Missing metadata:
|
|
587
587
|
```markdown
|
|
588
588
|
# My Guide
|
|
589
589
|
|
|
590
590
|
Here's how to do stuff...
|
|
591
591
|
```
|
|
592
592
|
|
|
593
|
-
|
|
593
|
+
Incomplete examples:
|
|
594
594
|
```markdown
|
|
595
595
|
Just run this:
|
|
596
596
|
```bash
|
|
@@ -598,7 +598,7 @@ Just run this:
|
|
|
598
598
|
```
|
|
599
599
|
```
|
|
600
600
|
|
|
601
|
-
|
|
601
|
+
Poor formatting:
|
|
602
602
|
```markdown
|
|
603
603
|
You can run script.sh or use the checkpoint command to create a checkpoint or list them using --list flag...
|
|
604
604
|
```
|
|
@@ -74,7 +74,7 @@ class ContextCheckpointManager:
|
|
|
74
74
|
|
|
75
75
|
def _signal_handler(self, signum, frame):
|
|
76
76
|
"""Handle shutdown signals gracefully."""
|
|
77
|
-
print(f"\n{Colors.YELLOW}
|
|
77
|
+
print(f"\n{Colors.YELLOW}Shutting down checkpoint manager...{Colors.END}")
|
|
78
78
|
self.running = False
|
|
79
79
|
sys.exit(0)
|
|
80
80
|
|
|
@@ -97,7 +97,7 @@ class ContextCheckpointManager:
|
|
|
97
97
|
Looks for patterns like:
|
|
98
98
|
- "Token usage: 75000/200000"
|
|
99
99
|
- "Context: 75%"
|
|
100
|
-
- "
|
|
100
|
+
- " CONTEXT WARNING"
|
|
101
101
|
"""
|
|
102
102
|
# Pattern 1: Token usage: X/Y
|
|
103
103
|
match = re.search(r"Token usage:\s*(\d+)/(\d+)", output)
|
|
@@ -112,7 +112,7 @@ class ContextCheckpointManager:
|
|
|
112
112
|
return int(match.group(1)) / 100
|
|
113
113
|
|
|
114
114
|
# Pattern 3: Warning messages
|
|
115
|
-
if "
|
|
115
|
+
if " CONTEXT WARNING" in output or "Approaching context limit" in output:
|
|
116
116
|
return 0.90 # Assume 90% if warning present
|
|
117
117
|
|
|
118
118
|
return None
|
|
@@ -184,7 +184,7 @@ class ContextCheckpointManager:
|
|
|
184
184
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
185
185
|
checkpoint_id = f"checkpoint_{timestamp}_{self.checkpoint_count}"
|
|
186
186
|
|
|
187
|
-
self._log(f"
|
|
187
|
+
self._log(f" Creating checkpoint: {checkpoint_id}", "INFO")
|
|
188
188
|
|
|
189
189
|
# Extract current conversation
|
|
190
190
|
conversation = self.get_current_conversation()
|
|
@@ -213,7 +213,7 @@ class ContextCheckpointManager:
|
|
|
213
213
|
summary_file = self.checkpoint_dir / f"{checkpoint_id}_summary.md"
|
|
214
214
|
self._create_checkpoint_summary(checkpoint_data, summary_file)
|
|
215
215
|
|
|
216
|
-
self._log(f"
|
|
216
|
+
self._log(f" Checkpoint saved: {checkpoint_file.name}", "SUCCESS")
|
|
217
217
|
self.last_checkpoint_time = datetime.now()
|
|
218
218
|
|
|
219
219
|
return checkpoint_file
|
|
@@ -265,7 +265,7 @@ After checkpoint, the session should be cleared and restarted with:
|
|
|
265
265
|
|
|
266
266
|
def clear_session(self):
|
|
267
267
|
"""Clear the current Claude session."""
|
|
268
|
-
self._log("
|
|
268
|
+
self._log(" Clearing session...", "INFO")
|
|
269
269
|
try:
|
|
270
270
|
# Try to clear via CLI
|
|
271
271
|
result = subprocess.run(
|
|
@@ -273,7 +273,7 @@ After checkpoint, the session should be cleared and restarted with:
|
|
|
273
273
|
)
|
|
274
274
|
|
|
275
275
|
if result.returncode == 0:
|
|
276
|
-
self._log("
|
|
276
|
+
self._log(" Session cleared successfully", "SUCCESS")
|
|
277
277
|
return True
|
|
278
278
|
else:
|
|
279
279
|
self._log(f"Warning: Clear command returned {result.returncode}", "WARNING")
|
|
@@ -298,7 +298,7 @@ After checkpoint, the session should be cleared and restarted with:
|
|
|
298
298
|
self._log(f"Checkpoint not found: {checkpoint_id}", "ERROR")
|
|
299
299
|
return False
|
|
300
300
|
|
|
301
|
-
self._log(f"
|
|
301
|
+
self._log(f" Loading checkpoint: {checkpoint_id}", "INFO")
|
|
302
302
|
|
|
303
303
|
try:
|
|
304
304
|
with open(checkpoint_file) as f:
|
|
@@ -308,7 +308,7 @@ After checkpoint, the session should be cleared and restarted with:
|
|
|
308
308
|
resume_prompt = self._create_resume_prompt(checkpoint_data)
|
|
309
309
|
|
|
310
310
|
# Start new session with resume prompt
|
|
311
|
-
self._log("
|
|
311
|
+
self._log("Starting new session with checkpoint context...", "INFO")
|
|
312
312
|
print("\n" + "=" * 80)
|
|
313
313
|
print("RESUME PROMPT (paste this into Claude Code):")
|
|
314
314
|
print("=" * 80 + "\n")
|
|
@@ -382,7 +382,7 @@ Ready to continue!
|
|
|
382
382
|
Args:
|
|
383
383
|
log_file: Path to log file to monitor
|
|
384
384
|
"""
|
|
385
|
-
self._log(f"
|
|
385
|
+
self._log(f" Watching log file: {log_file}", "INFO")
|
|
386
386
|
|
|
387
387
|
try:
|
|
388
388
|
with open(log_file) as f:
|
|
@@ -415,10 +415,10 @@ Ready to continue!
|
|
|
415
415
|
|
|
416
416
|
if context_level >= CONTEXT_EMERGENCY_THRESHOLD:
|
|
417
417
|
# EMERGENCY: Force checkpoint immediately
|
|
418
|
-
self._log(f"
|
|
418
|
+
self._log(f" EMERGENCY: Context at {percentage:.1f}% - Force checkpoint!", "CRITICAL")
|
|
419
419
|
checkpoint_file = self.create_checkpoint(context_level, reason="emergency")
|
|
420
420
|
self._log(
|
|
421
|
-
"
|
|
421
|
+
" MANUAL ACTION REQUIRED: Clear session and resume from checkpoint", "CRITICAL"
|
|
422
422
|
)
|
|
423
423
|
self._log(
|
|
424
424
|
f"Run: python3 tooling/scripts/context_checkpoint.py --resume {checkpoint_file.stem}",
|
|
@@ -427,17 +427,17 @@ Ready to continue!
|
|
|
427
427
|
|
|
428
428
|
elif context_level >= CONTEXT_CRITICAL_THRESHOLD:
|
|
429
429
|
# CRITICAL: Auto-checkpoint
|
|
430
|
-
self._log(f"
|
|
430
|
+
self._log(f" CRITICAL: Context at {percentage:.1f}% - Auto checkpoint", "WARNING")
|
|
431
431
|
checkpoint_file = self.create_checkpoint(context_level, reason="critical")
|
|
432
|
-
self._log("
|
|
432
|
+
self._log(" Consider clearing session soon", "WARNING")
|
|
433
433
|
|
|
434
434
|
elif context_level >= CONTEXT_WARNING_THRESHOLD:
|
|
435
435
|
# WARNING: Just notify
|
|
436
|
-
self._log(f"
|
|
436
|
+
self._log(f" WARNING: Context at {percentage:.1f}%", "WARNING")
|
|
437
437
|
|
|
438
438
|
def interactive_monitor(self):
|
|
439
439
|
"""Run interactive monitoring mode."""
|
|
440
|
-
self._log("
|
|
440
|
+
self._log("Starting interactive context monitor", "INFO")
|
|
441
441
|
self._log(
|
|
442
442
|
f"Thresholds: Warning={CONTEXT_WARNING_THRESHOLD * 100}%, Critical={CONTEXT_CRITICAL_THRESHOLD * 100}%, Emergency={CONTEXT_EMERGENCY_THRESHOLD * 100}%",
|
|
443
443
|
"INFO",
|
|
@@ -441,7 +441,7 @@ def generate_persona_markdown(config: PersonaConfig) -> str:
|
|
|
441
441
|
"",
|
|
442
442
|
"If you sense context is running low, output a warning:",
|
|
443
443
|
"```",
|
|
444
|
-
"
|
|
444
|
+
" CONTEXT WARNING: Approaching context limit. Prioritizing completion of current task.",
|
|
445
445
|
"```",
|
|
446
446
|
"",
|
|
447
447
|
]
|
|
@@ -549,7 +549,7 @@ def list_personas(project_root: Path):
|
|
|
549
549
|
override_file = (
|
|
550
550
|
project_root / "tooling" / ".automation" / "overrides" / f"{name}.override.yaml"
|
|
551
551
|
)
|
|
552
|
-
has_override = "
|
|
552
|
+
has_override = "[OK]" if override_file.exists() else " "
|
|
553
553
|
|
|
554
554
|
print(f" {Colors.GREEN}{name:15}{Colors.NC} │ {role:25} │ Override: {has_override}")
|
|
555
555
|
|
|
@@ -561,7 +561,7 @@ def validate_persona(name: str, project_root: Path) -> bool:
|
|
|
561
561
|
agent_file = project_root / "tooling" / ".automation" / "agents" / f"{name}.md"
|
|
562
562
|
|
|
563
563
|
if not agent_file.exists():
|
|
564
|
-
print(f"{Colors.RED}
|
|
564
|
+
print(f"{Colors.RED}[X] Agent file not found: {agent_file}{Colors.NC}")
|
|
565
565
|
return False
|
|
566
566
|
|
|
567
567
|
print(f"{Colors.BOLD}Validating persona: {name}{Colors.NC}")
|
|
@@ -587,13 +587,13 @@ def validate_persona(name: str, project_root: Path) -> bool:
|
|
|
587
587
|
|
|
588
588
|
# Print results
|
|
589
589
|
for error in errors:
|
|
590
|
-
print(f" {Colors.RED}
|
|
590
|
+
print(f" {Colors.RED}[ERROR]{Colors.NC} {error}")
|
|
591
591
|
|
|
592
592
|
for warning in warnings:
|
|
593
|
-
print(f" {Colors.YELLOW}
|
|
593
|
+
print(f" {Colors.YELLOW}[WARNING]{Colors.NC} {warning}")
|
|
594
594
|
|
|
595
595
|
if not errors and not warnings:
|
|
596
|
-
print(f" {Colors.GREEN}
|
|
596
|
+
print(f" {Colors.GREEN}[OK] Persona is valid!{Colors.NC}")
|
|
597
597
|
|
|
598
598
|
print()
|
|
599
599
|
return len(errors) == 0
|
|
@@ -674,7 +674,7 @@ def main():
|
|
|
674
674
|
print()
|
|
675
675
|
agent_file, override_file = save_persona(config, project_root)
|
|
676
676
|
|
|
677
|
-
print(f"{Colors.GREEN}
|
|
677
|
+
print(f"{Colors.GREEN}[OK] Persona created successfully!{Colors.NC}")
|
|
678
678
|
print()
|
|
679
679
|
print(f" Agent file: {agent_file}")
|
|
680
680
|
print(f" Override file: {override_file}")
|
|
@@ -181,7 +181,7 @@ You are running in an automated pipeline with limited context window. To avoid l
|
|
|
181
181
|
|
|
182
182
|
If you sense context is running low, output a warning:
|
|
183
183
|
```
|
|
184
|
-
|
|
184
|
+
CONTEXT WARNING: Approaching context limit. Prioritizing completion of current task.
|
|
185
185
|
```
|
|
186
186
|
|
|
187
187
|
EOF
|
|
@@ -255,7 +255,7 @@ list_personas() {
|
|
|
255
255
|
|
|
256
256
|
local has_override=" "
|
|
257
257
|
if [[ -f "$OVERRIDES_DIR/${name}.override.yaml" ]]; then
|
|
258
|
-
has_override="
|
|
258
|
+
has_override="[OK]"
|
|
259
259
|
fi
|
|
260
260
|
|
|
261
261
|
printf " ${GREEN}%-15s${NC} │ %-25s │ %s\n" "$name" "$role" "$has_override"
|
|
@@ -296,7 +296,7 @@ create_from_template() {
|
|
|
296
296
|
local agent_file=$(generate_agent_file "$name" "$role" "$focus" "$model" "${responsibilities[@]}")
|
|
297
297
|
local override_file=$(generate_override_file "$name")
|
|
298
298
|
|
|
299
|
-
echo -e "${GREEN}
|
|
299
|
+
echo -e "${GREEN}[OK] Persona created from template!${NC}"
|
|
300
300
|
echo ""
|
|
301
301
|
echo " Agent file: $agent_file"
|
|
302
302
|
[[ -n "$override_file" ]] && echo " Override file: $override_file"
|
|
@@ -369,7 +369,7 @@ interactive_create() {
|
|
|
369
369
|
local override_file=$(generate_override_file "$name")
|
|
370
370
|
|
|
371
371
|
echo ""
|
|
372
|
-
echo -e "${GREEN}
|
|
372
|
+
echo -e "${GREEN}[OK] Persona created successfully!${NC}"
|
|
373
373
|
echo ""
|
|
374
374
|
echo " Agent file: $agent_file"
|
|
375
375
|
[[ -n "$override_file" ]] && echo " Override file: $override_file"
|
|
@@ -78,7 +78,7 @@ prompt_yes_no() {
|
|
|
78
78
|
################################################################################
|
|
79
79
|
|
|
80
80
|
detect_project_type() {
|
|
81
|
-
echo -e "${BLUE}
|
|
81
|
+
echo -e "${BLUE}> Detecting project type...${NC}"
|
|
82
82
|
|
|
83
83
|
local project_type="generic"
|
|
84
84
|
|
|
@@ -115,7 +115,7 @@ setup_directory_structure() {
|
|
|
115
115
|
local project_root="$1"
|
|
116
116
|
local workflow_mode="${2:-both}" # greenfield, brownfield, or both
|
|
117
117
|
|
|
118
|
-
echo -e "${BLUE}
|
|
118
|
+
echo -e "${BLUE}> Creating directory structure...${NC}"
|
|
119
119
|
|
|
120
120
|
# Core directories (always created)
|
|
121
121
|
mkdir -p "$project_root/tooling/.automation/agents"
|
|
@@ -141,14 +141,14 @@ setup_directory_structure() {
|
|
|
141
141
|
echo -e "${BLUE} Creating brownfield structure...${NC}"
|
|
142
142
|
fi
|
|
143
143
|
|
|
144
|
-
echo -e "${GREEN}
|
|
144
|
+
echo -e "${GREEN} Directories created${NC}"
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
copy_core_scripts() {
|
|
148
148
|
local project_root="$1"
|
|
149
149
|
local source_dir="$2"
|
|
150
150
|
|
|
151
|
-
echo -e "${BLUE}
|
|
151
|
+
echo -e "${BLUE}> Copying core automation scripts...${NC}"
|
|
152
152
|
|
|
153
153
|
# Core library scripts
|
|
154
154
|
cp "$source_dir/lib/claude-cli.sh" "$project_root/tooling/scripts/lib/"
|
|
@@ -165,7 +165,7 @@ copy_core_scripts() {
|
|
|
165
165
|
chmod +x "$project_root/tooling/scripts/"*.py
|
|
166
166
|
chmod +x "$project_root/tooling/scripts/lib/"*.sh
|
|
167
167
|
|
|
168
|
-
echo -e "${GREEN}
|
|
168
|
+
echo -e "${GREEN} Scripts copied${NC}"
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
create_config_file() {
|
|
@@ -176,7 +176,7 @@ create_config_file() {
|
|
|
176
176
|
local model_planning="$5"
|
|
177
177
|
local display_currency="${6:-USD}"
|
|
178
178
|
|
|
179
|
-
echo -e "${BLUE}
|
|
179
|
+
echo -e "${BLUE}> Creating configuration file...${NC}"
|
|
180
180
|
|
|
181
181
|
cat > "$project_root/tooling/.automation/config.sh" << EOF
|
|
182
182
|
#!/bin/zsh
|
|
@@ -227,13 +227,13 @@ EOF
|
|
|
227
227
|
|
|
228
228
|
chmod +x "$project_root/tooling/.automation/config.sh"
|
|
229
229
|
|
|
230
|
-
echo -e "${GREEN}
|
|
230
|
+
echo -e "${GREEN} Configuration created${NC}"
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
create_agent_personas() {
|
|
234
234
|
local project_root="$1"
|
|
235
235
|
|
|
236
|
-
echo -e "${BLUE}
|
|
236
|
+
echo -e "${BLUE}> Creating agent persona definitions...${NC}"
|
|
237
237
|
|
|
238
238
|
# SM (Scrum Master) Agent
|
|
239
239
|
cat > "$project_root/tooling/.automation/agents/sm.md" << 'EOF'
|
|
@@ -371,14 +371,14 @@ Brownfield development - working with existing, production code.
|
|
|
371
371
|
- Clear about risks and tradeoffs
|
|
372
372
|
EOF
|
|
373
373
|
|
|
374
|
-
echo -e "${GREEN}
|
|
374
|
+
echo -e "${GREEN} Agent personas created${NC}"
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
create_sprint_status() {
|
|
378
378
|
local project_root="$1"
|
|
379
379
|
local project_name="$2"
|
|
380
380
|
|
|
381
|
-
echo -e "${BLUE}
|
|
381
|
+
echo -e "${BLUE}> Creating sprint status tracker...${NC}"
|
|
382
382
|
|
|
383
383
|
cat > "$project_root/tooling/docs/sprint-status.yaml" << EOF
|
|
384
384
|
# Sprint Status - $project_name
|
|
@@ -405,14 +405,14 @@ stories:
|
|
|
405
405
|
# 1-2-implement-auth: in-progress
|
|
406
406
|
EOF
|
|
407
407
|
|
|
408
|
-
echo -e "${GREEN}
|
|
408
|
+
echo -e "${GREEN} Sprint status created${NC}"
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
create_documentation_standard() {
|
|
412
412
|
local project_root="$1"
|
|
413
413
|
local source_dir="$2"
|
|
414
414
|
|
|
415
|
-
echo -e "${BLUE}
|
|
415
|
+
echo -e "${BLUE}> Creating documentation standard...${NC}"
|
|
416
416
|
|
|
417
417
|
# Copy DOC-STANDARD if it exists, otherwise create basic one
|
|
418
418
|
if [[ -f "$source_dir/../docs/DOC-STANDARD.md" ]]; then
|
|
@@ -463,18 +463,18 @@ Brief description of what this document covers.
|
|
|
463
463
|
EOF
|
|
464
464
|
fi
|
|
465
465
|
|
|
466
|
-
echo -e "${GREEN}
|
|
466
|
+
echo -e "${GREEN} Documentation standard created${NC}"
|
|
467
467
|
}
|
|
468
468
|
|
|
469
469
|
setup_checkpoint_service() {
|
|
470
470
|
local project_root="$1"
|
|
471
471
|
|
|
472
|
-
echo -e "${BLUE}
|
|
472
|
+
echo -e "${BLUE}> Setting up checkpoint service...${NC}"
|
|
473
473
|
|
|
474
474
|
if prompt_yes_no "Install checkpoint service as macOS LaunchAgent?"; then
|
|
475
475
|
cd "$project_root/tooling/scripts"
|
|
476
476
|
./setup-checkpoint-service.sh
|
|
477
|
-
echo -e "${GREEN}
|
|
477
|
+
echo -e "${GREEN} Checkpoint service installed${NC}"
|
|
478
478
|
else
|
|
479
479
|
echo -e "${YELLOW} ⊘ Skipped checkpoint service installation${NC}"
|
|
480
480
|
echo -e "${BLUE} You can install it later with: ./tooling/scripts/setup-checkpoint-service.sh${NC}"
|
|
@@ -485,7 +485,7 @@ create_readme() {
|
|
|
485
485
|
local project_root="$1"
|
|
486
486
|
local project_name="$2"
|
|
487
487
|
|
|
488
|
-
echo -e "${BLUE}
|
|
488
|
+
echo -e "${BLUE}> Creating workflow README...${NC}"
|
|
489
489
|
|
|
490
490
|
cat > "$project_root/tooling/README.md" << EOF
|
|
491
491
|
# $project_name - Development Workflow
|
|
@@ -586,7 +586,7 @@ Each persona uses the appropriate Claude model for optimal cost/quality.
|
|
|
586
586
|
- Checkpoints: \`tooling/.automation/checkpoints/\`
|
|
587
587
|
EOF
|
|
588
588
|
|
|
589
|
-
echo -e "${GREEN}
|
|
589
|
+
echo -e "${GREEN} README created${NC}"
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
################################################################################
|
|
@@ -719,7 +719,7 @@ main() {
|
|
|
719
719
|
# STEP 8: Finalize
|
|
720
720
|
print_step "8" "Setup Complete!"
|
|
721
721
|
|
|
722
|
-
echo -e "${GREEN}
|
|
722
|
+
echo -e "${GREEN} Workflow initialization complete!${NC}"
|
|
723
723
|
echo ""
|
|
724
724
|
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
|
|
725
725
|
echo -e "${CYAN} NEXT STEPS${NC}"
|
|
@@ -739,7 +739,7 @@ main() {
|
|
|
739
739
|
echo -e "${YELLOW}4. Read the workflow guide:${NC}"
|
|
740
740
|
echo -e " ${BLUE}$project_root/tooling/README.md${NC}"
|
|
741
741
|
echo ""
|
|
742
|
-
echo -e "${GREEN}Happy coding!
|
|
742
|
+
echo -e "${GREEN}Happy coding! ${NC}"
|
|
743
743
|
echo ""
|
|
744
744
|
}
|
|
745
745
|
|
|
@@ -267,7 +267,7 @@ class HandoffGenerator:
|
|
|
267
267
|
"""Extract warnings from agent log output."""
|
|
268
268
|
warnings = []
|
|
269
269
|
warning_patterns = [
|
|
270
|
-
r"
|
|
270
|
+
r"\[WARNING\]\s*(.+)",
|
|
271
271
|
r"WARNING:\s*(.+)",
|
|
272
272
|
r"WARN:\s*(.+)",
|
|
273
273
|
r"Watch out.*?:\s*(.+)",
|
|
@@ -428,9 +428,9 @@ class WorkTracker:
|
|
|
428
428
|
def record_blocker(self, blocker: str, resolved: bool = False):
|
|
429
429
|
"""Record a blocker encountered."""
|
|
430
430
|
if resolved:
|
|
431
|
-
self.blockers.append(f"
|
|
431
|
+
self.blockers.append(f" {blocker} (resolved)")
|
|
432
432
|
else:
|
|
433
|
-
self.blockers.append(f"
|
|
433
|
+
self.blockers.append(f" {blocker}")
|
|
434
434
|
|
|
435
435
|
def record_warning(self, warning: str):
|
|
436
436
|
"""Record a warning for the next agent."""
|
|
@@ -452,9 +452,7 @@ class WorkTracker:
|
|
|
452
452
|
|
|
453
453
|
# Separate resolved and unresolved blockers
|
|
454
454
|
resolved = [
|
|
455
|
-
b.replace("
|
|
456
|
-
for b in self.blockers
|
|
457
|
-
if b.startswith("✅")
|
|
455
|
+
b.replace(" ", "").replace(" (resolved)", "") for b in self.blockers if b.startswith("")
|
|
458
456
|
]
|
|
459
457
|
|
|
460
458
|
return generator.generate(
|