@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.
Files changed (141) hide show
  1. package/README.md +3 -3
  2. package/package.json +3 -3
  3. package/pennyfarthing-dist/agents/README.md +1 -1
  4. package/pennyfarthing-dist/agents/dev.md +1 -1
  5. package/pennyfarthing-dist/agents/handoff.md +1 -1
  6. package/pennyfarthing-dist/agents/reviewer-preflight.md +1 -1
  7. package/pennyfarthing-dist/agents/reviewer.md +21 -4
  8. package/pennyfarthing-dist/agents/sm-setup.md +3 -3
  9. package/pennyfarthing-dist/agents/sm.md +11 -1
  10. package/pennyfarthing-dist/agents/tea.md +1 -1
  11. package/pennyfarthing-dist/agents/testing-runner.md +3 -3
  12. package/pennyfarthing-dist/commands/architect.md +3 -1
  13. package/pennyfarthing-dist/commands/continue-session.md +2 -2
  14. package/pennyfarthing-dist/commands/dev.md +3 -1
  15. package/pennyfarthing-dist/commands/devops.md +3 -1
  16. package/pennyfarthing-dist/commands/health-check.md +3 -1
  17. package/pennyfarthing-dist/commands/new-work.md +23 -0
  18. package/pennyfarthing-dist/commands/orchestrator.md +3 -1
  19. package/pennyfarthing-dist/commands/parallel-work.md +6 -4
  20. package/pennyfarthing-dist/commands/pm.md +3 -1
  21. package/pennyfarthing-dist/commands/prime.md +18 -22
  22. package/pennyfarthing-dist/commands/reviewer.md +3 -1
  23. package/pennyfarthing-dist/commands/set-theme.md +1 -1
  24. package/pennyfarthing-dist/commands/sm.md +3 -1
  25. package/pennyfarthing-dist/commands/sprint.md +13 -4
  26. package/pennyfarthing-dist/commands/tea.md +3 -1
  27. package/pennyfarthing-dist/commands/tech-writer.md +3 -1
  28. package/pennyfarthing-dist/commands/ux-designer.md +3 -1
  29. package/pennyfarthing-dist/commands/work.md +4 -2
  30. package/pennyfarthing-dist/guides/agent-behavior.md +36 -257
  31. package/pennyfarthing-dist/personas/themes/rome.yaml +11 -11
  32. package/pennyfarthing-dist/scripts/core/agent-session.sh +7 -0
  33. package/pennyfarthing-dist/scripts/core/check-context.sh +140 -226
  34. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +13 -2
  35. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +4 -1
  36. package/pennyfarthing-dist/scripts/health/drift-detection.sh +1 -7
  37. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +4 -11
  38. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +3 -8
  39. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +3 -3
  40. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +1 -7
  41. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +2 -8
  42. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +2 -8
  43. package/pennyfarthing-dist/scripts/lib/find-root.sh +17 -45
  44. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +1 -7
  45. package/pennyfarthing-dist/scripts/sprint/archive-story.sh +2 -8
  46. package/pennyfarthing-dist/scripts/sprint/available-stories.sh +2 -8
  47. package/pennyfarthing-dist/scripts/sprint/check-story.sh +2 -8
  48. package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +2 -8
  49. package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +2 -8
  50. package/pennyfarthing-dist/scripts/sprint/list-future.sh +2 -8
  51. package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +2 -8
  52. package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +2 -8
  53. package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +2 -8
  54. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +2 -1
  55. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +4 -9
  56. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +2 -8
  57. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +2 -8
  58. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +1 -7
  59. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +2 -8
  60. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +2 -8
  61. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +2 -8
  62. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +2 -8
  63. package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +1 -1
  64. package/pennyfarthing-dist/skills/jira/SKILL.md +48 -24
  65. package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +7 -0
  66. package/pennyfarthing-dist/skills/sprint/skill.md +30 -30
  67. package/pennyfarthing-dist/workflows/patch.yaml +68 -0
  68. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  69. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  70. package/pennyfarthing_scripts/cli.py +168 -0
  71. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  72. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  73. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  74. package/pennyfarthing_scripts/context.py +414 -0
  75. package/pennyfarthing_scripts/patch_mode.py +449 -0
  76. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  77. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  78. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  79. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  80. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  81. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  82. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  83. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  84. package/pennyfarthing_scripts/prime/cli.py +209 -1
  85. package/pennyfarthing_scripts/prime/models.py +9 -0
  86. package/pennyfarthing_scripts/prime/persona.py +41 -0
  87. package/pennyfarthing_scripts/prime/tiers.py +201 -0
  88. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  89. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  90. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  91. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  92. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  93. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  94. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  95. package/pennyfarthing_scripts/sprint/cli.py +144 -84
  96. package/pennyfarthing_scripts/tests/test_patch_mode.py +830 -0
  97. package/pennyfarthing_scripts/tests/test_tiers.py +1090 -0
  98. package/pennyfarthing_scripts/tests/test_token_counting.py +559 -0
  99. package/pennyfarthing_scripts/tests/test_workflow_check.py +341 -0
  100. package/pennyfarthing_scripts/workflow.py +104 -0
  101. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  102. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  103. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  104. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  105. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  106. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  107. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  108. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  109. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  110. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  111. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  112. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  113. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  114. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  115. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  116. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  117. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  118. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  119. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  120. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  121. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  122. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  123. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  124. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  125. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  126. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  127. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  128. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  129. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  130. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  131. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  132. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  133. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  134. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  135. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  136. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  137. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  138. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  139. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  140. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  141. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Pennyfarthing
2
2
 
3
- **v7.9.2** | *The outer loop goes once, the inner loop goes many times.*
3
+ **v8.1.0** | *The outer loop goes once, the inner loop goes many times.*
4
4
 
5
5
  <img src="pennyfarthing.png" alt="Pennyfarthing Logo" width="75" style="float:left; margin:10px">
6
6
 
@@ -62,7 +62,7 @@ npx pennyfarthing init
62
62
  npx pennyfarthing doctor
63
63
 
64
64
  # Start working (in Claude Code)
65
- /work
65
+ /new-work
66
66
  ```
67
67
 
68
68
  ### Optional: Visual Terminal
@@ -88,7 +88,7 @@ BikeLane is the umbrella workflow system supporting three types:
88
88
  ### Example: TDD Workflow (Phased)
89
89
 
90
90
  ```
91
- /work → SM → TEA → Dev → Reviewer → SM (finish)
91
+ /new-work → SM → TEA → Dev → Reviewer → SM (finish)
92
92
  │ │ │ │
93
93
  setup tests impl review
94
94
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pennyfarthing/core",
3
- "version": "8.0.4",
3
+ "version": "9.0.0",
4
4
  "description": "Claude Code agent framework with TDD workflow and persona system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,8 +30,8 @@
30
30
  "url": "https://github.com/1898andCo/pennyfarthing/issues"
31
31
  },
32
32
  "scripts": {
33
- "build": "pnpm --filter @pennyfarthing/shared build && pnpm --filter @pennyfarthing/core build && pnpm --filter @pennyfarthing/cyclist build && ./scripts/utils/generate-skill-docs.sh",
34
- "docs": "./scripts/utils/generate-skill-docs.sh",
33
+ "build": "pnpm --filter @pennyfarthing/shared build && pnpm --filter @pennyfarthing/core build && pnpm --filter @pennyfarthing/cyclist build && ./scripts/generate-skill-docs.sh",
34
+ "docs": "./scripts/generate-skill-docs.sh",
35
35
  "dev": "pnpm -r --parallel dev",
36
36
  "test": "pnpm -r test",
37
37
  "lint": "eslint 'packages/*/src/**/*.ts' --max-warnings 0",
@@ -284,7 +284,7 @@ When running in Cyclist, background tasks are automatically tracked:
284
284
  Use the background task tracking utilities to manage session file entries:
285
285
 
286
286
  ```bash
287
- source .pennyfarthing/scripts/utils/background-tasks.sh
287
+ source .pennyfarthing/scripts/lib/background-tasks.sh
288
288
  SESSION_FILE=".session/${STORY_ID}-session.md"
289
289
 
290
290
  # After spawning, record the task:
@@ -153,7 +153,7 @@ Write to session file BEFORE spawning handoff:
153
153
  3. Await `HANDOFF_RESULT` with `next_agent`
154
154
  4. **ABSOLUTE LAST ACTION:**
155
155
  ```bash
156
- .pennyfarthing/scripts/handoff/handoff-marker.sh {next_agent}
156
+ .pennyfarthing/scripts/core/handoff-marker.sh {next_agent}
157
157
  ```
158
158
  5. Output result verbatim and EXIT
159
159
  </exit-sequence>
@@ -229,7 +229,7 @@ When you receive `HANDOFF_RESULT`:
229
229
  **CRITICAL: The calling agent MUST run this as their ABSOLUTE LAST ACTION:**
230
230
 
231
231
  ```bash
232
- .pennyfarthing/scripts/handoff/handoff-marker.sh {next_agent}
232
+ .pennyfarthing/scripts/core/handoff-marker.sh {next_agent}
233
233
  ```
234
234
 
235
235
  Then output the script's result verbatim and EXIT. Nothing else after.
@@ -35,7 +35,7 @@ cd "${REPO}" 2>/dev/null || cd "packages/${REPO}" && git fetch origin && git che
35
35
  ## 2. Check Test Cache
36
36
 
37
37
  ```bash
38
- source scripts/utils/test-cache.sh
38
+ source .pennyfarthing/scripts/test/test-cache.sh
39
39
  SESSION_FILE=".session/{STORY_ID}-session.md"
40
40
 
41
41
  if test_cache_valid "$SESSION_FILE"; then
@@ -124,6 +124,7 @@ OWNER=$(.pennyfarthing/scripts/workflow/phase-owner.sh {workflow} {phase})
124
124
  ## MANDATORY: Complete Before Exiting
125
125
 
126
126
  - [ ] Write Reviewer Assessment to session file
127
+ - [ ] **If APPROVED:** Merge PR directly with `gh pr merge {PR_NUMBER} --merge --delete-branch`
127
128
  - [ ] Spawn `handoff` subagent with VERDICT (approved/rejected)
128
129
  - [ ] Verify handoff completed (subagent emits marker)
129
130
  </handoff-gate>
@@ -158,16 +159,32 @@ OWNER=$(.pennyfarthing/scripts/workflow/phase-owner.sh {workflow} {phase})
158
159
  <exit-sequence>
159
160
  ## Exit Sequence
160
161
 
162
+ ### If APPROVED:
161
163
  1. Write Reviewer Assessment to session file
162
- 2. Spawn `handoff` subagent with VERDICT
163
- 3. Await `HANDOFF_RESULT` with `next_agent`
164
+ 2. **Merge the PR directly** (don't wait for SM):
165
+ ```bash
166
+ gh pr merge {PR_NUMBER} --merge --delete-branch
167
+ ```
168
+ 3. Update session phase to `finish`
169
+ 4. Spawn `handoff` subagent with VERDICT=approved
170
+ 5. Await `HANDOFF_RESULT` with `next_agent` (will be `sm`)
171
+ 6. **ABSOLUTE LAST ACTION:**
172
+ ```bash
173
+ .pennyfarthing/scripts/core/handoff-marker.sh sm
174
+ ```
175
+ 7. Output result verbatim and EXIT
176
+
177
+ ### If REJECTED:
178
+ 1. Write Reviewer Assessment to session file
179
+ 2. Spawn `handoff` subagent with VERDICT=rejected
180
+ 3. Await `HANDOFF_RESULT` with `next_agent` (will be `dev`)
164
181
  4. **ABSOLUTE LAST ACTION:**
165
182
  ```bash
166
- .pennyfarthing/scripts/handoff/handoff-marker.sh {next_agent}
183
+ .pennyfarthing/scripts/core/handoff-marker.sh dev
167
184
  ```
168
185
  5. Output result verbatim and EXIT
169
186
 
170
- **Verdict routing:** APPROVED → sm | REJECTED → dev
187
+ **Verdict routing:** APPROVED → merge PR, then sm | REJECTED → dev
171
188
  </exit-sequence>
172
189
 
173
190
  <skills>
@@ -135,14 +135,14 @@ GRANTS=$(cat .claude/settings.local.json 2>/dev/null | jq '.permissions.grants /
135
135
 
136
136
  ## Step 3: Claim in Jira
137
137
 
138
- Use `/jira claim` command:
138
+ Use `/jira check` and `/jira claim` commands:
139
139
 
140
140
  ```bash
141
141
  # Check availability first
142
- .pennyfarthing/scripts/jira/jira-claim-story.sh {JIRA_KEY}
142
+ /jira check {JIRA_KEY}
143
143
 
144
144
  # Then claim (assign to self + move to In Progress)
145
- .pennyfarthing/scripts/jira/jira-claim-story.sh {JIRA_KEY} --claim
145
+ /jira claim {JIRA_KEY}
146
146
  ```
147
147
 
148
148
  **Exit codes:**
@@ -175,6 +175,16 @@ Present to user:
175
175
  - **Stepped workflow** → Tell user to run `/workflow start {workflow}` (no handoff)
176
176
  </new-work-flow>
177
177
 
178
+ <merge-gate>
179
+ ## Merge Gate (BLOCKING)
180
+
181
+ Before starting new work: `gh pr list --state open` - BLOCKS if any exist.
182
+
183
+ Open PRs → incomplete work → merge conflicts, stale branches, CI failures.
184
+
185
+ **Resolution:** Merge/close all PRs first. Use `/reviewer` to complete reviews.
186
+ </merge-gate>
187
+
178
188
  <gate>
179
189
  ## Pre-Handoff Checklist (BLOCKING)
180
190
 
@@ -276,7 +286,7 @@ OWNER=$(.pennyfarthing/scripts/workflow/phase-owner.sh {workflow} {phase})
276
286
  3. Await `HANDOFF_RESULT` with `next_agent`
277
287
  4. **ABSOLUTE LAST ACTION:**
278
288
  ```bash
279
- .pennyfarthing/scripts/handoff/handoff-marker.sh {next_agent}
289
+ .pennyfarthing/scripts/core/handoff-marker.sh {next_agent}
280
290
  ```
281
291
  5. Output result verbatim and EXIT
282
292
 
@@ -144,7 +144,7 @@ Write to session file BEFORE spawning handoff:
144
144
  3. Await `HANDOFF_RESULT` with `next_agent`
145
145
  4. **ABSOLUTE LAST ACTION:**
146
146
  ```bash
147
- .pennyfarthing/scripts/handoff/handoff-marker.sh {next_agent}
147
+ .pennyfarthing/scripts/core/handoff-marker.sh {next_agent}
148
148
  ```
149
149
  5. Output result verbatim and EXIT
150
150
  </exit-sequence>
@@ -40,8 +40,8 @@ This runs lint + typecheck + tests. Exit 0 = all passed.
40
40
  ## Setup
41
41
 
42
42
  ```bash
43
- source .pennyfarthing/scripts/repo-utils.sh
44
- source .pennyfarthing/scripts/utils/test-setup.sh
43
+ source .pennyfarthing/scripts/misc/repo-utils.sh
44
+ source .pennyfarthing/scripts/test/test-setup.sh
45
45
 
46
46
  RUN_ID="${RUN_ID:-$(generate_run_id)}"
47
47
  ensure_test_containers
@@ -73,7 +73,7 @@ fi
73
73
 
74
74
  Write cache after running:
75
75
  ```bash
76
- source .pennyfarthing/scripts/utils/test-cache.sh
76
+ source .pennyfarthing/scripts/test/test-cache.sh
77
77
  SESSION_FILE=".session/${STORY_ID}-session.md"
78
78
  test_cache_write "$SESSION_FILE" "$RESULT" "$PASS" "$FAIL" "$SKIP" "${DURATION}s"
79
79
  ```
@@ -3,5 +3,7 @@ description: System Architect - Technical design and architecture
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "architect"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "architect"
7
9
  ```
@@ -66,7 +66,7 @@ Source the checkpoint utilities and restore:
66
66
 
67
67
  ```bash
68
68
  # Source checkpoint utilities
69
- source "${PROJECT_ROOT:-.}/.pennyfarthing/scripts/utils/checkpoint.sh"
69
+ source "${PROJECT_ROOT:-.}/.pennyfarthing/scripts/lib/checkpoint.sh"
70
70
 
71
71
  # Restore by label
72
72
  PHASE=$(checkpoint_restore "phase:${STORY_ID}")
@@ -177,7 +177,7 @@ This command completes the circuit breaker workflow:
177
177
  </integration>
178
178
 
179
179
  <reference>
180
- - **Checkpoint API:** `scripts/utils/checkpoint.sh`
180
+ - **Checkpoint API:** `.pennyfarthing/scripts/lib/checkpoint.sh`
181
181
  - **Circuit Breaker:** `scripts/hooks/context-circuit-breaker.sh`
182
182
  - **Related:** `/work`, `/new-work`
183
183
  - **Session Files:** `.session/{story-id}-session.md`
@@ -3,5 +3,7 @@ description: Developer - Feature implementation and coding
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/phase-check-start.sh" "dev"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "dev"
7
9
  ```
@@ -3,5 +3,7 @@ description: DevOps Engineer - Infrastructure and deployment automation
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "devops"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "devops"
7
9
  ```
@@ -3,7 +3,9 @@ description: Check Pennyfarthing installation health and apply updates
3
3
  ---
4
4
 
5
5
  ```bash
6
- ./scripts/core/agent-session.sh start "devops"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "devops"
7
9
  ```
8
10
 
9
11
  <agent-activation>
@@ -0,0 +1,23 @@
1
+ ---
2
+ description: Start the next available story from the sprint backlog
3
+ ---
4
+
5
+ # New Work
6
+
7
+ <purpose>
8
+ Shortcut to start the highest priority available story. Alias for `/sprint work next`.
9
+ </purpose>
10
+
11
+ <on-invoke>
12
+ Invoke the sprint work command with "next" to auto-select the highest priority story:
13
+
14
+ ```
15
+ /sprint work next
16
+ ```
17
+ </on-invoke>
18
+
19
+ <related>
20
+ - `/sprint work` - Interactive story selection
21
+ - `/sprint backlog` - View available stories
22
+ - `/work` - Resume existing work or start new
23
+ </related>
@@ -3,5 +3,7 @@ description: Orchestrator - Coordinator of all agents and meta operations
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "orchestrator"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "orchestrator"
7
9
  ```
@@ -3,7 +3,9 @@ description: Start parallel work in a new worktree
3
3
  ---
4
4
 
5
5
  ```bash
6
- ./scripts/core/agent-session.sh start "parallel-work"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "sm"
7
9
  ```
8
10
 
9
11
  <parallel-work-flow>
@@ -20,10 +22,10 @@ read -p "Branch name (e.g., feat/5-3a-feature): " BRANCH_NAME
20
22
 
21
23
  # Create worktree
22
24
  WORKTREE_NAME="wt-${STORY_ID}"
23
- ./scripts/git/worktree-manager.sh create "$WORKTREE_NAME" "$BRANCH_NAME"
25
+ .pennyfarthing/scripts/git/worktree-manager.sh create "$WORKTREE_NAME" "$BRANCH_NAME"
24
26
 
25
27
  # Get port configuration
26
- eval $(./scripts/git/worktree-manager.sh ports "$WORKTREE_NAME")
28
+ eval $(.pennyfarthing/scripts/git/worktree-manager.sh ports "$WORKTREE_NAME")
27
29
  ```
28
30
 
29
31
  ### Step 2: Create Session File
@@ -67,5 +69,5 @@ Invoke SM to complete story setup in the worktree context.
67
69
  </agent-activation>
68
70
 
69
71
  <agent-exit>
70
- On exit: Capture learnings to sidecar, run `./scripts/core/agent-session.sh stop`
72
+ On exit: Capture learnings to sidecar.
71
73
  </agent-exit>
@@ -3,5 +3,7 @@ description: Product Manager - Strategic planning and prioritization
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "pm"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "pm"
7
9
  ```
@@ -4,7 +4,7 @@ description: Load essential project context at agent activation
4
4
 
5
5
  <purpose>
6
6
  Quickly load essential context files to reduce agent cold-start overhead.
7
- Automatically invoked on agent activation via agent-session.sh.
7
+ Automatically invoked on agent activation via `pf agent start`.
8
8
  </purpose>
9
9
 
10
10
  <when-to-use>
@@ -17,23 +17,23 @@ Automatically invoked on agent activation via agent-session.sh.
17
17
 
18
18
  ## Running /prime
19
19
 
20
- Use the prime.sh script:
20
+ Use the Python CLI:
21
21
 
22
22
  ```bash
23
23
  # Load all essential context (default)
24
- $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/prime.sh
24
+ python3 -m pennyfarthing_scripts.cli agent start "sm"
25
25
 
26
- # Minimal mode - CLAUDE.md only (fastest)
27
- $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/prime.sh --minimal
26
+ # Minimal mode - fastest startup
27
+ python3 -m pennyfarthing_scripts.cli agent start "sm" --minimal
28
28
 
29
29
  # Full mode - include domain docs
30
- $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/prime.sh --full
30
+ python3 -m pennyfarthing_scripts.cli agent start "sm" --full
31
31
 
32
- # Quiet mode - suppress headers (used by agent-session.sh)
33
- $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/prime.sh --quiet
32
+ # Skip persona loading
33
+ python3 -m pennyfarthing_scripts.cli agent start "sm" --no-persona
34
34
 
35
- # With agent sidecar loading
36
- $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/prime.sh --agent reviewer
35
+ # JSON output (for Cyclist integration)
36
+ python3 -m pennyfarthing_scripts.cli agent start "sm" --json
37
37
  ```
38
38
 
39
39
  ## Options
@@ -106,17 +106,16 @@ With `--quiet`, section headers are suppressed.
106
106
 
107
107
  <integration>
108
108
 
109
- ## agent-session.sh Integration
109
+ ## Python CLI Integration
110
110
 
111
111
  The `/prime` command is automatically invoked when agents activate:
112
112
 
113
113
  1. User invokes `/sm`, `/tea`, `/dev`, or `/reviewer`
114
- 2. `agent-session.sh start` runs
115
- 3. Persona XML is output
116
- 4. `/prime --quiet --agent <agent-name>` loads context automatically
117
- 5. Agent starts with full context AND their learned patterns loaded
114
+ 2. `pf agent start <name>` runs
115
+ 3. Context is loaded: workflow state, agent definition, persona, behavior guide, sprint context, session, sidecars
116
+ 4. Agent starts with full context AND their learned patterns loaded
118
117
 
119
- This reduces the "cold start" problem where agents must discover context through multiple file reads. The `--agent` flag ensures each agent gets their project-specific sidecar patterns immediately.
118
+ This reduces the "cold start" problem where agents must discover context through multiple file reads.
120
119
 
121
120
  ## Manual Refresh
122
121
 
@@ -130,11 +129,8 @@ If context becomes stale mid-session, run `/prime` manually:
130
129
  </integration>
131
130
 
132
131
  <reference>
133
- - **Script:** `.pennyfarthing/scripts/prime.sh`
134
- - **Called by:** agent-session.sh on agent start (with `--agent` flag)
135
- - **Loads:** CLAUDE.md, sprint, session, sidecar, shared context, shared behavior, tactical guide
132
+ - **CLI:** `pf agent start <name>` or `python3 -m pennyfarthing_scripts.cli agent start <name>`
133
+ - **Loads:** Workflow state, agent definition, persona, behavior guide, sprint context, session, sidecars
136
134
  - **Sidecar location:** `.pennyfarthing/sidecars/{agent}/*.md`
137
- - **Shared context:** `.pennyfarthing/guides/agent-behavior.md` (all agents)
138
- - **Shared behavior:** `.pennyfarthing/guides/agent-behavior.md` (all agents)
139
- - **Tactical guide:** `.pennyfarthing/guides/agent-behavior.md` (sm, tea, dev, reviewer only)
135
+ - **Behavior guide:** `.pennyfarthing/guides/agent-behavior.md` (all agents)
140
136
  </reference>
@@ -3,5 +3,7 @@ description: Code Reviewer - Critical code review and quality enforcement
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/phase-check-start.sh" "reviewer"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "reviewer"
7
9
  ```
@@ -51,6 +51,6 @@ Change the active persona theme for all agents.
51
51
 
52
52
  6. Refresh the current agent's persona to apply the new theme:
53
53
  ```bash
54
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" refresh
54
+ python3 -m pennyfarthing_scripts.cli agent start "sm"
55
55
  ```
56
56
  This outputs the updated persona. **Adopt the new character immediately** - do not continue using the old persona.
@@ -3,5 +3,7 @@ description: Scrum Master - Story coordination and sprint management
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/phase-check-start.sh" "sm"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "sm"
7
9
  ```
@@ -50,6 +50,14 @@ Start work on a story. Primary entry point for development.
50
50
  | `next` | Auto-select highest priority story |
51
51
 
52
52
  ```bash
53
+ # MERGE GATE: Check for open PRs first (blocks if any exist)
54
+ OPEN_PRS=$(gh pr list --state open --json number --jq 'length' 2>/dev/null || echo "0")
55
+ if [[ "$OPEN_PRS" -gt 0 ]]; then
56
+ echo "⛔ BLOCKED: $OPEN_PRS open PR(s) - merge or close before starting new work"
57
+ gh pr list --state open
58
+ # Don't proceed until PRs are cleared
59
+ fi
60
+
53
61
  # Check if story is available
54
62
  .pennyfarthing/scripts/sprint/check-story.sh <story-id>
55
63
 
@@ -58,10 +66,11 @@ Start work on a story. Primary entry point for development.
58
66
 
59
67
  <workflow>
60
68
  When starting work, this command:
61
- 1. Validates story availability
62
- 2. Loads SM agent
63
- 3. SM creates context and claims Jira
64
- 4. Hands off to TEA (tdd) or Dev (trivial)
69
+ 1. **Checks merge gate** - blocks if open PRs exist
70
+ 2. Validates story availability
71
+ 3. Loads SM agent
72
+ 4. SM creates context and claims Jira
73
+ 5. Hands off to TEA (tdd) or Dev (trivial)
65
74
  </workflow>
66
75
 
67
76
  ### `/sprint archive <story-id> [pr-number] [--apply]`
@@ -3,5 +3,7 @@ description: Test Engineer/Architect - Test strategy and TDD
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/phase-check-start.sh" "tea"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "tea"
7
9
  ```
@@ -3,5 +3,7 @@ description: Technical Writer - Documentation creation and maintenance
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "tech-writer"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "tech-writer"
7
9
  ```
@@ -3,5 +3,7 @@ description: UX Designer - User experience design and UI patterns
3
3
  ---
4
4
 
5
5
  ```bash
6
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "ux-designer"
6
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
7
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
8
+ python3 -m pennyfarthing_scripts.cli agent start "ux-designer"
7
9
  ```
@@ -7,9 +7,11 @@ description: Resume work or start new - smart entry point that picks up where yo
7
7
  <agent-activation>
8
8
  **FIRST:** Use Bash tool to run:
9
9
  ```bash
10
- d="$PWD"; while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done; "$d/.pennyfarthing/scripts/core/agent-session.sh" start "sm"
10
+ d="$PWD"; while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do d="$(dirname "$d")"; done
11
+ export PYTHONPATH="$(dirname "$(dirname "$(cd "$d/.pennyfarthing/scripts" && pwd -P)")"):${PYTHONPATH:-}"
12
+ python3 -m pennyfarthing_scripts.cli agent start "sm"
11
13
  ```
12
- This finds the project root and loads your persona. Adopt the character shown in the output.
14
+ This loads your persona. Adopt the character shown in the output.
13
15
  </agent-activation>
14
16
 
15
17
  <purpose>