@pennyfarthing/core 11.1.0 → 11.2.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 (263) hide show
  1. package/README.md +8 -8
  2. package/package.json +16 -14
  3. package/packages/core/dist/cli/utils/constants.d.ts +1 -1
  4. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
  5. package/packages/core/dist/cli/utils/constants.js +2 -1
  6. package/packages/core/dist/cli/utils/constants.js.map +1 -1
  7. package/packages/core/dist/consultation/dialogue-manager.d.ts +75 -0
  8. package/packages/core/dist/consultation/dialogue-manager.d.ts.map +1 -0
  9. package/packages/core/dist/consultation/dialogue-manager.js +334 -0
  10. package/packages/core/dist/consultation/dialogue-manager.js.map +1 -0
  11. package/packages/core/dist/consultation/dialogue-manager.test.d.ts +19 -0
  12. package/packages/core/dist/consultation/dialogue-manager.test.d.ts.map +1 -0
  13. package/packages/core/dist/consultation/dialogue-manager.test.js +444 -0
  14. package/packages/core/dist/consultation/dialogue-manager.test.js.map +1 -0
  15. package/packages/core/dist/server/api/git.d.ts +13 -1
  16. package/packages/core/dist/server/api/git.d.ts.map +1 -1
  17. package/packages/core/dist/server/api/git.js +53 -34
  18. package/packages/core/dist/server/api/git.js.map +1 -1
  19. package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
  20. package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
  21. package/packages/core/dist/server/otlp-receiver.js +185 -24
  22. package/packages/core/dist/server/otlp-receiver.js.map +1 -1
  23. package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
  24. package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
  25. package/packages/core/dist/server/otlp-receiver.test.js +446 -0
  26. package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
  27. package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
  28. package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
  29. package/packages/core/dist/shared/portrait-resolver.js +27 -0
  30. package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
  31. package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
  32. package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
  33. package/packages/core/dist/shared/skill-search.test.js +2 -2
  34. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
  35. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
  36. package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
  37. package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
  38. package/pennyfarthing-dist/agents/dev.md +1 -1
  39. package/pennyfarthing-dist/agents/reviewer.md +1 -1
  40. package/pennyfarthing-dist/agents/sm-setup.md +1 -1
  41. package/pennyfarthing-dist/agents/sm.md +2 -2
  42. package/pennyfarthing-dist/agents/tea.md +1 -1
  43. package/pennyfarthing-dist/agents/testing-runner.md +2 -1
  44. package/pennyfarthing-dist/commands/pf-chore.md +2 -2
  45. package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
  46. package/pennyfarthing-dist/guides/agent-behavior.md +1 -1
  47. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
  48. package/pennyfarthing-dist/guides/bikerack.md +3 -3
  49. package/pennyfarthing-dist/guides/hooks.md +1 -1
  50. package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
  51. package/pennyfarthing-dist/guides/xml-tags.md +2 -2
  52. package/pennyfarthing-dist/scripts/README.md +1 -1
  53. package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
  54. package/pennyfarthing-dist/scripts/core/check-context.sh +1 -1
  55. package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +322 -0
  56. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
  57. package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
  58. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
  59. package/pennyfarthing-dist/scripts/git/README.md +24 -14
  60. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
  61. package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
  62. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
  63. package/pennyfarthing-dist/scripts/git/release.sh +0 -0
  64. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
  65. package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
  66. package/pennyfarthing-dist/scripts/hooks/README.md +1 -1
  67. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +1 -1
  68. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
  69. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
  70. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  71. package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +0 -0
  72. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
  73. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
  74. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
  75. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
  76. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
  77. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
  78. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
  79. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
  80. package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
  81. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
  82. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
  83. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +1 -1
  84. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
  85. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
  86. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
  87. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
  88. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
  89. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
  90. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
  91. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
  92. package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
  93. package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
  94. package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
  95. package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
  96. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
  97. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
  98. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
  99. package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
  100. package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
  101. package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
  102. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
  103. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
  104. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
  105. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
  106. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
  107. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
  108. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
  109. package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
  110. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
  111. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
  112. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
  113. package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
  114. package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
  115. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
  116. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
  117. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
  118. package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
  119. package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
  120. package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
  121. package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
  122. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
  123. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
  124. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
  125. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
  126. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
  127. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
  128. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
  129. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
  130. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
  131. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
  132. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
  133. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
  134. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
  135. package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
  136. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
  137. package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
  138. package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
  139. package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
  140. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
  141. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
  142. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
  143. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
  144. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
  145. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
  146. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
  147. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
  148. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
  149. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
  150. package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
  151. package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
  152. package/pennyfarthing-dist/skills/pf-story/scripts/create-story.sh +0 -0
  153. package/pennyfarthing-dist/skills/pf-story/scripts/size-story.sh +0 -0
  154. package/pennyfarthing-dist/skills/pf-story/scripts/story-template.sh +0 -0
  155. package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
  156. package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
  157. package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
  158. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +18 -6
  159. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +1 -1
  160. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +1 -1
  161. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
  162. package/pennyfarthing-dist/workflows/review-tandem.yaml +65 -0
  163. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +16 -8
  164. package/pennyfarthing_scripts/CLAUDE.md +26 -4
  165. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  166. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  167. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/bc/cli.py +3 -5
  171. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  172. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  173. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  174. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  181. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  182. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  183. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  184. package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
  185. package/pennyfarthing_scripts/bikerack/base_panel.py +62 -0
  186. package/pennyfarthing_scripts/bikerack/changed_panel.py +32 -28
  187. package/pennyfarthing_scripts/bikerack/cli.py +10 -11
  188. package/pennyfarthing_scripts/bikerack/debug_panel.py +31 -1
  189. package/pennyfarthing_scripts/bikerack/diffs_panel.py +74 -17
  190. package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
  191. package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
  192. package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
  193. package/pennyfarthing_scripts/bikerack/sprint_panel.py +158 -26
  194. package/pennyfarthing_scripts/bikerack/tui.py +336 -30
  195. package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
  196. package/pennyfarthing_scripts/cli.py +37 -65
  197. package/pennyfarthing_scripts/consultation/__init__.py +1 -0
  198. package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  200. package/pennyfarthing_scripts/consultation/cli.py +149 -0
  201. package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
  202. package/pennyfarthing_scripts/context.py +3 -3
  203. package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/git/__init__.py +12 -1
  206. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/git/__pycache__/hooks_installer.cpython-314.pyc +0 -0
  209. package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
  210. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  211. package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
  212. package/pennyfarthing_scripts/git/create_branches.py +3 -4
  213. package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
  214. package/pennyfarthing_scripts/git/repos.py +196 -0
  215. package/pennyfarthing_scripts/git/status_all.py +27 -11
  216. package/pennyfarthing_scripts/git/worktree.py +302 -0
  217. package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  218. package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  219. package/pennyfarthing_scripts/git_group/cli.py +143 -40
  220. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  221. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  222. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  223. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  224. package/pennyfarthing_scripts/handoff/complete_phase.py +12 -0
  225. package/pennyfarthing_scripts/handoff/resolve_gate.py +5 -14
  226. package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  227. package/pennyfarthing_scripts/hooks.py +3 -17
  228. package/pennyfarthing_scripts/pretooluse_hook.py +1 -1
  229. package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
  230. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  231. package/pennyfarthing_scripts/prime/heatmap.py +655 -0
  232. package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
  233. package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/session_start_hook.py +1 -1
  235. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/sprint/loader.py +15 -1
  237. package/pennyfarthing_scripts/sprint/story_finish.py +14 -0
  238. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  239. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  240. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  241. package/pennyfarthing_scripts/tests/test_bikerack.py +51 -51
  242. package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
  243. package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
  244. package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
  245. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  246. package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
  247. package/pennyfarthing_scripts/validate/cli.py +17 -5
  248. package/pennyfarthing_scripts/workflow/__init__.py +40 -0
  249. package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  251. package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/workflow/cli.py +1099 -0
  255. package/pennyfarthing_scripts/workflow/helpers.py +241 -0
  256. package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
  257. package/pennyfarthing_scripts/workflow/state.py +112 -0
  258. package/scripts/README.md +41 -0
  259. package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
  260. package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
  261. package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
  262. package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
  263. package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
@@ -1,497 +1,6 @@
1
- #!/usr/bin/env zsh
2
- # Worktree management utilities for parallel development work
3
- # Usage: worktree-manager.sh {create|remove|list|status|ports|cd} [args]
4
- #
5
- # Configuration (choose one):
6
- # 1. repos.yaml: Define repos in .pennyfarthing/repos.yaml (recommended)
7
- # 2. Legacy env vars: Set API_REPO and UI_REPO in .claude/project/hooks/setup-env.sh
8
-
1
+ #!/usr/bin/env bash
2
+ # DEPRECATED: Use `pf git worktree` instead.
3
+ # This shim forwards to the Python CLI.
9
4
  set -e
10
-
11
- # Self-locate: derive paths from this script's position
12
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd -P)"
13
-
14
- # Load environment
15
- if [ -f "$PROJECT_ROOT/.env" ]; then
16
- set -a; source "$PROJECT_ROOT/.env"; set +a
17
- fi
18
-
19
- # Source project hooks if available
20
- if [ -f "$PROJECT_ROOT/.claude/project/hooks/setup-env.sh" ]; then
21
- source "$PROJECT_ROOT/.claude/project/hooks/setup-env.sh"
22
- fi
23
-
24
- # Source repo utilities (handles repos.yaml or legacy env vars)
25
- REPO_UTILS_LAZY=1 # Don't auto-load, we'll do it after validation
26
- source "$SCRIPT_DIR/../misc/repo-utils.sh"
27
-
28
- WORKTREE_ROOT="${WORKTREE_ROOT:-$PROJECT_ROOT/worktrees}"
29
- WORKTREE_PORT_OFFSET="${WORKTREE_PORT_OFFSET:-100}"
30
-
31
- # ============================================================================
32
- # Services Configuration
33
- # ============================================================================
34
-
35
- # Load services configuration from pennyfarthing-settings.yaml
36
- # Sets: _SERVICES_JSON, _PORT_OFFSET
37
- # Returns 1 if no services configured
38
- load_services_config() {
39
- local config_file="${PROJECT_ROOT}/.claude/project/pennyfarthing-settings.yaml"
40
-
41
- if [[ ! -f "$config_file" ]]; then
42
- _SERVICES_JSON=""
43
- _PORT_OFFSET=$WORKTREE_PORT_OFFSET
44
- return 1
45
- fi
46
-
47
- # Parse services config using yq (preferred) or Python fallback
48
- local config
49
- if command -v yq &>/dev/null; then
50
- # Check if services section exists
51
- local has_services
52
- has_services=$(yq '.services.definitions' "$config_file" 2>/dev/null)
53
- if [[ -z "$has_services" || "$has_services" == "null" ]]; then
54
- _SERVICES_JSON=""
55
- _PORT_OFFSET=$WORKTREE_PORT_OFFSET
56
- return 1
57
- fi
58
-
59
- local port_offset
60
- port_offset=$(yq '.services.port_offset // 100' "$config_file" 2>/dev/null)
61
- local definitions_json
62
- definitions_json=$(yq -o=json '.services.definitions' "$config_file" 2>/dev/null)
63
-
64
- _PORT_OFFSET=$port_offset
65
- _SERVICES_JSON="$definitions_json"
66
- return 0
67
- elif command -v python3 &>/dev/null; then
68
- config=$(python3 -c "
69
- import yaml
70
- import json
71
- import sys
72
-
73
- try:
74
- with open('$config_file', 'r') as f:
75
- settings = yaml.safe_load(f)
76
-
77
- if not settings or 'services' not in settings or 'definitions' not in settings['services']:
78
- sys.exit(1)
79
-
80
- svc = settings['services']
81
- port_offset = svc.get('port_offset', ${WORKTREE_PORT_OFFSET})
82
- definitions = svc['definitions']
83
-
84
- # Ensure env_var is set for each service
85
- for d in definitions:
86
- if 'env_var' not in d:
87
- d['env_var'] = d['name'].upper().replace(' ', '_').replace('-', '_') + '_PORT'
88
-
89
- print(f'_PORT_OFFSET={port_offset}')
90
- print(f\"_SERVICES_JSON='{json.dumps(definitions)}'\")
91
- except Exception:
92
- sys.exit(1)
93
- " 2>/dev/null)
94
-
95
- if [[ $? -eq 0 && -n "$config" ]]; then
96
- eval "$config"
97
- return 0
98
- fi
99
- fi
100
-
101
- _SERVICES_JSON=""
102
- _PORT_OFFSET=$WORKTREE_PORT_OFFSET
103
- return 1
104
- }
105
-
106
- # Load and validate repo configuration
107
- load_repos_config
108
-
109
- if [ "$(get_repo_count)" -eq 0 ]; then
110
- echo "❌ Error: No repositories configured"
111
- echo ""
112
- echo "Option 1: Create .pennyfarthing/repos.yaml (recommended for multi-repo projects)"
113
- echo "Option 2: Set API_REPO and UI_REPO in .claude/project/hooks/setup-env.sh"
114
- exit 1
115
- fi
116
-
117
- # Ensure worktree root exists
118
- mkdir -p "$WORKTREE_ROOT"
119
-
120
- show_help() {
121
- cat << EOF
122
- Worktree Manager - Parallel Development Tool
123
-
124
- Usage: worktree-manager.sh <command> [options]
125
-
126
- Commands:
127
- create <name> <branch> [repos] Create worktree(s) for parallel work
128
- remove <name> Remove worktree and clean up
129
- list List all active worktrees
130
- status Show detailed worktree status
131
- ports <name> Get port configuration for worktree
132
- cd <name> Print path to worktree (use with: cd \$(./scripts/worktree-manager.sh cd <name>))
133
- config Show current repo configuration
134
-
135
- Examples:
136
- # Create worktree for all repos
137
- ./scripts/worktree-manager.sh create 5-1a feat/5-1a-file-upload
138
-
139
- # Create worktree for specific repo type
140
- ./scripts/worktree-manager.sh create bug-123 fix/bug-123-validation api
141
-
142
- # Create worktree for specific repos (comma-separated)
143
- ./scripts/worktree-manager.sh create feat-x feat/x-feature adapter-a,adapter-b
144
-
145
- # Get ports for running dev servers
146
- eval \$(./scripts/worktree-manager.sh ports 5-1a)
147
- echo "API: \$API_PORT, UI: \$UI_PORT"
148
-
149
- # Remove worktree after merge
150
- ./scripts/worktree-manager.sh remove 5-1a
151
-
152
- # Show repo configuration
153
- ./scripts/worktree-manager.sh config
154
-
155
- Repos Filter (third argument):
156
- all - All configured repos (default)
157
- api - Only repos of type 'api'
158
- ui - Only repos of type 'ui'
159
- adapter - Only repos of type 'adapter'
160
- service - Only repos of type 'service'
161
- repo1,repo2 - Comma-separated list of specific repo names
162
-
163
- Configuration:
164
- Option 1 (recommended): Create .pennyfarthing/repos.yaml
165
- Option 2 (legacy): Set API_REPO and UI_REPO environment variables
166
-
167
- Session Files:
168
- Session files are named after story IDs: .session/{story-id}-session.md
169
- Example: .session/5-1a-session.md (with worktree field inside)
170
- Session files are managed by SM agent, not worktree-manager.
171
-
172
- Environment Variables:
173
- PROJECT_ROOT - Project root directory
174
- WORKTREE_ROOT - Where worktrees are created (default: \$PROJECT_ROOT/worktrees)
175
- WORKTREE_PORT_OFFSET - Port offset between worktrees (default: 100)
176
-
177
- EOF
178
- }
179
-
180
- create_worktree() {
181
- local WT_NAME="$1"
182
- local BRANCH="$2"
183
- local REPOS_FILTER="${3:-all}" # all, api, ui, adapter, service, or comma-separated names
184
-
185
- if [ -z "$WT_NAME" ] || [ -z "$BRANCH" ]; then
186
- echo "❌ Usage: worktree-manager.sh create <name> <branch> [repos-filter]"
187
- echo " repos-filter: all, api, ui, adapter, service, or comma-separated names"
188
- exit 1
189
- fi
190
-
191
- local WT_PATH="$WORKTREE_ROOT/$WT_NAME"
192
-
193
- # Check if worktree already exists
194
- if [ -d "$WT_PATH" ]; then
195
- echo "❌ Worktree '$WT_NAME' already exists at $WT_PATH"
196
- exit 1
197
- fi
198
-
199
- mkdir -p "$WT_PATH"
200
-
201
- echo "🔧 Creating worktree: $WT_NAME"
202
- echo " Branch: $BRANCH"
203
- echo " Path: $WT_PATH"
204
- echo " Repos: $REPOS_FILTER"
205
- echo ""
206
-
207
- # Get repos to create worktrees for (handle legacy 'both' as 'all')
208
- local repos_filter="$REPOS_FILTER"
209
- [ "$repos_filter" = "both" ] && repos_filter="all"
210
-
211
- local repos_to_create
212
- repos_to_create=$(filter_repos "$repos_filter")
213
-
214
- local created_repos=()
215
-
216
- while IFS= read -r repo; do
217
- [ -z "$repo" ] && continue
218
-
219
- local repo_path
220
- repo_path=$(get_repo_path "$repo")
221
- local full_path="$PROJECT_ROOT/$repo_path"
222
- local repo_type
223
- repo_type=$(get_repo_type "$repo")
224
-
225
- if [ -d "$full_path" ]; then
226
- echo "📦 Creating worktree for $repo ($repo_type)..."
227
- cd "$full_path"
228
-
229
- # Check if branch exists locally, remotely, or needs to be created
230
- if git show-ref --verify --quiet "refs/heads/$BRANCH" 2>/dev/null; then
231
- git worktree add "$WT_PATH/$repo" "$BRANCH"
232
- elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH" 2>/dev/null; then
233
- git worktree add "$WT_PATH/$repo" "$BRANCH"
234
- else
235
- # Create new branch from develop (or main if develop doesn't exist)
236
- local base_branch="develop"
237
- if ! git show-ref --verify --quiet "refs/heads/develop" 2>/dev/null; then
238
- base_branch="main"
239
- fi
240
- git worktree add -b "$BRANCH" "$WT_PATH/$repo" "$base_branch"
241
- fi
242
- echo " ✅ $repo worktree created"
243
- created_repos+=("$repo")
244
- else
245
- echo " ⚠️ Repo not found: $full_path"
246
- fi
247
- done <<< "$repos_to_create"
248
-
249
- echo ""
250
- echo "✅ Worktree '$WT_NAME' created successfully!"
251
- echo ""
252
- echo "📝 Session file: Use /sm to create .session/{story-id}-session.md"
253
- echo ""
254
- echo "Next steps:"
255
- for repo in "${created_repos[@]}"; do
256
- echo " cd $WT_PATH/$repo"
257
- done
258
- echo ""
259
- echo "Start dev servers with custom ports:"
260
- echo " eval \$(./scripts/worktree-manager.sh ports $WT_NAME)"
261
- }
262
-
263
- remove_worktree() {
264
- local WT_NAME="$1"
265
-
266
- if [ -z "$WT_NAME" ]; then
267
- echo "❌ Usage: worktree-manager.sh remove <name>"
268
- exit 1
269
- fi
270
-
271
- local WT_PATH="$WORKTREE_ROOT/$WT_NAME"
272
-
273
- if [ ! -d "$WT_PATH" ]; then
274
- echo "❌ Worktree '$WT_NAME' not found at $WT_PATH"
275
- exit 1
276
- fi
277
-
278
- echo "🗑️ Removing worktree: $WT_NAME"
279
-
280
- # Remove worktrees for all configured repos
281
- for repo in $(get_repos); do
282
- local repo_path
283
- repo_path=$(get_repo_path "$repo")
284
-
285
- if [ -d "$WT_PATH/$repo" ]; then
286
- echo " Removing $repo worktree..."
287
- cd "$PROJECT_ROOT/$repo_path"
288
- git worktree remove "$WT_PATH/$repo" --force 2>/dev/null || true
289
- fi
290
- done
291
-
292
- # Clean up directory
293
- rm -rf "$WT_PATH"
294
-
295
- # Note: Session files are managed by SM agent
296
- # Use /sm to finish work and archive the session file
297
- echo ""
298
- echo " Note: Session file (if any) should be archived via /sm finish"
299
-
300
- # Prune worktree references for all repos
301
- for repo in $(get_repos); do
302
- local repo_path
303
- repo_path=$(get_repo_path "$repo")
304
- if [ -d "$PROJECT_ROOT/$repo_path" ]; then
305
- cd "$PROJECT_ROOT/$repo_path" && git worktree prune 2>/dev/null || true
306
- fi
307
- done
308
-
309
- echo ""
310
- echo "✅ Worktree '$WT_NAME' removed successfully!"
311
- }
312
-
313
- list_worktrees() {
314
- echo "=== Active Worktrees ==="
315
- echo ""
316
-
317
- for repo in $(get_repos); do
318
- local repo_path
319
- repo_path=$(get_repo_path "$repo")
320
- local repo_type
321
- repo_type=$(get_repo_type "$repo")
322
-
323
- if [ -d "$PROJECT_ROOT/$repo_path" ]; then
324
- echo "📦 $repo ($repo_type):"
325
- cd "$PROJECT_ROOT/$repo_path" && git worktree list
326
- echo ""
327
- fi
328
- done
329
-
330
- echo "📁 Worktree Directory:"
331
- if [ -d "$WORKTREE_ROOT" ] && [ "$(ls -A "$WORKTREE_ROOT" 2>/dev/null)" ]; then
332
- ls -la "$WORKTREE_ROOT"
333
- else
334
- echo " (empty)"
335
- fi
336
- }
337
-
338
- show_status() {
339
- echo "=== Worktree Status ==="
340
- echo ""
341
-
342
- if [ ! -d "$WORKTREE_ROOT" ] || [ -z "$(ls -A "$WORKTREE_ROOT" 2>/dev/null)" ]; then
343
- echo "No active worktrees."
344
- echo ""
345
- echo "Create one with:"
346
- echo " ./scripts/worktree-manager.sh create <name> <branch>"
347
- return
348
- fi
349
-
350
- for wt in "$WORKTREE_ROOT"/*/; do
351
- if [ -d "$wt" ]; then
352
- local WT_NAME=$(basename "$wt")
353
- echo "📁 $WT_NAME"
354
- echo " Path: $wt"
355
-
356
- # Show status for each configured repo
357
- for repo in $(get_repos); do
358
- if [ -d "$wt/$repo" ]; then
359
- local repo_type
360
- repo_type=$(get_repo_type "$repo")
361
- local branch=$(cd "$wt/$repo" && git branch --show-current 2>/dev/null || echo "unknown")
362
- local status_count=$(cd "$wt/$repo" && git status --short 2>/dev/null | wc -l | tr -d ' ')
363
- echo " $repo ($repo_type): $branch ($status_count uncommitted)"
364
- fi
365
- done
366
-
367
- # Check for session files that reference this worktree
368
- local found_session=""
369
- for sf in "$PROJECT_ROOT"/.session/*-session.md; do
370
- if [ -f "$sf" ] && grep -q "worktree: $WT_NAME" "$sf" 2>/dev/null; then
371
- found_session=$(basename "$sf")
372
- break
373
- fi
374
- done
375
- if [ -n "$found_session" ]; then
376
- echo " Session: ✅ .session/$found_session"
377
- else
378
- echo " Session: ❌ (no session file references this worktree)"
379
- fi
380
-
381
- # Show ports (from services config)
382
- local WT_INDEX=$(ls -1 "$WORKTREE_ROOT" 2>/dev/null | grep -n "^$WT_NAME$" | cut -d: -f1)
383
- WT_INDEX=${WT_INDEX:-1}
384
- if load_services_config; then
385
- local OFFSET=$((_PORT_OFFSET * WT_INDEX))
386
- local ports_display
387
- ports_display=$(python3 -c "
388
- import json
389
- services = $_SERVICES_JSON
390
- offset = $OFFSET
391
- parts = []
392
- for svc in services:
393
- name = svc['name']
394
- port = svc['base_port'] + offset
395
- parts.append(f'{name}={port}')
396
- print(', '.join(parts))
397
- " 2>/dev/null)
398
- echo " Ports: $ports_display"
399
- else
400
- echo " Ports: (no services configured)"
401
- fi
402
- echo ""
403
- fi
404
- done
405
- }
406
-
407
- get_ports() {
408
- local WT_NAME="$1"
409
-
410
- if [ -z "$WT_NAME" ]; then
411
- echo "# Usage: worktree-manager.sh ports <name>" >&2
412
- echo "# Outputs shell variables for service ports" >&2
413
- exit 1
414
- fi
415
-
416
- # Load services configuration
417
- if ! load_services_config; then
418
- echo "# No services configured in .claude/project/pennyfarthing-settings.yaml" >&2
419
- echo "# Add a 'services' section with 'definitions' array" >&2
420
- exit 1
421
- fi
422
-
423
- # Calculate port offset based on worktree index
424
- local WT_INDEX=$(ls -1 "$WORKTREE_ROOT" 2>/dev/null | grep -n "^$WT_NAME$" | cut -d: -f1)
425
- WT_INDEX=${WT_INDEX:-1}
426
- local OFFSET=$((_PORT_OFFSET * WT_INDEX))
427
-
428
- # Output worktree info
429
- echo "export WORKTREE_PATH=$WORKTREE_ROOT/$WT_NAME"
430
- echo "export WORKTREE_INDEX=$WT_INDEX"
431
- echo "export WORKTREE_PORT_OFFSET=$OFFSET"
432
-
433
- # Generate exports for each configured service
434
- python3 -c "
435
- import json
436
-
437
- services = $_SERVICES_JSON
438
- offset = $OFFSET
439
-
440
- for svc in services:
441
- env_var = svc.get('env_var', svc['name'].upper().replace(' ', '_').replace('-', '_') + '_PORT')
442
- port = svc['base_port'] + offset
443
- print(f'export {env_var}={port}')
444
- " 2>/dev/null
445
- }
446
-
447
- get_path() {
448
- local WT_NAME="$1"
449
-
450
- if [ -z "$WT_NAME" ]; then
451
- echo "❌ Usage: worktree-manager.sh cd <name>"
452
- exit 1
453
- fi
454
-
455
- local WT_PATH="$WORKTREE_ROOT/$WT_NAME"
456
-
457
- if [ ! -d "$WT_PATH" ]; then
458
- echo "❌ Worktree '$WT_NAME' not found" >&2
459
- exit 1
460
- fi
461
-
462
- echo "$WT_PATH"
463
- }
464
-
465
- # Main command dispatch
466
- case "${1:-help}" in
467
- create)
468
- create_worktree "$2" "$3" "$4"
469
- ;;
470
- remove|rm|delete)
471
- remove_worktree "$2"
472
- ;;
473
- list|ls)
474
- list_worktrees
475
- ;;
476
- status|st)
477
- show_status
478
- ;;
479
- ports)
480
- get_ports "$2"
481
- ;;
482
- cd|path)
483
- get_path "$2"
484
- ;;
485
- config)
486
- show_config
487
- ;;
488
- help|--help|-h)
489
- show_help
490
- ;;
491
- *)
492
- echo "❌ Unknown command: $1"
493
- echo ""
494
- show_help
495
- exit 1
496
- ;;
497
- esac
5
+ echo "DEPRECATED: worktree-manager.sh — use 'pf git worktree' instead" >&2
6
+ exec pf git worktree "$@"
@@ -21,7 +21,7 @@ Git hooks and Claude Code hooks.
21
21
  Git hooks are installed via:
22
22
 
23
23
  ```bash
24
- .pennyfarthing/scripts/git/install-git-hooks.sh
24
+ pf git install-hooks
25
25
  ```
26
26
 
27
27
  Claude hooks are configured in `.claude/settings.json`.
@@ -42,7 +42,7 @@ BELL_QUEUE_FILE="$PROJECT_ROOT/.pennyfarthing/bell-queue.json"
42
42
  # Detect Cyclist — bell queue is a Cyclist-only feature
43
43
  IS_CYCLIST=false
44
44
  CYCLIST_PORT=""
45
- PORT_FILE="$PROJECT_ROOT/.cyclist-port"
45
+ PORT_FILE="$PROJECT_ROOT/.wheelhub-port"
46
46
  if [[ -f "$PORT_FILE" ]]; then
47
47
  CYCLIST_PORT=$(cat "$PORT_FILE" 2>/dev/null)
48
48
  if [[ -n "$CYCLIST_PORT" ]] && [[ "$CYCLIST_PORT" =~ ^[0-9]+$ ]]; then
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  # otel-auto-config.sh - Auto-configure OTEL for Cyclist web mode (Story 20-1)
3
3
  #
4
- # This hook checks for a .cyclist-port file in the project directory.
4
+ # This hook checks for a .wheelhub-port file in the project directory.
5
5
  # If found, it sets the OTEL environment variables to connect Claude Code
6
6
  # telemetry to the running Cyclist server.
7
7
  #
@@ -9,24 +9,22 @@
9
9
  # source /path/to/otel-auto-config.sh
10
10
  #
11
11
  # Prerequisites:
12
- # - Cyclist must be running in web mode (writes .cyclist-port file)
12
+ # - Cyclist must be running in web mode (writes .wheelhub-port file)
13
13
  # - CLAUDE_PROJECT_DIR must be set (standard in Claude Code environment)
14
14
 
15
15
  # Determine project directory
16
16
  PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
17
17
 
18
- # Check .cyclist-port first, then .bikerack-port as fallback
18
+ # Read port from .wheelhub-port (used by both Cyclist and BikeRack)
19
19
  PORT=""
20
- for PORT_FILE in "$PROJECT_DIR/.cyclist-port" "$PROJECT_DIR/.bikerack-port"; do
21
- if [[ -f "$PORT_FILE" ]]; then
22
- PORT=$(cat "$PORT_FILE" 2>/dev/null)
23
- # Validate port is a number
24
- if [[ "$PORT" =~ ^[0-9]+$ ]]; then
25
- break
26
- fi
20
+ PORT_FILE="$PROJECT_DIR/.wheelhub-port"
21
+ if [[ -f "$PORT_FILE" ]]; then
22
+ PORT=$(cat "$PORT_FILE" 2>/dev/null)
23
+ # Validate port is a number
24
+ if [[ ! "$PORT" =~ ^[0-9]+$ ]]; then
27
25
  PORT=""
28
26
  fi
29
- done
27
+ fi
30
28
 
31
29
  # Configure OTEL if a valid port was found
32
30
  if [[ -n "$PORT" ]]; then
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -31,7 +31,7 @@ fi
31
31
  touch "$WELCOME_LOCK"
32
32
 
33
33
  # Check if running in Cyclist (port file exists)
34
- PORT_FILE="$PROJECT_ROOT/.cyclist-port"
34
+ PORT_FILE="$PROJECT_ROOT/.wheelhub-port"
35
35
  IN_CYCLIST=false
36
36
  if [[ -f "$PORT_FILE" ]]; then
37
37
  CYCLIST_PORT=$(cat "$PORT_FILE" 2>/dev/null)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes