@pennyfarthing/core 8.0.4 → 9.0.0
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/README.md +3 -3
- package/package.json +3 -3
- package/pennyfarthing-dist/agents/README.md +1 -1
- package/pennyfarthing-dist/agents/dev.md +1 -1
- package/pennyfarthing-dist/agents/handoff.md +1 -1
- package/pennyfarthing-dist/agents/reviewer-preflight.md +1 -1
- package/pennyfarthing-dist/agents/reviewer.md +21 -4
- package/pennyfarthing-dist/agents/sm-setup.md +3 -3
- package/pennyfarthing-dist/agents/sm.md +11 -1
- package/pennyfarthing-dist/agents/tea.md +1 -1
- package/pennyfarthing-dist/agents/testing-runner.md +3 -3
- package/pennyfarthing-dist/commands/architect.md +3 -1
- package/pennyfarthing-dist/commands/continue-session.md +2 -2
- package/pennyfarthing-dist/commands/dev.md +3 -1
- package/pennyfarthing-dist/commands/devops.md +3 -1
- package/pennyfarthing-dist/commands/health-check.md +3 -1
- package/pennyfarthing-dist/commands/new-work.md +23 -0
- package/pennyfarthing-dist/commands/orchestrator.md +3 -1
- package/pennyfarthing-dist/commands/parallel-work.md +6 -4
- package/pennyfarthing-dist/commands/pm.md +3 -1
- package/pennyfarthing-dist/commands/prime.md +18 -22
- package/pennyfarthing-dist/commands/reviewer.md +3 -1
- package/pennyfarthing-dist/commands/set-theme.md +1 -1
- package/pennyfarthing-dist/commands/sm.md +3 -1
- package/pennyfarthing-dist/commands/sprint.md +13 -4
- package/pennyfarthing-dist/commands/tea.md +3 -1
- package/pennyfarthing-dist/commands/tech-writer.md +3 -1
- package/pennyfarthing-dist/commands/ux-designer.md +3 -1
- package/pennyfarthing-dist/commands/work.md +4 -2
- package/pennyfarthing-dist/guides/agent-behavior.md +36 -257
- package/pennyfarthing-dist/personas/themes/rome.yaml +11 -11
- package/pennyfarthing-dist/scripts/core/agent-session.sh +7 -0
- package/pennyfarthing-dist/scripts/core/check-context.sh +140 -226
- package/pennyfarthing-dist/scripts/core/handoff-marker.sh +13 -2
- package/pennyfarthing-dist/scripts/git/worktree-manager.sh +4 -1
- package/pennyfarthing-dist/scripts/health/drift-detection.sh +1 -7
- package/pennyfarthing-dist/scripts/hooks/post-merge.sh +4 -11
- package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +3 -8
- package/pennyfarthing-dist/scripts/hooks/pre-push.sh +3 -3
- package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +1 -7
- package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +2 -8
- package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +2 -8
- package/pennyfarthing-dist/scripts/lib/find-root.sh +17 -45
- package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +1 -7
- package/pennyfarthing-dist/scripts/sprint/archive-story.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/available-stories.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/check-story.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/list-future.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +2 -8
- package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +2 -8
- package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +2 -1
- package/pennyfarthing-dist/scripts/workflow/finish-story.sh +4 -9
- package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +2 -8
- package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +2 -8
- package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +1 -7
- package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +2 -8
- package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +2 -8
- package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +2 -8
- package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +2 -8
- package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +1 -1
- package/pennyfarthing-dist/skills/jira/SKILL.md +48 -24
- package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +7 -0
- package/pennyfarthing-dist/skills/sprint/skill.md +30 -30
- package/pennyfarthing-dist/workflows/patch.yaml +68 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/cli.py +168 -0
- package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/context.py +414 -0
- package/pennyfarthing_scripts/patch_mode.py +449 -0
- package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/cli.py +209 -1
- package/pennyfarthing_scripts/prime/models.py +9 -0
- package/pennyfarthing_scripts/prime/persona.py +41 -0
- package/pennyfarthing_scripts/prime/tiers.py +201 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/cli.py +144 -84
- package/pennyfarthing_scripts/tests/test_patch_mode.py +830 -0
- package/pennyfarthing_scripts/tests/test_tiers.py +1090 -0
- package/pennyfarthing_scripts/tests/test_token_counting.py +559 -0
- package/pennyfarthing_scripts/tests/test_workflow_check.py +341 -0
- package/pennyfarthing_scripts/workflow.py +104 -0
- package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
|
@@ -21,7 +21,7 @@ Never manually edit `sprint/current-sprint.yaml`. Use the scripts below for dete
|
|
|
21
21
|
Show current sprint status with story counts and points.
|
|
22
22
|
|
|
23
23
|
<run>
|
|
24
|
-
.pennyfarthing/scripts
|
|
24
|
+
.pennyfarthing/scripts/sprint/sprint-status.sh [filter]
|
|
25
25
|
</run>
|
|
26
26
|
|
|
27
27
|
<args>
|
|
@@ -31,10 +31,10 @@ Show current sprint status with story counts and points.
|
|
|
31
31
|
</args>
|
|
32
32
|
|
|
33
33
|
<example>
|
|
34
|
-
.pennyfarthing/scripts
|
|
35
|
-
.pennyfarthing/scripts
|
|
36
|
-
.pennyfarthing/scripts
|
|
37
|
-
.pennyfarthing/scripts
|
|
34
|
+
.pennyfarthing/scripts/sprint/sprint-status.sh # All stories
|
|
35
|
+
.pennyfarthing/scripts/sprint/sprint-status.sh todo # Backlog only
|
|
36
|
+
.pennyfarthing/scripts/sprint/sprint-status.sh in-progress # WIP only
|
|
37
|
+
.pennyfarthing/scripts/sprint/sprint-status.sh done # Completed only
|
|
38
38
|
</example>
|
|
39
39
|
|
|
40
40
|
<output>
|
|
@@ -49,7 +49,7 @@ When filtered, only shows epics with matching stories.
|
|
|
49
49
|
Show available stories grouped by epic with Jira context.
|
|
50
50
|
|
|
51
51
|
<run>
|
|
52
|
-
.pennyfarthing/scripts
|
|
52
|
+
.pennyfarthing/scripts/sprint/available-stories.sh
|
|
53
53
|
</run>
|
|
54
54
|
|
|
55
55
|
<output>
|
|
@@ -82,7 +82,7 @@ Shows backlog, user selects story, then proceeds to setup.
|
|
|
82
82
|
#### With story ID: Direct start
|
|
83
83
|
|
|
84
84
|
<run>
|
|
85
|
-
.pennyfarthing/scripts
|
|
85
|
+
.pennyfarthing/scripts/sprint/check-story.sh <story-id>
|
|
86
86
|
</run>
|
|
87
87
|
|
|
88
88
|
<args>
|
|
@@ -97,14 +97,14 @@ Shows backlog, user selects story, then proceeds to setup.
|
|
|
97
97
|
</output>
|
|
98
98
|
|
|
99
99
|
<example>
|
|
100
|
-
.pennyfarthing/scripts
|
|
100
|
+
.pennyfarthing/scripts/sprint/check-story.sh MSSCI-12038
|
|
101
101
|
# Returns: {"type": "story", "available": true, "title": "...", ...}
|
|
102
102
|
</example>
|
|
103
103
|
|
|
104
104
|
#### With epic ID: Start first available story in epic
|
|
105
105
|
|
|
106
106
|
<run>
|
|
107
|
-
.pennyfarthing/scripts
|
|
107
|
+
.pennyfarthing/scripts/sprint/check-story.sh <epic-id>
|
|
108
108
|
</run>
|
|
109
109
|
|
|
110
110
|
<output>
|
|
@@ -113,14 +113,14 @@ Action: Automatically start work on `first_story` if available.
|
|
|
113
113
|
</output>
|
|
114
114
|
|
|
115
115
|
<example>
|
|
116
|
-
.pennyfarthing/scripts
|
|
116
|
+
.pennyfarthing/scripts/sprint/check-story.sh MSSCI-11952
|
|
117
117
|
# Returns: {"type": "epic", "first_story": {"id": "MSSCI-11954", ...}, ...}
|
|
118
118
|
</example>
|
|
119
119
|
|
|
120
120
|
#### With `next`: Auto-select highest priority story
|
|
121
121
|
|
|
122
122
|
<run>
|
|
123
|
-
.pennyfarthing/scripts
|
|
123
|
+
.pennyfarthing/scripts/sprint/check-story.sh next
|
|
124
124
|
</run>
|
|
125
125
|
|
|
126
126
|
<output>
|
|
@@ -129,7 +129,7 @@ Action: Automatically start work on returned story.
|
|
|
129
129
|
</output>
|
|
130
130
|
|
|
131
131
|
<example>
|
|
132
|
-
.pennyfarthing/scripts
|
|
132
|
+
.pennyfarthing/scripts/sprint/check-story.sh next
|
|
133
133
|
# Returns: {"type": "next", "story": {"id": "MSSCI-11950", "priority": "P1", ...}}
|
|
134
134
|
</example>
|
|
135
135
|
|
|
@@ -140,7 +140,7 @@ Action: Automatically start work on returned story.
|
|
|
140
140
|
Archive a completed story to the sprint archive file.
|
|
141
141
|
|
|
142
142
|
<run>
|
|
143
|
-
.pennyfarthing/scripts
|
|
143
|
+
.pennyfarthing/scripts/sprint/archive-story.sh <story-id> [pr-number] [--apply]
|
|
144
144
|
</run>
|
|
145
145
|
|
|
146
146
|
<args>
|
|
@@ -153,10 +153,10 @@ Archive a completed story to the sprint archive file.
|
|
|
153
153
|
|
|
154
154
|
<example>
|
|
155
155
|
# Archive only (manual removal needed)
|
|
156
|
-
.pennyfarthing/scripts
|
|
156
|
+
.pennyfarthing/scripts/sprint/archive-story.sh 35-2 368
|
|
157
157
|
|
|
158
158
|
# Archive and remove atomically (recommended)
|
|
159
|
-
.pennyfarthing/scripts
|
|
159
|
+
.pennyfarthing/scripts/sprint/archive-story.sh 35-2 368 --apply
|
|
160
160
|
</example>
|
|
161
161
|
|
|
162
162
|
<output>
|
|
@@ -173,7 +173,7 @@ Archive a completed story to the sprint archive file.
|
|
|
173
173
|
Initialize a new sprint from template.
|
|
174
174
|
|
|
175
175
|
<run>
|
|
176
|
-
.pennyfarthing/scripts
|
|
176
|
+
.pennyfarthing/scripts/sprint/new-sprint.sh <yyww> <jira-id> <start> <end> "<goal>"
|
|
177
177
|
</run>
|
|
178
178
|
|
|
179
179
|
<args>
|
|
@@ -187,7 +187,7 @@ Initialize a new sprint from template.
|
|
|
187
187
|
</args>
|
|
188
188
|
|
|
189
189
|
<example>
|
|
190
|
-
.pennyfarthing/scripts
|
|
190
|
+
.pennyfarthing/scripts/sprint/new-sprint.sh 2605 277 2026-02-03 2026-02-16 "Polish and stabilization"
|
|
191
191
|
</example>
|
|
192
192
|
|
|
193
193
|
<output>
|
|
@@ -205,7 +205,7 @@ Warning: Prompts for confirmation if current sprint is still active.
|
|
|
205
205
|
Show future work initiatives and epics available for promotion.
|
|
206
206
|
|
|
207
207
|
<run>
|
|
208
|
-
.pennyfarthing/scripts
|
|
208
|
+
.pennyfarthing/scripts/sprint/list-future.sh [--epic EPIC_ID]
|
|
209
209
|
</run>
|
|
210
210
|
|
|
211
211
|
<args>
|
|
@@ -229,10 +229,10 @@ With `--epic`:
|
|
|
229
229
|
|
|
230
230
|
<example>
|
|
231
231
|
# Show all future work
|
|
232
|
-
.pennyfarthing/scripts
|
|
232
|
+
.pennyfarthing/scripts/sprint/list-future.sh
|
|
233
233
|
|
|
234
234
|
# Show details for specific epic
|
|
235
|
-
.pennyfarthing/scripts
|
|
235
|
+
.pennyfarthing/scripts/sprint/list-future.sh --epic epic-55
|
|
236
236
|
</example>
|
|
237
237
|
|
|
238
238
|
---
|
|
@@ -242,7 +242,7 @@ With `--epic`:
|
|
|
242
242
|
Move an epic from `future.yaml` to `current-sprint.yaml`.
|
|
243
243
|
|
|
244
244
|
<run>
|
|
245
|
-
.pennyfarthing/scripts
|
|
245
|
+
.pennyfarthing/scripts/sprint/promote-epic.sh <epic-id>
|
|
246
246
|
</run>
|
|
247
247
|
|
|
248
248
|
<args>
|
|
@@ -252,7 +252,7 @@ Move an epic from `future.yaml` to `current-sprint.yaml`.
|
|
|
252
252
|
</args>
|
|
253
253
|
|
|
254
254
|
<example>
|
|
255
|
-
.pennyfarthing/scripts
|
|
255
|
+
.pennyfarthing/scripts/sprint/promote-epic.sh epic-41
|
|
256
256
|
</example>
|
|
257
257
|
|
|
258
258
|
<output>
|
|
@@ -278,7 +278,7 @@ These scripts read sprint YAML without modifying it. Use these instead of direct
|
|
|
278
278
|
### Get Story Field
|
|
279
279
|
|
|
280
280
|
<run>
|
|
281
|
-
.pennyfarthing/scripts
|
|
281
|
+
.pennyfarthing/scripts/sprint/get-story-field.sh <story-id> <field>
|
|
282
282
|
</run>
|
|
283
283
|
|
|
284
284
|
<args>
|
|
@@ -289,9 +289,9 @@ These scripts read sprint YAML without modifying it. Use these instead of direct
|
|
|
289
289
|
</args>
|
|
290
290
|
|
|
291
291
|
<example>
|
|
292
|
-
.pennyfarthing/scripts
|
|
293
|
-
.pennyfarthing/scripts
|
|
294
|
-
.pennyfarthing/scripts
|
|
292
|
+
.pennyfarthing/scripts/sprint/get-story-field.sh 35-2 workflow # Returns: tdd
|
|
293
|
+
.pennyfarthing/scripts/sprint/get-story-field.sh 35-2 jira # Returns: MSSCI-12345
|
|
294
|
+
.pennyfarthing/scripts/sprint/get-story-field.sh 35-2 status # Returns: in_progress
|
|
295
295
|
</example>
|
|
296
296
|
|
|
297
297
|
<output>
|
|
@@ -303,7 +303,7 @@ Field value or "null" if not found. Common fields: `workflow`, `status`, `jira`,
|
|
|
303
303
|
### Get Epic Field
|
|
304
304
|
|
|
305
305
|
<run>
|
|
306
|
-
.pennyfarthing/scripts
|
|
306
|
+
.pennyfarthing/scripts/sprint/get-epic-field.sh <epic-id> <field>
|
|
307
307
|
</run>
|
|
308
308
|
|
|
309
309
|
<args>
|
|
@@ -314,8 +314,8 @@ Field value or "null" if not found. Common fields: `workflow`, `status`, `jira`,
|
|
|
314
314
|
</args>
|
|
315
315
|
|
|
316
316
|
<example>
|
|
317
|
-
.pennyfarthing/scripts
|
|
318
|
-
.pennyfarthing/scripts
|
|
317
|
+
.pennyfarthing/scripts/sprint/get-epic-field.sh epic-35 jira # Returns: MSSCI-11234
|
|
318
|
+
.pennyfarthing/scripts/sprint/get-epic-field.sh 35 title # Returns: Epic title
|
|
319
319
|
</example>
|
|
320
320
|
|
|
321
321
|
<output>
|
|
@@ -347,7 +347,7 @@ When `/sprint work` (or `/new-work`) starts a story:
|
|
|
347
347
|
<agent-activation>
|
|
348
348
|
Load SM persona first:
|
|
349
349
|
```bash
|
|
350
|
-
d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts
|
|
350
|
+
d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "sm"
|
|
351
351
|
```
|
|
352
352
|
</agent-activation>
|
|
353
353
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Patch Mode Workflow - Interrupt-Driven Bug Fix
|
|
2
|
+
# For quick fixes during active story work
|
|
3
|
+
#
|
|
4
|
+
# Story: 74-1
|
|
5
|
+
# Epic: epic-74 (Patch Mode Workflow)
|
|
6
|
+
#
|
|
7
|
+
# Flow: Dev only (no TEA, no review)
|
|
8
|
+
# Use for: Blocking bugs, script errors, path fixes, urgent UI fixes
|
|
9
|
+
#
|
|
10
|
+
# Key difference from trivial:
|
|
11
|
+
# - Branches from FEATURE branch, not develop
|
|
12
|
+
# - Merges back to FEATURE branch
|
|
13
|
+
# - Preserves and restores workflow state
|
|
14
|
+
# - Supports nested patches (stack-based)
|
|
15
|
+
|
|
16
|
+
workflow:
|
|
17
|
+
name: patch
|
|
18
|
+
description: Interrupt-driven bug fix during active story work
|
|
19
|
+
version: "1.0.0"
|
|
20
|
+
|
|
21
|
+
# Patch mode is NOT a full workflow - it's an interrupt
|
|
22
|
+
# It doesn't have phases in the traditional sense
|
|
23
|
+
type: interrupt
|
|
24
|
+
|
|
25
|
+
phases:
|
|
26
|
+
- name: fix
|
|
27
|
+
agent: dev
|
|
28
|
+
description: Fix the blocking issue
|
|
29
|
+
output: [fix_commit]
|
|
30
|
+
gate:
|
|
31
|
+
type: manual
|
|
32
|
+
condition: Fix verified working
|
|
33
|
+
|
|
34
|
+
# Branch naming
|
|
35
|
+
branch:
|
|
36
|
+
prefix: "patch/"
|
|
37
|
+
format: "{prefix}{description}-{timestamp}"
|
|
38
|
+
|
|
39
|
+
# Commit format
|
|
40
|
+
commit:
|
|
41
|
+
format: "fix(patch): {description} [from:{story_id}]"
|
|
42
|
+
coauthor: true
|
|
43
|
+
|
|
44
|
+
# State management
|
|
45
|
+
state:
|
|
46
|
+
file: ".session/patch-stack.yaml"
|
|
47
|
+
preserved_fields:
|
|
48
|
+
- story_id
|
|
49
|
+
- workflow
|
|
50
|
+
- phase
|
|
51
|
+
- agent
|
|
52
|
+
- feature_branch
|
|
53
|
+
|
|
54
|
+
# Integration
|
|
55
|
+
tirepump:
|
|
56
|
+
auto_restore: true
|
|
57
|
+
handoff_on_complete: true
|
|
58
|
+
|
|
59
|
+
triggers:
|
|
60
|
+
# Manual triggers
|
|
61
|
+
commands:
|
|
62
|
+
- "/patch"
|
|
63
|
+
- "/fix-blocker"
|
|
64
|
+
# Automatic triggers (future)
|
|
65
|
+
# error_patterns:
|
|
66
|
+
# - "No such file or directory"
|
|
67
|
+
# - "ModuleNotFoundError"
|
|
68
|
+
# - "command not found"
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pennyfarthing CLI - Command line interface for agent orchestration.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python -m pennyfarthing_scripts.cli [OPTIONS] COMMAND [ARGS]...
|
|
6
|
+
pf [OPTIONS] COMMAND [ARGS]...
|
|
7
|
+
|
|
8
|
+
This module uses lazy loading to keep startup time under 200ms.
|
|
9
|
+
Heavy imports (httpx, workflow modules) are deferred until needed.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
# Get version from package - this is a fast import
|
|
15
|
+
from pennyfarthing_scripts import __version__
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.group()
|
|
19
|
+
@click.version_option(version=__version__, prog_name="pf")
|
|
20
|
+
def cli():
|
|
21
|
+
"""Pennyfarthing CLI - Agent orchestration utilities.
|
|
22
|
+
|
|
23
|
+
Commands are organized into groups:
|
|
24
|
+
|
|
25
|
+
\b
|
|
26
|
+
workflow - Workflow state and phase management
|
|
27
|
+
agent - Agent session management
|
|
28
|
+
sprint - Sprint status and story operations
|
|
29
|
+
"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Import and register sprint group (lazy registration preserves startup time)
|
|
34
|
+
from pennyfarthing_scripts.sprint.cli import sprint
|
|
35
|
+
|
|
36
|
+
cli.add_command(sprint)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@cli.group()
|
|
40
|
+
def agent():
|
|
41
|
+
"""Agent session management.
|
|
42
|
+
|
|
43
|
+
\b
|
|
44
|
+
Commands:
|
|
45
|
+
start - Start an agent session with context
|
|
46
|
+
"""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@agent.command("start")
|
|
51
|
+
@click.argument("name")
|
|
52
|
+
@click.option("--session-id", help="Use explicit session ID")
|
|
53
|
+
@click.option("--no-persona", is_flag=True, help="Skip persona loading")
|
|
54
|
+
@click.option("--json", "json_output", is_flag=True, help="Output as JSON")
|
|
55
|
+
@click.option("--minimal", is_flag=True, help="Skip all context (fastest)")
|
|
56
|
+
@click.option("--full", is_flag=True, help="Include domain docs")
|
|
57
|
+
def agent_start(
|
|
58
|
+
name: str,
|
|
59
|
+
session_id: str | None,
|
|
60
|
+
no_persona: bool,
|
|
61
|
+
json_output: bool,
|
|
62
|
+
minimal: bool,
|
|
63
|
+
full: bool,
|
|
64
|
+
):
|
|
65
|
+
"""Start an agent session with full context.
|
|
66
|
+
|
|
67
|
+
Loads agent definition, persona, behavior guide, sprint context,
|
|
68
|
+
session context, and sidecar memory.
|
|
69
|
+
|
|
70
|
+
\b
|
|
71
|
+
Arguments:
|
|
72
|
+
NAME - Agent name (sm, tea, dev, reviewer, etc.)
|
|
73
|
+
"""
|
|
74
|
+
# Lazy import - only load when command is actually invoked
|
|
75
|
+
from pennyfarthing_scripts.prime import prime
|
|
76
|
+
|
|
77
|
+
exit_code = prime(
|
|
78
|
+
agent_name=name,
|
|
79
|
+
session_id=session_id,
|
|
80
|
+
no_persona=no_persona,
|
|
81
|
+
json_output=json_output,
|
|
82
|
+
minimal=minimal,
|
|
83
|
+
full=full,
|
|
84
|
+
)
|
|
85
|
+
raise SystemExit(exit_code)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@cli.group()
|
|
89
|
+
def workflow():
|
|
90
|
+
"""Workflow state and phase management.
|
|
91
|
+
|
|
92
|
+
\b
|
|
93
|
+
Commands:
|
|
94
|
+
check - Check current workflow state
|
|
95
|
+
phase-check - Verify phase ownership
|
|
96
|
+
handoff - Emit handoff marker
|
|
97
|
+
"""
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@workflow.command("check")
|
|
102
|
+
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
|
|
103
|
+
def workflow_check(output_json: bool):
|
|
104
|
+
"""Check current workflow state.
|
|
105
|
+
|
|
106
|
+
Returns the current story ID, phase, and workflow state.
|
|
107
|
+
"""
|
|
108
|
+
# Lazy import - only load when command is actually invoked
|
|
109
|
+
from pennyfarthing_scripts.workflow import get_workflow_state
|
|
110
|
+
|
|
111
|
+
state = get_workflow_state()
|
|
112
|
+
|
|
113
|
+
if output_json:
|
|
114
|
+
import json
|
|
115
|
+
|
|
116
|
+
click.echo(json.dumps(state, indent=2))
|
|
117
|
+
else:
|
|
118
|
+
click.echo(f"State: {state.get('state', 'unknown')}")
|
|
119
|
+
if state.get("story_id"):
|
|
120
|
+
click.echo(f"Story: {state['story_id']}")
|
|
121
|
+
if state.get("workflow"):
|
|
122
|
+
click.echo(f"Workflow: {state['workflow']}")
|
|
123
|
+
if state.get("phase"):
|
|
124
|
+
click.echo(f"Phase: {state['phase']}")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@workflow.command("phase-check")
|
|
128
|
+
@click.argument("workflow_name")
|
|
129
|
+
@click.argument("phase")
|
|
130
|
+
def workflow_phase_check(workflow_name: str, phase: str):
|
|
131
|
+
"""Check which agent owns a workflow phase.
|
|
132
|
+
|
|
133
|
+
\b
|
|
134
|
+
Arguments:
|
|
135
|
+
WORKFLOW_NAME - The workflow type (tdd, trivial, etc.)
|
|
136
|
+
PHASE - The phase to check (red, implement, review, etc.)
|
|
137
|
+
"""
|
|
138
|
+
# Lazy import
|
|
139
|
+
from pennyfarthing_scripts.workflow import get_phase_owner
|
|
140
|
+
|
|
141
|
+
owner = get_phase_owner(workflow_name, phase)
|
|
142
|
+
click.echo(owner)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@workflow.command("handoff")
|
|
146
|
+
@click.argument("next_agent")
|
|
147
|
+
def workflow_handoff(next_agent: str):
|
|
148
|
+
"""Emit a handoff marker for Cyclist.
|
|
149
|
+
|
|
150
|
+
\b
|
|
151
|
+
Arguments:
|
|
152
|
+
NEXT_AGENT - The agent to hand off to (tea, dev, reviewer, etc.)
|
|
153
|
+
"""
|
|
154
|
+
# Output the marker format expected by Cyclist
|
|
155
|
+
click.echo("---")
|
|
156
|
+
click.echo("AGENT_COMMAND:")
|
|
157
|
+
click.echo(f' marker: "<!-- CYCLIST:HANDOFF:/{next_agent} -->"')
|
|
158
|
+
click.echo(f' fallback: "Run `/{next_agent}` to continue"')
|
|
159
|
+
click.echo("---")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def main():
|
|
163
|
+
"""Entry point for the CLI."""
|
|
164
|
+
cli()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
if __name__ == "__main__":
|
|
168
|
+
main()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|