@pennyfarthing/core 10.0.1 → 10.0.3

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 (1145) hide show
  1. package/README.md +287 -0
  2. package/package.json +34 -38
  3. package/packages/core/dist/cli/commands/doctor-file-layout.test.d.ts +13 -0
  4. package/packages/core/dist/cli/commands/doctor-file-layout.test.d.ts.map +1 -0
  5. package/packages/core/dist/cli/commands/doctor-file-layout.test.js +234 -0
  6. package/packages/core/dist/cli/commands/doctor-file-layout.test.js.map +1 -0
  7. package/packages/core/dist/cli/commands/doctor.d.ts +36 -0
  8. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -0
  9. package/packages/core/dist/cli/commands/doctor.js +1650 -0
  10. package/packages/core/dist/cli/commands/doctor.js.map +1 -0
  11. package/packages/core/dist/cli/commands/e2e-fresh-install.test.js +395 -0
  12. package/packages/core/dist/cli/commands/e2e-fresh-install.test.js.map +1 -0
  13. package/packages/core/dist/cli/commands/e2e-upgrade.test.js +562 -0
  14. package/packages/core/dist/cli/commands/e2e-upgrade.test.js.map +1 -0
  15. package/packages/core/dist/cli/commands/hooks-consolidation.test.d.ts +19 -0
  16. package/packages/core/dist/cli/commands/hooks-consolidation.test.d.ts.map +1 -0
  17. package/packages/core/dist/cli/commands/hooks-consolidation.test.js +358 -0
  18. package/packages/core/dist/cli/commands/hooks-consolidation.test.js.map +1 -0
  19. package/packages/core/dist/cli/commands/update.d.ts.map +1 -0
  20. package/packages/core/dist/cli/commands/update.js +454 -0
  21. package/packages/core/dist/cli/commands/update.js.map +1 -0
  22. package/packages/core/dist/cli/utils/settings.d.ts.map +1 -0
  23. package/packages/core/dist/cli/utils/settings.js +377 -0
  24. package/packages/core/dist/cli/utils/settings.js.map +1 -0
  25. package/packages/core/dist/cli/utils/themes.d.ts +105 -0
  26. package/packages/core/dist/cli/utils/themes.d.ts.map +1 -0
  27. package/packages/core/dist/cli/utils/themes.js.map +1 -0
  28. package/pennyfarthing-dist/agents/README.md +348 -0
  29. package/pennyfarthing-dist/agents/architect.md +180 -0
  30. package/pennyfarthing-dist/agents/dev.md +169 -0
  31. package/pennyfarthing-dist/agents/devops.md +203 -0
  32. package/pennyfarthing-dist/agents/handoff.md +235 -0
  33. package/pennyfarthing-dist/agents/orchestrator.md +182 -0
  34. package/pennyfarthing-dist/agents/pm.md +152 -0
  35. package/pennyfarthing-dist/agents/reviewer-preflight.md +129 -0
  36. package/pennyfarthing-dist/agents/reviewer.md +197 -0
  37. package/pennyfarthing-dist/agents/sm-file-summary.md +79 -0
  38. package/pennyfarthing-dist/agents/sm-finish.md +82 -0
  39. package/pennyfarthing-dist/agents/sm-handoff.md +129 -0
  40. package/pennyfarthing-dist/agents/sm-setup.md +251 -0
  41. package/pennyfarthing-dist/agents/sm.md +305 -0
  42. package/pennyfarthing-dist/agents/tea.md +161 -0
  43. package/pennyfarthing-dist/agents/tech-writer.md +226 -0
  44. package/pennyfarthing-dist/agents/testing-runner.md +184 -0
  45. package/pennyfarthing-dist/agents/ux-designer.md +236 -0
  46. package/pennyfarthing-dist/agents/workflow-status-check.md +96 -0
  47. package/pennyfarthing-dist/commands/architect.md +9 -0
  48. package/pennyfarthing-dist/commands/benchmark-control.md +69 -0
  49. package/pennyfarthing-dist/commands/benchmark.md +485 -0
  50. package/pennyfarthing-dist/commands/brainstorming.md +91 -0
  51. package/pennyfarthing-dist/commands/check.md +156 -0
  52. package/pennyfarthing-dist/commands/chore.md +218 -0
  53. package/pennyfarthing-dist/commands/close-epic.md +139 -0
  54. package/pennyfarthing-dist/commands/continue-session.md +218 -0
  55. package/pennyfarthing-dist/commands/create-branches-from-story.md +358 -0
  56. package/pennyfarthing-dist/commands/create-theme.md +29 -0
  57. package/pennyfarthing-dist/commands/dev.md +9 -0
  58. package/pennyfarthing-dist/commands/devops.md +9 -0
  59. package/pennyfarthing-dist/commands/fix-blocker.md +22 -0
  60. package/pennyfarthing-dist/commands/git-cleanup.md +57 -0
  61. package/pennyfarthing-dist/commands/health-check.md +143 -0
  62. package/pennyfarthing-dist/commands/help.md +264 -0
  63. package/pennyfarthing-dist/commands/job-fair.md +102 -0
  64. package/pennyfarthing-dist/commands/list-themes.md +21 -0
  65. package/pennyfarthing-dist/commands/new-work.md +23 -0
  66. package/pennyfarthing-dist/commands/orchestrator.md +9 -0
  67. package/pennyfarthing-dist/commands/parallel-work.md +73 -0
  68. package/pennyfarthing-dist/commands/party-mode.md +77 -0
  69. package/pennyfarthing-dist/commands/patch.md +210 -0
  70. package/pennyfarthing-dist/commands/permissions.md +193 -0
  71. package/pennyfarthing-dist/commands/pm.md +9 -0
  72. package/pennyfarthing-dist/commands/prime.md +136 -0
  73. package/pennyfarthing-dist/commands/release.md +74 -0
  74. package/pennyfarthing-dist/commands/repo-status.md +49 -0
  75. package/pennyfarthing-dist/commands/retro.md +200 -0
  76. package/pennyfarthing-dist/commands/reviewer.md +9 -0
  77. package/pennyfarthing-dist/commands/run-ci.md +116 -0
  78. package/pennyfarthing-dist/commands/set-theme.md +56 -0
  79. package/pennyfarthing-dist/commands/setup.md +65 -0
  80. package/pennyfarthing-dist/commands/show-theme.md +21 -0
  81. package/pennyfarthing-dist/commands/sm.md +9 -0
  82. package/pennyfarthing-dist/commands/solo.md +447 -0
  83. package/pennyfarthing-dist/commands/sprint-planning.md +109 -0
  84. package/pennyfarthing-dist/commands/sprint.md +142 -0
  85. package/pennyfarthing-dist/commands/standalone.md +194 -0
  86. package/pennyfarthing-dist/commands/start-epic.md +168 -0
  87. package/pennyfarthing-dist/commands/sync-epic-to-jira.md +184 -0
  88. package/pennyfarthing-dist/commands/sync-work-with-sprint.md +373 -0
  89. package/pennyfarthing-dist/commands/tea.md +9 -0
  90. package/pennyfarthing-dist/commands/tech-writer.md +9 -0
  91. package/pennyfarthing-dist/commands/theme-maker.md +676 -0
  92. package/pennyfarthing-dist/commands/update-domain-docs.md +83 -0
  93. package/pennyfarthing-dist/commands/ux-designer.md +9 -0
  94. package/pennyfarthing-dist/commands/work.md +25 -0
  95. package/pennyfarthing-dist/commands/workflow.md +21 -0
  96. package/pennyfarthing-dist/guides/agent-behavior.md +92 -0
  97. package/pennyfarthing-dist/guides/agent-coordination.md +475 -0
  98. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +432 -0
  99. package/pennyfarthing-dist/guides/agent-template-strategic.md +148 -0
  100. package/pennyfarthing-dist/guides/agent-template-tactical.md +162 -0
  101. package/pennyfarthing-dist/guides/bell-mode.md +65 -0
  102. package/pennyfarthing-dist/guides/benchmarks.md +62 -0
  103. package/pennyfarthing-dist/guides/bikelane.md +86 -0
  104. package/pennyfarthing-dist/guides/hooks.md +230 -0
  105. package/pennyfarthing-dist/guides/measurement-framework.md +210 -0
  106. package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +766 -0
  107. package/pennyfarthing-dist/guides/patterns/fan-out-fan-in-pattern.md +574 -0
  108. package/pennyfarthing-dist/guides/patterns/helper-delegation-pattern.md +488 -0
  109. package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +402 -0
  110. package/pennyfarthing-dist/guides/permission-protocol.md +188 -0
  111. package/pennyfarthing-dist/guides/persona-loading.md +46 -0
  112. package/pennyfarthing-dist/guides/prime.md +72 -0
  113. package/pennyfarthing-dist/guides/prompt-patterns.md +338 -0
  114. package/pennyfarthing-dist/guides/reflector.md +59 -0
  115. package/pennyfarthing-dist/guides/relay-mode.md +53 -0
  116. package/pennyfarthing-dist/guides/scale-levels.md +114 -0
  117. package/pennyfarthing-dist/guides/session-artifacts.md +193 -0
  118. package/pennyfarthing-dist/guides/session-schema.md +346 -0
  119. package/pennyfarthing-dist/guides/skill-schema.md +412 -0
  120. package/pennyfarthing-dist/guides/tirepump.md +54 -0
  121. package/pennyfarthing-dist/guides/workflow-schema.md +257 -0
  122. package/pennyfarthing-dist/guides/workflow-step-schema.md +512 -0
  123. package/pennyfarthing-dist/guides/worktree-mode.md +113 -0
  124. package/pennyfarthing-dist/guides/xml-tags.md +627 -0
  125. package/pennyfarthing-dist/output-styles/teaching.md +33 -0
  126. package/pennyfarthing-dist/output-styles/terse.md +20 -0
  127. package/pennyfarthing-dist/output-styles/verbose.md +28 -0
  128. package/pennyfarthing-dist/personas/themes/a-team.yaml +331 -0
  129. package/pennyfarthing-dist/personas/themes/alice-in-wonderland.yaml +324 -0
  130. package/pennyfarthing-dist/personas/themes/battlestar-galactica.yaml +283 -0
  131. package/pennyfarthing-dist/personas/themes/blade-runner.yaml +289 -0
  132. package/pennyfarthing-dist/personas/themes/catch-22.yaml +304 -0
  133. package/pennyfarthing-dist/personas/themes/control.yaml +201 -0
  134. package/pennyfarthing-dist/personas/themes/cowboy-bebop.yaml +315 -0
  135. package/pennyfarthing-dist/personas/themes/discworld.yaml +334 -0
  136. package/pennyfarthing-dist/personas/themes/doctor-who.yaml +284 -0
  137. package/pennyfarthing-dist/personas/themes/dune.yaml +296 -0
  138. package/pennyfarthing-dist/personas/themes/firefly.yaml +307 -0
  139. package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +275 -0
  140. package/pennyfarthing-dist/personas/themes/harry-potter.yaml +302 -0
  141. package/pennyfarthing-dist/personas/themes/hitchhikers-guide.yaml +311 -0
  142. package/pennyfarthing-dist/personas/themes/lord-of-the-rings.yaml +326 -0
  143. package/pennyfarthing-dist/personas/themes/mad-max.yaml +343 -0
  144. package/pennyfarthing-dist/personas/themes/mash.yaml +329 -0
  145. package/pennyfarthing-dist/personas/themes/princess-bride.yaml +334 -0
  146. package/pennyfarthing-dist/personas/themes/sandman.yaml +282 -0
  147. package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +358 -0
  148. package/pennyfarthing-dist/personas/themes/star-wars.yaml +297 -0
  149. package/pennyfarthing-dist/personas/themes/the-expanse.yaml +337 -0
  150. package/pennyfarthing-dist/personas/themes/the-matrix.yaml +341 -0
  151. package/pennyfarthing-dist/personas/themes/watchmen.yaml +285 -0
  152. package/pennyfarthing-dist/personas/themes/west-wing.yaml +284 -0
  153. package/pennyfarthing-dist/personas/themes/x-files.yaml +296 -0
  154. package/pennyfarthing-dist/scripts/README.md +87 -0
  155. package/pennyfarthing-dist/scripts/core/README.md +25 -0
  156. package/pennyfarthing-dist/scripts/core/agent-session.sh +390 -0
  157. package/pennyfarthing-dist/scripts/core/check-context.sh +194 -0
  158. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +112 -0
  159. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +90 -0
  160. package/pennyfarthing-dist/scripts/core/prime.sh +30 -0
  161. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +21 -0
  162. package/pennyfarthing-dist/scripts/git/README.md +25 -0
  163. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +267 -0
  164. package/pennyfarthing-dist/scripts/git/git-status-all.sh +152 -0
  165. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +79 -0
  166. package/pennyfarthing-dist/scripts/git/release.sh +246 -0
  167. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +497 -0
  168. package/pennyfarthing-dist/scripts/health/drift-detection.sh +156 -0
  169. package/pennyfarthing-dist/scripts/hooks/README.md +32 -0
  170. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  171. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +106 -0
  172. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +95 -0
  173. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +65 -0
  174. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +32 -0
  175. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +35 -0
  176. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +150 -0
  177. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +190 -0
  178. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +71 -0
  179. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +42 -0
  180. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +20 -0
  181. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +499 -0
  182. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +30 -0
  183. package/pennyfarthing-dist/scripts/hooks/session-start.sh +97 -0
  184. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +65 -0
  185. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +78 -0
  186. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +94 -0
  187. package/pennyfarthing-dist/scripts/jira/README.md +36 -0
  188. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +16 -0
  189. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +16 -0
  190. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +22 -0
  191. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +16 -0
  192. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +18 -0
  193. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +16 -0
  194. package/pennyfarthing-dist/scripts/lib/README.md +29 -0
  195. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +177 -0
  196. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +136 -0
  197. package/pennyfarthing-dist/scripts/lib/common.sh +212 -0
  198. package/pennyfarthing-dist/scripts/lib/file-lock.sh +269 -0
  199. package/pennyfarthing-dist/scripts/lib/find-root.sh +58 -0
  200. package/pennyfarthing-dist/scripts/lib/logging.sh +186 -0
  201. package/pennyfarthing-dist/scripts/lib/retry.sh +76 -0
  202. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +102 -0
  203. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +91 -0
  204. package/pennyfarthing-dist/scripts/misc/README.md +44 -0
  205. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +13 -0
  206. package/pennyfarthing-dist/scripts/misc/add_short_names.py +226 -0
  207. package/pennyfarthing-dist/scripts/misc/backlog.sh +77 -0
  208. package/pennyfarthing-dist/scripts/misc/check-status.sh +247 -0
  209. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +231 -0
  210. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +107 -0
  211. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +74 -0
  212. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +10 -0
  213. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +319 -0
  214. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +141 -0
  215. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +778 -0
  216. package/pennyfarthing-dist/scripts/misc/run-ci.sh +212 -0
  217. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +7 -0
  218. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +319 -0
  219. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +193 -0
  220. package/pennyfarthing-dist/scripts/misc/statusline.sh +257 -0
  221. package/pennyfarthing-dist/scripts/misc/uninstall.sh +275 -0
  222. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +160 -0
  223. package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +417 -0
  224. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +54 -0
  225. package/pennyfarthing-dist/scripts/sprint/README.md +29 -0
  226. package/pennyfarthing-dist/scripts/sprint/archive-story.sh +133 -0
  227. package/pennyfarthing-dist/scripts/sprint/available-stories.sh +91 -0
  228. package/pennyfarthing-dist/scripts/sprint/check-story.sh +158 -0
  229. package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +52 -0
  230. package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +63 -0
  231. package/pennyfarthing-dist/scripts/sprint/list-future.sh +145 -0
  232. package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +110 -0
  233. package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +148 -0
  234. package/pennyfarthing-dist/scripts/sprint/sprint-common.sh +415 -0
  235. package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +33 -0
  236. package/pennyfarthing-dist/scripts/sprint/sprint-metrics.sh +230 -0
  237. package/pennyfarthing-dist/scripts/sprint/sprint-status.sh +134 -0
  238. package/pennyfarthing-dist/scripts/sprint/validate-sprint-yaml.sh +139 -0
  239. package/pennyfarthing-dist/scripts/story/README.md +23 -0
  240. package/pennyfarthing-dist/scripts/story/create-story.sh +19 -0
  241. package/pennyfarthing-dist/scripts/story/size-story.sh +18 -0
  242. package/pennyfarthing-dist/scripts/story/story-template.sh +18 -0
  243. package/pennyfarthing-dist/scripts/test/README.md +23 -0
  244. package/pennyfarthing-dist/scripts/test/ensure-swebench-data.sh +59 -0
  245. package/pennyfarthing-dist/scripts/test/ground-truth-judge.py +220 -0
  246. package/pennyfarthing-dist/scripts/test/swebench-judge.py +374 -0
  247. package/pennyfarthing-dist/scripts/test/test-cache.sh +165 -0
  248. package/pennyfarthing-dist/scripts/test/test-setup.sh +337 -0
  249. package/pennyfarthing-dist/scripts/tests/check.test.sh +582 -0
  250. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +515 -0
  251. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +599 -0
  252. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +332 -0
  253. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +573 -0
  254. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +859 -0
  255. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +662 -0
  256. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +589 -0
  257. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +106 -0
  258. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +597 -0
  259. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +514 -0
  260. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +517 -0
  261. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +331 -0
  262. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +647 -0
  263. package/pennyfarthing-dist/scripts/theme/README.md +22 -0
  264. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +13 -0
  265. package/pennyfarthing-dist/scripts/theme/compute_theme_tiers.py +402 -0
  266. package/pennyfarthing-dist/scripts/theme/list-themes.sh +30 -0
  267. package/pennyfarthing-dist/scripts/theme/update-theme-tiers.sh +97 -0
  268. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +576 -0
  269. package/pennyfarthing-dist/scripts/workflow/README.md +28 -0
  270. package/pennyfarthing-dist/scripts/workflow/check.py +502 -0
  271. package/pennyfarthing-dist/scripts/workflow/check.sh +24 -0
  272. package/pennyfarthing-dist/scripts/workflow/complete-step.py +304 -0
  273. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +154 -0
  274. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +222 -0
  275. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +61 -0
  276. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +13 -0
  277. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +124 -0
  278. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +34 -0
  279. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +157 -0
  280. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +132 -0
  281. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +250 -0
  282. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +161 -0
  283. package/pennyfarthing-dist/skills/agentic-patterns/SKILL.md +246 -0
  284. package/pennyfarthing-dist/skills/changelog/SKILL.md +385 -0
  285. package/pennyfarthing-dist/skills/code-review/SKILL.md +172 -0
  286. package/pennyfarthing-dist/skills/context-engineering/SKILL.md +277 -0
  287. package/pennyfarthing-dist/skills/cyclist/SKILL.md +88 -0
  288. package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +461 -0
  289. package/pennyfarthing-dist/skills/finalize-run/SKILL.md +261 -0
  290. package/pennyfarthing-dist/skills/jira/SKILL.md +207 -0
  291. package/pennyfarthing-dist/skills/judge/SKILL.md +644 -0
  292. package/pennyfarthing-dist/skills/just/SKILL.md +414 -0
  293. package/pennyfarthing-dist/skills/mermaid/SKILL.md +256 -0
  294. package/pennyfarthing-dist/skills/otel/skill.md +227 -0
  295. package/pennyfarthing-dist/skills/permissions/skill.md +157 -0
  296. package/pennyfarthing-dist/skills/persona-benchmark/SKILL.md +187 -0
  297. package/pennyfarthing-dist/skills/skill-registry.schema.json +107 -0
  298. package/pennyfarthing-dist/skills/skill-registry.yaml +393 -0
  299. package/pennyfarthing-dist/skills/sprint/scripts/archive-story.sh +101 -0
  300. package/pennyfarthing-dist/skills/sprint/scripts/available-stories.sh +97 -0
  301. package/pennyfarthing-dist/skills/sprint/scripts/check-story.sh +164 -0
  302. package/pennyfarthing-dist/skills/sprint/scripts/create-jira-epic.sh +23 -0
  303. package/pennyfarthing-dist/skills/sprint/scripts/new-sprint.sh +116 -0
  304. package/pennyfarthing-dist/skills/sprint/scripts/promote-epic.sh +164 -0
  305. package/pennyfarthing-dist/skills/sprint/scripts/sprint-info.sh +39 -0
  306. package/pennyfarthing-dist/skills/sprint/scripts/sprint-status.sh +147 -0
  307. package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +23 -0
  308. package/pennyfarthing-dist/skills/sprint/skill.md +465 -0
  309. package/pennyfarthing-dist/skills/story/scripts/create-story.sh +159 -0
  310. package/pennyfarthing-dist/skills/story/scripts/size-story.sh +198 -0
  311. package/pennyfarthing-dist/skills/story/scripts/story-template.sh +162 -0
  312. package/pennyfarthing-dist/skills/story/skill.md +219 -0
  313. package/pennyfarthing-dist/skills/systematic-debugging/SKILL.md +446 -0
  314. package/pennyfarthing-dist/skills/testing/SKILL.md +121 -0
  315. package/pennyfarthing-dist/skills/testing/references/troubleshooting.md +124 -0
  316. package/pennyfarthing-dist/skills/theme/skill.md +141 -0
  317. package/pennyfarthing-dist/skills/theme-creation/SKILL.md +178 -0
  318. package/pennyfarthing-dist/skills/workflow/scripts/list-workflows.sh +91 -0
  319. package/pennyfarthing-dist/skills/workflow/scripts/resume-workflow.sh +163 -0
  320. package/pennyfarthing-dist/skills/workflow/scripts/show-workflow.sh +138 -0
  321. package/pennyfarthing-dist/skills/workflow/scripts/start-workflow.sh +273 -0
  322. package/pennyfarthing-dist/skills/workflow/scripts/workflow-status.sh +167 -0
  323. package/pennyfarthing-dist/skills/workflow/skill.md +345 -0
  324. package/pennyfarthing-dist/skills/yq/SKILL.md +272 -0
  325. package/pennyfarthing-dist/templates/LEADERBOARD.schema.yaml +187 -0
  326. package/pennyfarthing-dist/templates/LEADERBOARD.template.md +59 -0
  327. package/pennyfarthing-dist/templates/agent-scopes.yaml.template +276 -0
  328. package/pennyfarthing-dist/templates/pennyfarthing-settings.yaml.template +61 -0
  329. package/pennyfarthing-dist/templates/persona-config.yaml.template +22 -0
  330. package/pennyfarthing-dist/templates/preferences.yaml.template +15 -0
  331. package/pennyfarthing-dist/templates/settings.local.json.template +138 -0
  332. package/pennyfarthing-dist/templates/setup-env.sh.template +18 -0
  333. package/pennyfarthing-dist/templates/shared-context.md.template +70 -0
  334. package/pennyfarthing-dist/templates/sidecar/decisions.md.template +40 -0
  335. package/pennyfarthing-dist/templates/sidecar/gotchas.md.template +37 -0
  336. package/pennyfarthing-dist/templates/sidecar/patterns.md.template +34 -0
  337. package/pennyfarthing-dist/workflows/agent-docs.yaml +70 -0
  338. package/pennyfarthing-dist/workflows/architecture/steps/step-01-initialize.md +113 -0
  339. package/pennyfarthing-dist/workflows/architecture/steps/step-01b-continue.md +105 -0
  340. package/pennyfarthing-dist/workflows/architecture/steps/step-02-context.md +127 -0
  341. package/pennyfarthing-dist/workflows/architecture/steps/step-03-patterns.md +145 -0
  342. package/pennyfarthing-dist/workflows/architecture/steps/step-04-components.md +150 -0
  343. package/pennyfarthing-dist/workflows/architecture/steps/step-05-interfaces.md +145 -0
  344. package/pennyfarthing-dist/workflows/architecture/steps/step-06-risks.md +154 -0
  345. package/pennyfarthing-dist/workflows/architecture/steps/step-07-document.md +172 -0
  346. package/pennyfarthing-dist/workflows/architecture/templates/architecture-decision.md +102 -0
  347. package/pennyfarthing-dist/workflows/architecture.yaml +65 -0
  348. package/pennyfarthing-dist/workflows/bdd.yaml +60 -0
  349. package/pennyfarthing-dist/workflows/brainstorming/brain-methods.csv +62 -0
  350. package/pennyfarthing-dist/workflows/brainstorming/checklist.md +44 -0
  351. package/pennyfarthing-dist/workflows/brainstorming/instructions.md +736 -0
  352. package/pennyfarthing-dist/workflows/brainstorming/workflow.yaml +49 -0
  353. package/pennyfarthing-dist/workflows/code-review/checklist.md +23 -0
  354. package/pennyfarthing-dist/workflows/code-review/instructions.md +234 -0
  355. package/pennyfarthing-dist/workflows/code-review/workflow.yaml +51 -0
  356. package/pennyfarthing-dist/workflows/dev-story/checklist.md +80 -0
  357. package/pennyfarthing-dist/workflows/dev-story/instructions.xml +410 -0
  358. package/pennyfarthing-dist/workflows/dev-story/workflow.yaml +50 -0
  359. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-01-validate-prerequisites.md +281 -0
  360. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-02-design-epics.md +256 -0
  361. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-03-create-stories.md +298 -0
  362. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-04-final-validation.md +177 -0
  363. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +145 -0
  364. package/pennyfarthing-dist/workflows/epics-and-stories/templates/epics-template.md +57 -0
  365. package/pennyfarthing-dist/workflows/epics-and-stories/workflow.yaml +28 -0
  366. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +103 -0
  367. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-02-categorize.md +147 -0
  368. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-03-execute.md +215 -0
  369. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +97 -0
  370. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +78 -0
  371. package/pennyfarthing-dist/workflows/git-cleanup.yaml +59 -0
  372. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-01-document-discovery.md +211 -0
  373. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-02-prd-analysis.md +199 -0
  374. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-03-epic-coverage-validation.md +202 -0
  375. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-04-ux-alignment.md +162 -0
  376. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-05-epic-quality-review.md +280 -0
  377. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-06-final-assessment.md +158 -0
  378. package/pennyfarthing-dist/workflows/implementation-readiness/templates/readiness-report-template.md +4 -0
  379. package/pennyfarthing-dist/workflows/implementation-readiness/workflow.yaml +40 -0
  380. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-01-connect.md +257 -0
  381. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-02-explore.md +107 -0
  382. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-03-fix.md +127 -0
  383. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-04-commit.md +122 -0
  384. package/pennyfarthing-dist/workflows/interactive-debug/workflow.yaml +51 -0
  385. package/pennyfarthing-dist/workflows/patch.yaml +67 -0
  386. package/pennyfarthing-dist/workflows/prd/data/domain-complexity.csv +13 -0
  387. package/pennyfarthing-dist/workflows/prd/data/prd-purpose.md +197 -0
  388. package/pennyfarthing-dist/workflows/prd/data/project-types.csv +11 -0
  389. package/pennyfarthing-dist/workflows/prd/steps-c/step-01-init.md +197 -0
  390. package/pennyfarthing-dist/workflows/prd/steps-c/step-01b-continue.md +159 -0
  391. package/pennyfarthing-dist/workflows/prd/steps-c/step-02-discovery.md +230 -0
  392. package/pennyfarthing-dist/workflows/prd/steps-c/step-03-success.md +232 -0
  393. package/pennyfarthing-dist/workflows/prd/steps-c/step-04-journeys.md +219 -0
  394. package/pennyfarthing-dist/workflows/prd/steps-c/step-05-domain.md +213 -0
  395. package/pennyfarthing-dist/workflows/prd/steps-c/step-06-innovation.md +232 -0
  396. package/pennyfarthing-dist/workflows/prd/steps-c/step-07-project-type.md +243 -0
  397. package/pennyfarthing-dist/workflows/prd/steps-c/step-08-scoping.md +234 -0
  398. package/pennyfarthing-dist/workflows/prd/steps-c/step-09-functional.md +237 -0
  399. package/pennyfarthing-dist/workflows/prd/steps-c/step-10-nonfunctional.md +248 -0
  400. package/pennyfarthing-dist/workflows/prd/steps-c/step-11-polish.md +223 -0
  401. package/pennyfarthing-dist/workflows/prd/steps-c/step-12-complete.md +186 -0
  402. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-01-discovery.md +253 -0
  403. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-01b-legacy-conversion.md +214 -0
  404. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-02-review.md +255 -0
  405. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-03-edit.md +259 -0
  406. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-04-complete.md +174 -0
  407. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-01-discovery.md +224 -0
  408. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-02-format-detection.md +197 -0
  409. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-02b-parity-check.md +215 -0
  410. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-03-density-validation.md +180 -0
  411. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +220 -0
  412. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-05-measurability-validation.md +234 -0
  413. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-06-traceability-validation.md +223 -0
  414. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +211 -0
  415. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +249 -0
  416. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-09-project-type-validation.md +269 -0
  417. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-10-smart-validation.md +215 -0
  418. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +270 -0
  419. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-12-completeness-validation.md +248 -0
  420. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-13-report-complete.md +238 -0
  421. package/pennyfarthing-dist/workflows/prd/templates/prd-template.md +10 -0
  422. package/pennyfarthing-dist/workflows/prd/workflow.yaml +42 -0
  423. package/pennyfarthing-dist/workflows/product-brief/steps/step-01-init.md +195 -0
  424. package/pennyfarthing-dist/workflows/product-brief/steps/step-01b-continue.md +180 -0
  425. package/pennyfarthing-dist/workflows/product-brief/steps/step-02-vision.md +221 -0
  426. package/pennyfarthing-dist/workflows/product-brief/steps/step-03-users.md +224 -0
  427. package/pennyfarthing-dist/workflows/product-brief/steps/step-04-metrics.md +228 -0
  428. package/pennyfarthing-dist/workflows/product-brief/steps/step-05-scope.md +243 -0
  429. package/pennyfarthing-dist/workflows/product-brief/steps/step-06-complete.md +216 -0
  430. package/pennyfarthing-dist/workflows/product-brief/templates/product-brief.template.md +10 -0
  431. package/pennyfarthing-dist/workflows/product-brief/workflow.yaml +31 -0
  432. package/pennyfarthing-dist/workflows/project-context/project-context-template.md +21 -0
  433. package/pennyfarthing-dist/workflows/project-context/steps/step-01-discover.md +206 -0
  434. package/pennyfarthing-dist/workflows/project-context/steps/step-02-generate.md +349 -0
  435. package/pennyfarthing-dist/workflows/project-context/steps/step-03-complete.md +306 -0
  436. package/pennyfarthing-dist/workflows/project-context/workflow.yaml +27 -0
  437. package/pennyfarthing-dist/workflows/project-setup/steps/step-01-discover.md +157 -0
  438. package/pennyfarthing-dist/workflows/project-setup/steps/step-02-clone-repos.md +217 -0
  439. package/pennyfarthing-dist/workflows/project-setup/steps/step-03-repos-yaml.md +159 -0
  440. package/pennyfarthing-dist/workflows/project-setup/steps/step-04-claude-md.md +186 -0
  441. package/pennyfarthing-dist/workflows/project-setup/steps/step-05-shared-context.md +185 -0
  442. package/pennyfarthing-dist/workflows/project-setup/steps/step-06-task-runner.md +279 -0
  443. package/pennyfarthing-dist/workflows/project-setup/steps/step-07-theme.md +200 -0
  444. package/pennyfarthing-dist/workflows/project-setup/steps/step-08-theme-packs.md +142 -0
  445. package/pennyfarthing-dist/workflows/project-setup/steps/step-09-cyclist.md +245 -0
  446. package/pennyfarthing-dist/workflows/project-setup/steps/step-10-complete.md +204 -0
  447. package/pennyfarthing-dist/workflows/project-setup/workflow.yaml +41 -0
  448. package/pennyfarthing-dist/workflows/quick-dev/steps/step-01-mode-detection.md +177 -0
  449. package/pennyfarthing-dist/workflows/quick-dev/steps/step-02-context-gathering.md +143 -0
  450. package/pennyfarthing-dist/workflows/quick-dev/steps/step-03-execute.md +138 -0
  451. package/pennyfarthing-dist/workflows/quick-dev/steps/step-04-self-check.md +135 -0
  452. package/pennyfarthing-dist/workflows/quick-dev/steps/step-05-adversarial-review.md +129 -0
  453. package/pennyfarthing-dist/workflows/quick-dev/steps/step-06-resolve-findings.md +163 -0
  454. package/pennyfarthing-dist/workflows/quick-dev/workflow.yaml +27 -0
  455. package/pennyfarthing-dist/workflows/quick-spec/steps/step-01-understand.md +201 -0
  456. package/pennyfarthing-dist/workflows/quick-spec/steps/step-02-investigate.md +156 -0
  457. package/pennyfarthing-dist/workflows/quick-spec/steps/step-03-generate.md +140 -0
  458. package/pennyfarthing-dist/workflows/quick-spec/steps/step-04-review.md +203 -0
  459. package/pennyfarthing-dist/workflows/quick-spec/tech-spec-template.md +74 -0
  460. package/pennyfarthing-dist/workflows/quick-spec/workflow.yaml +27 -0
  461. package/pennyfarthing-dist/workflows/release/steps/step-01-preflight.md +105 -0
  462. package/pennyfarthing-dist/workflows/release/steps/step-02-bump.md +95 -0
  463. package/pennyfarthing-dist/workflows/release/steps/step-03-changelog.md +125 -0
  464. package/pennyfarthing-dist/workflows/release/steps/step-04-readme.md +101 -0
  465. package/pennyfarthing-dist/workflows/release/steps/step-05-claude-md.md +102 -0
  466. package/pennyfarthing-dist/workflows/release/steps/step-06-retro.md +59 -0
  467. package/pennyfarthing-dist/workflows/release/steps/step-07-commit.md +109 -0
  468. package/pennyfarthing-dist/workflows/release/steps/step-08-merge.md +65 -0
  469. package/pennyfarthing-dist/workflows/release/steps/step-09-push.md +75 -0
  470. package/pennyfarthing-dist/workflows/release/steps/step-10-publish.md +93 -0
  471. package/pennyfarthing-dist/workflows/release/steps/step-11-finalize.md +71 -0
  472. package/pennyfarthing-dist/workflows/release.yaml +62 -0
  473. package/pennyfarthing-dist/workflows/research/steps-domain/step-01-init.md +159 -0
  474. package/pennyfarthing-dist/workflows/research/steps-domain/step-02-domain-analysis.md +253 -0
  475. package/pennyfarthing-dist/workflows/research/steps-domain/step-03-competitive-landscape.md +263 -0
  476. package/pennyfarthing-dist/workflows/research/steps-domain/step-04-regulatory-focus.md +232 -0
  477. package/pennyfarthing-dist/workflows/research/steps-domain/step-05-technical-trends.md +260 -0
  478. package/pennyfarthing-dist/workflows/research/steps-domain/step-06-research-synthesis.md +477 -0
  479. package/pennyfarthing-dist/workflows/research/steps-market/step-01-init.md +205 -0
  480. package/pennyfarthing-dist/workflows/research/steps-market/step-02-customer-behavior.md +262 -0
  481. package/pennyfarthing-dist/workflows/research/steps-market/step-02-customer-insights.md +227 -0
  482. package/pennyfarthing-dist/workflows/research/steps-market/step-03-customer-pain-points.md +275 -0
  483. package/pennyfarthing-dist/workflows/research/steps-market/step-04-customer-decisions.md +286 -0
  484. package/pennyfarthing-dist/workflows/research/steps-market/step-05-competitive-analysis.md +203 -0
  485. package/pennyfarthing-dist/workflows/research/steps-market/step-06-research-completion.md +510 -0
  486. package/pennyfarthing-dist/workflows/research/steps-technical/step-01-init.md +159 -0
  487. package/pennyfarthing-dist/workflows/research/steps-technical/step-02-technical-overview.md +264 -0
  488. package/pennyfarthing-dist/workflows/research/steps-technical/step-03-integration-patterns.md +274 -0
  489. package/pennyfarthing-dist/workflows/research/steps-technical/step-04-architectural-patterns.md +228 -0
  490. package/pennyfarthing-dist/workflows/research/steps-technical/step-05-implementation-research.md +267 -0
  491. package/pennyfarthing-dist/workflows/research/steps-technical/step-06-research-synthesis.md +522 -0
  492. package/pennyfarthing-dist/workflows/research/templates/research.template.md +29 -0
  493. package/pennyfarthing-dist/workflows/research/workflow.yaml +45 -0
  494. package/pennyfarthing-dist/workflows/retrospective/checklist.md +31 -0
  495. package/pennyfarthing-dist/workflows/retrospective/instructions.md +1443 -0
  496. package/pennyfarthing-dist/workflows/retrospective/workflow.yaml +50 -0
  497. package/pennyfarthing-dist/workflows/sprint-planning/checklist.md +33 -0
  498. package/pennyfarthing-dist/workflows/sprint-planning/sprint-status-template.yaml +55 -0
  499. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-01-parse-epic-files.md +69 -0
  500. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-02-build-sprint-status.md +61 -0
  501. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-03-status-detection.md +80 -0
  502. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-04-generate-status-file.md +90 -0
  503. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-05-validate-and-report.md +78 -0
  504. package/pennyfarthing-dist/workflows/sprint-planning/workflow.yaml +34 -0
  505. package/pennyfarthing-dist/workflows/tdd.yaml +50 -0
  506. package/pennyfarthing-dist/workflows/trivial.yaml +40 -0
  507. package/pennyfarthing-dist/workflows/ux-design/steps/step-01-init.md +141 -0
  508. package/pennyfarthing-dist/workflows/ux-design/steps/step-01b-continue.md +133 -0
  509. package/pennyfarthing-dist/workflows/ux-design/steps/step-02-discovery.md +196 -0
  510. package/pennyfarthing-dist/workflows/ux-design/steps/step-03-core-experience.md +222 -0
  511. package/pennyfarthing-dist/workflows/ux-design/steps/step-04-emotional-response.md +225 -0
  512. package/pennyfarthing-dist/workflows/ux-design/steps/step-05-inspiration.md +240 -0
  513. package/pennyfarthing-dist/workflows/ux-design/steps/step-06-design-system.md +258 -0
  514. package/pennyfarthing-dist/workflows/ux-design/steps/step-07-defining-experience.md +260 -0
  515. package/pennyfarthing-dist/workflows/ux-design/steps/step-08-visual-foundation.md +230 -0
  516. package/pennyfarthing-dist/workflows/ux-design/steps/step-09-design-directions.md +230 -0
  517. package/pennyfarthing-dist/workflows/ux-design/steps/step-10-user-journeys.md +247 -0
  518. package/pennyfarthing-dist/workflows/ux-design/steps/step-11-component-strategy.md +254 -0
  519. package/pennyfarthing-dist/workflows/ux-design/steps/step-12-ux-patterns.md +243 -0
  520. package/pennyfarthing-dist/workflows/ux-design/steps/step-13-responsive-accessibility.md +270 -0
  521. package/pennyfarthing-dist/workflows/ux-design/steps/step-14-complete.md +234 -0
  522. package/pennyfarthing-dist/workflows/ux-design/ux-design-template.md +13 -0
  523. package/pennyfarthing-dist/workflows/ux-design/workflow.yaml +41 -0
  524. package/pennyfarthing_scripts/README.md +66 -0
  525. package/pennyfarthing_scripts/__init__.py +17 -0
  526. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  527. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  528. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  529. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  530. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  531. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  532. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  533. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  534. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  535. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  536. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  537. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  538. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  539. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  540. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  541. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  542. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  543. package/pennyfarthing_scripts/bellmode_hook.py +154 -0
  544. package/pennyfarthing_scripts/brownfield/__init__.py +35 -0
  545. package/pennyfarthing_scripts/brownfield/__main__.py +7 -0
  546. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  547. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  548. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  549. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  550. package/pennyfarthing_scripts/brownfield/cli.py +131 -0
  551. package/pennyfarthing_scripts/brownfield/discover.py +753 -0
  552. package/pennyfarthing_scripts/cli.py +184 -0
  553. package/pennyfarthing_scripts/common/__init__.py +49 -0
  554. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  555. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  556. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  557. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  558. package/pennyfarthing_scripts/common/config.py +91 -0
  559. package/pennyfarthing_scripts/common/output.py +180 -0
  560. package/pennyfarthing_scripts/common/themes.py +253 -0
  561. package/pennyfarthing_scripts/config.py +21 -0
  562. package/pennyfarthing_scripts/context.py +414 -0
  563. package/pennyfarthing_scripts/git/__init__.py +29 -0
  564. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  565. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  566. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  567. package/pennyfarthing_scripts/git/create_branches.py +439 -0
  568. package/pennyfarthing_scripts/git/status_all.py +310 -0
  569. package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +7 -0
  570. package/pennyfarthing_scripts/hooks.py +454 -0
  571. package/pennyfarthing_scripts/hotspots/__init__.py +31 -0
  572. package/pennyfarthing_scripts/hotspots/__main__.py +6 -0
  573. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  574. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  575. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  576. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  577. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  578. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  579. package/pennyfarthing_scripts/hotspots/analyze.py +472 -0
  580. package/pennyfarthing_scripts/hotspots/cli.py +152 -0
  581. package/pennyfarthing_scripts/hotspots/formatters.py +109 -0
  582. package/pennyfarthing_scripts/hotspots/models.py +60 -0
  583. package/pennyfarthing_scripts/jira/__init__.py +99 -0
  584. package/pennyfarthing_scripts/jira/__main__.py +10 -0
  585. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  586. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  587. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  588. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  589. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  590. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  591. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  592. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  593. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  594. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  595. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  596. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  597. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  598. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  599. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  600. package/pennyfarthing_scripts/jira/bidirectional.py +561 -0
  601. package/pennyfarthing_scripts/jira/claim.py +211 -0
  602. package/pennyfarthing_scripts/jira/cli.py +277 -0
  603. package/pennyfarthing_scripts/jira/client.py +762 -0
  604. package/pennyfarthing_scripts/jira/create.py +267 -0
  605. package/pennyfarthing_scripts/jira/epic.py +176 -0
  606. package/pennyfarthing_scripts/jira/operations.py +124 -0
  607. package/pennyfarthing_scripts/jira/reconcile.py +277 -0
  608. package/pennyfarthing_scripts/jira/story.py +219 -0
  609. package/pennyfarthing_scripts/jira/sync.py +350 -0
  610. package/pennyfarthing_scripts/jira_bidirectional_sync.py +37 -0
  611. package/pennyfarthing_scripts/jira_epic_creation.py +30 -0
  612. package/pennyfarthing_scripts/jira_sync.py +36 -0
  613. package/pennyfarthing_scripts/jira_sync_story.py +30 -0
  614. package/pennyfarthing_scripts/migration/__init__.py +39 -0
  615. package/pennyfarthing_scripts/migration/__main__.py +10 -0
  616. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  617. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  618. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  619. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  620. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  621. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  622. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  623. package/pennyfarthing_scripts/migration/cli.py +304 -0
  624. package/pennyfarthing_scripts/migration/session.py +384 -0
  625. package/pennyfarthing_scripts/migration/skill.py +188 -0
  626. package/pennyfarthing_scripts/migration/step.py +229 -0
  627. package/pennyfarthing_scripts/migration/validate.py +282 -0
  628. package/pennyfarthing_scripts/output.py +37 -0
  629. package/pennyfarthing_scripts/patch_mode.py +449 -0
  630. package/pennyfarthing_scripts/preflight/__init__.py +17 -0
  631. package/pennyfarthing_scripts/preflight/__main__.py +10 -0
  632. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  633. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  634. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  635. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  636. package/pennyfarthing_scripts/preflight/cli.py +141 -0
  637. package/pennyfarthing_scripts/preflight/finish.py +382 -0
  638. package/pennyfarthing_scripts/pretooluse_hook.py +193 -0
  639. package/pennyfarthing_scripts/prime/__init__.py +125 -0
  640. package/pennyfarthing_scripts/prime/__main__.py +8 -0
  641. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  642. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  643. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  644. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  645. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  646. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  647. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  648. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  649. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  650. package/pennyfarthing_scripts/prime/cli.py +645 -0
  651. package/pennyfarthing_scripts/prime/loader.py +239 -0
  652. package/pennyfarthing_scripts/prime/models.py +206 -0
  653. package/pennyfarthing_scripts/prime/persona.py +309 -0
  654. package/pennyfarthing_scripts/prime/session.py +183 -0
  655. package/pennyfarthing_scripts/prime/tiers.py +201 -0
  656. package/pennyfarthing_scripts/prime/workflow.py +275 -0
  657. package/pennyfarthing_scripts/schema_validation_hook.py +306 -0
  658. package/pennyfarthing_scripts/sprint/__init__.py +66 -0
  659. package/pennyfarthing_scripts/sprint/__main__.py +10 -0
  660. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  661. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  662. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  663. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  664. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  665. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  666. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  667. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  668. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  669. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  670. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  671. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  672. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  673. package/pennyfarthing_scripts/sprint/archive.py +108 -0
  674. package/pennyfarthing_scripts/sprint/archive_epic.py +399 -0
  675. package/pennyfarthing_scripts/sprint/cli.py +373 -0
  676. package/pennyfarthing_scripts/sprint/import_epic.py +431 -0
  677. package/pennyfarthing_scripts/sprint/loader.py +193 -0
  678. package/pennyfarthing_scripts/sprint/status.py +122 -0
  679. package/pennyfarthing_scripts/sprint/story_add.py +187 -0
  680. package/pennyfarthing_scripts/sprint/story_update.py +181 -0
  681. package/pennyfarthing_scripts/sprint/validate_cmd.py +268 -0
  682. package/pennyfarthing_scripts/sprint/validator.py +570 -0
  683. package/pennyfarthing_scripts/sprint/work.py +192 -0
  684. package/pennyfarthing_scripts/sprint/yaml_io.py +258 -0
  685. package/pennyfarthing_scripts/story/__init__.py +67 -0
  686. package/pennyfarthing_scripts/story/__main__.py +10 -0
  687. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  688. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  689. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  690. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  691. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  692. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  693. package/pennyfarthing_scripts/story/cli.py +105 -0
  694. package/pennyfarthing_scripts/story/create.py +167 -0
  695. package/pennyfarthing_scripts/story/size.py +113 -0
  696. package/pennyfarthing_scripts/story/template.py +151 -0
  697. package/pennyfarthing_scripts/swebench.py +216 -0
  698. package/pennyfarthing_scripts/tests/__init__.py +1 -0
  699. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  700. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  701. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  702. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  703. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  704. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  705. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  706. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  707. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  708. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  709. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  710. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  711. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  712. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  713. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  714. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  715. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  716. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  717. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  718. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  719. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  720. package/pennyfarthing_scripts/tests/conftest.py +106 -0
  721. package/pennyfarthing_scripts/tests/test_brownfield.py +842 -0
  722. package/pennyfarthing_scripts/tests/test_cli_modules.py +245 -0
  723. package/pennyfarthing_scripts/tests/test_common.py +180 -0
  724. package/pennyfarthing_scripts/tests/test_git_utils.py +866 -0
  725. package/pennyfarthing_scripts/tests/test_jira_package.py +334 -0
  726. package/pennyfarthing_scripts/tests/test_package_structure.py +372 -0
  727. package/pennyfarthing_scripts/tests/test_patch_mode.py +830 -0
  728. package/pennyfarthing_scripts/tests/test_prime.py +1050 -0
  729. package/pennyfarthing_scripts/tests/test_sprint_package.py +236 -0
  730. package/pennyfarthing_scripts/tests/test_sprint_validator.py +731 -0
  731. package/pennyfarthing_scripts/tests/test_story_add.py +921 -0
  732. package/pennyfarthing_scripts/tests/test_story_package.py +156 -0
  733. package/pennyfarthing_scripts/tests/test_story_update.py +769 -0
  734. package/pennyfarthing_scripts/tests/test_tiers.py +1090 -0
  735. package/pennyfarthing_scripts/tests/test_token_counting.py +559 -0
  736. package/pennyfarthing_scripts/tests/test_validate_cmd.py +500 -0
  737. package/pennyfarthing_scripts/tests/test_workflow_check.py +341 -0
  738. package/pennyfarthing_scripts/tests/test_yaml_io.py +698 -0
  739. package/pennyfarthing_scripts/welcome_hook.py +157 -0
  740. package/pennyfarthing_scripts/workflow.py +287 -0
  741. package/dist/cli/commands/doctor.d.ts +0 -28
  742. package/dist/cli/commands/doctor.d.ts.map +0 -1
  743. package/dist/cli/commands/doctor.js +0 -1429
  744. package/dist/cli/commands/doctor.js.map +0 -1
  745. package/dist/cli/commands/e2e-fresh-install.test.js +0 -395
  746. package/dist/cli/commands/e2e-fresh-install.test.js.map +0 -1
  747. package/dist/cli/commands/e2e-upgrade.test.js +0 -562
  748. package/dist/cli/commands/e2e-upgrade.test.js.map +0 -1
  749. package/dist/cli/commands/update.d.ts.map +0 -1
  750. package/dist/cli/commands/update.js +0 -402
  751. package/dist/cli/commands/update.js.map +0 -1
  752. package/dist/cli/utils/settings.d.ts.map +0 -1
  753. package/dist/cli/utils/settings.js +0 -353
  754. package/dist/cli/utils/settings.js.map +0 -1
  755. package/dist/cli/utils/themes.d.ts +0 -104
  756. package/dist/cli/utils/themes.d.ts.map +0 -1
  757. package/dist/cli/utils/themes.js.map +0 -1
  758. /package/{bin → packages/core/bin}/pennyfarthing.js +0 -0
  759. /package/{dist → packages/core/dist}/bmad/context-reader.d.ts +0 -0
  760. /package/{dist → packages/core/dist}/bmad/context-reader.d.ts.map +0 -0
  761. /package/{dist → packages/core/dist}/bmad/context-reader.js +0 -0
  762. /package/{dist → packages/core/dist}/bmad/context-reader.js.map +0 -0
  763. /package/{dist → packages/core/dist}/bmad/context-reader.test.d.ts +0 -0
  764. /package/{dist → packages/core/dist}/bmad/context-reader.test.d.ts.map +0 -0
  765. /package/{dist → packages/core/dist}/bmad/context-reader.test.js +0 -0
  766. /package/{dist → packages/core/dist}/bmad/context-reader.test.js.map +0 -0
  767. /package/{dist → packages/core/dist}/bmad/epics-parser.d.ts +0 -0
  768. /package/{dist → packages/core/dist}/bmad/epics-parser.d.ts.map +0 -0
  769. /package/{dist → packages/core/dist}/bmad/epics-parser.js +0 -0
  770. /package/{dist → packages/core/dist}/bmad/epics-parser.js.map +0 -0
  771. /package/{dist → packages/core/dist}/bmad/epics-parser.test.d.ts +0 -0
  772. /package/{dist → packages/core/dist}/bmad/epics-parser.test.d.ts.map +0 -0
  773. /package/{dist → packages/core/dist}/bmad/epics-parser.test.js +0 -0
  774. /package/{dist → packages/core/dist}/bmad/epics-parser.test.js.map +0 -0
  775. /package/{dist → packages/core/dist}/bmad/index.d.ts +0 -0
  776. /package/{dist → packages/core/dist}/bmad/index.d.ts.map +0 -0
  777. /package/{dist → packages/core/dist}/bmad/index.js +0 -0
  778. /package/{dist → packages/core/dist}/bmad/index.js.map +0 -0
  779. /package/{dist → packages/core/dist}/bmad/status-sync.d.ts +0 -0
  780. /package/{dist → packages/core/dist}/bmad/status-sync.d.ts.map +0 -0
  781. /package/{dist → packages/core/dist}/bmad/status-sync.js +0 -0
  782. /package/{dist → packages/core/dist}/bmad/status-sync.js.map +0 -0
  783. /package/{dist → packages/core/dist}/bmad/status-sync.test.d.ts +0 -0
  784. /package/{dist → packages/core/dist}/bmad/status-sync.test.d.ts.map +0 -0
  785. /package/{dist → packages/core/dist}/bmad/status-sync.test.js +0 -0
  786. /package/{dist → packages/core/dist}/bmad/status-sync.test.js.map +0 -0
  787. /package/{dist → packages/core/dist}/bmad/story-exporter.d.ts +0 -0
  788. /package/{dist → packages/core/dist}/bmad/story-exporter.d.ts.map +0 -0
  789. /package/{dist → packages/core/dist}/bmad/story-exporter.js +0 -0
  790. /package/{dist → packages/core/dist}/bmad/story-exporter.js.map +0 -0
  791. /package/{dist → packages/core/dist}/bmad/story-exporter.test.d.ts +0 -0
  792. /package/{dist → packages/core/dist}/bmad/story-exporter.test.d.ts.map +0 -0
  793. /package/{dist → packages/core/dist}/bmad/story-exporter.test.js +0 -0
  794. /package/{dist → packages/core/dist}/bmad/story-exporter.test.js.map +0 -0
  795. /package/{dist → packages/core/dist}/bmad/story-parser.d.ts +0 -0
  796. /package/{dist → packages/core/dist}/bmad/story-parser.d.ts.map +0 -0
  797. /package/{dist → packages/core/dist}/bmad/story-parser.js +0 -0
  798. /package/{dist → packages/core/dist}/bmad/story-parser.js.map +0 -0
  799. /package/{dist → packages/core/dist}/bmad/story-parser.test.d.ts +0 -0
  800. /package/{dist → packages/core/dist}/bmad/story-parser.test.d.ts.map +0 -0
  801. /package/{dist → packages/core/dist}/bmad/story-parser.test.js +0 -0
  802. /package/{dist → packages/core/dist}/bmad/story-parser.test.js.map +0 -0
  803. /package/{dist → packages/core/dist}/cli/commands/command.d.ts +0 -0
  804. /package/{dist → packages/core/dist}/cli/commands/command.d.ts.map +0 -0
  805. /package/{dist → packages/core/dist}/cli/commands/command.js +0 -0
  806. /package/{dist → packages/core/dist}/cli/commands/command.js.map +0 -0
  807. /package/{dist → packages/core/dist}/cli/commands/cyclist.d.ts +0 -0
  808. /package/{dist → packages/core/dist}/cli/commands/cyclist.d.ts.map +0 -0
  809. /package/{dist → packages/core/dist}/cli/commands/cyclist.js +0 -0
  810. /package/{dist → packages/core/dist}/cli/commands/cyclist.js.map +0 -0
  811. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.d.ts +0 -0
  812. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.d.ts.map +0 -0
  813. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.js +0 -0
  814. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.js.map +0 -0
  815. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.d.ts +0 -0
  816. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.d.ts.map +0 -0
  817. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.js +0 -0
  818. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.js.map +0 -0
  819. /package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.d.ts +0 -0
  820. /package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.d.ts.map +0 -0
  821. /package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.d.ts +0 -0
  822. /package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.d.ts.map +0 -0
  823. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.d.ts +0 -0
  824. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.d.ts.map +0 -0
  825. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.js +0 -0
  826. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.js.map +0 -0
  827. /package/{dist → packages/core/dist}/cli/commands/init.d.ts +0 -0
  828. /package/{dist → packages/core/dist}/cli/commands/init.d.ts.map +0 -0
  829. /package/{dist → packages/core/dist}/cli/commands/init.js +0 -0
  830. /package/{dist → packages/core/dist}/cli/commands/init.js.map +0 -0
  831. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.d.ts +0 -0
  832. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.d.ts.map +0 -0
  833. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.js +0 -0
  834. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.js.map +0 -0
  835. /package/{dist → packages/core/dist}/cli/commands/skill.d.ts +0 -0
  836. /package/{dist → packages/core/dist}/cli/commands/skill.d.ts.map +0 -0
  837. /package/{dist → packages/core/dist}/cli/commands/skill.js +0 -0
  838. /package/{dist → packages/core/dist}/cli/commands/skill.js.map +0 -0
  839. /package/{dist → packages/core/dist}/cli/commands/theme.d.ts +0 -0
  840. /package/{dist → packages/core/dist}/cli/commands/theme.d.ts.map +0 -0
  841. /package/{dist → packages/core/dist}/cli/commands/theme.js +0 -0
  842. /package/{dist → packages/core/dist}/cli/commands/theme.js.map +0 -0
  843. /package/{dist → packages/core/dist}/cli/commands/uninstall.d.ts +0 -0
  844. /package/{dist → packages/core/dist}/cli/commands/uninstall.d.ts.map +0 -0
  845. /package/{dist → packages/core/dist}/cli/commands/uninstall.js +0 -0
  846. /package/{dist → packages/core/dist}/cli/commands/uninstall.js.map +0 -0
  847. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.d.ts +0 -0
  848. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.d.ts.map +0 -0
  849. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.js +0 -0
  850. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.js.map +0 -0
  851. /package/{dist → packages/core/dist}/cli/commands/update.d.ts +0 -0
  852. /package/{dist → packages/core/dist}/cli/commands/version.d.ts +0 -0
  853. /package/{dist → packages/core/dist}/cli/commands/version.d.ts.map +0 -0
  854. /package/{dist → packages/core/dist}/cli/commands/version.js +0 -0
  855. /package/{dist → packages/core/dist}/cli/commands/version.js.map +0 -0
  856. /package/{dist → packages/core/dist}/cli/customization.test.d.ts +0 -0
  857. /package/{dist → packages/core/dist}/cli/customization.test.d.ts.map +0 -0
  858. /package/{dist → packages/core/dist}/cli/customization.test.js +0 -0
  859. /package/{dist → packages/core/dist}/cli/customization.test.js.map +0 -0
  860. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.d.ts +0 -0
  861. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.d.ts.map +0 -0
  862. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.js +0 -0
  863. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.js.map +0 -0
  864. /package/{dist → packages/core/dist}/cli/index.d.ts +0 -0
  865. /package/{dist → packages/core/dist}/cli/index.d.ts.map +0 -0
  866. /package/{dist → packages/core/dist}/cli/index.js +0 -0
  867. /package/{dist → packages/core/dist}/cli/index.js.map +0 -0
  868. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.d.ts +0 -0
  869. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.d.ts.map +0 -0
  870. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.js +0 -0
  871. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.js.map +0 -0
  872. /package/{dist → packages/core/dist}/cli/theme-maker.test.d.ts +0 -0
  873. /package/{dist → packages/core/dist}/cli/theme-maker.test.d.ts.map +0 -0
  874. /package/{dist → packages/core/dist}/cli/theme-maker.test.js +0 -0
  875. /package/{dist → packages/core/dist}/cli/theme-maker.test.js.map +0 -0
  876. /package/{dist → packages/core/dist}/cli/utils/constants.d.ts +0 -0
  877. /package/{dist → packages/core/dist}/cli/utils/constants.d.ts.map +0 -0
  878. /package/{dist → packages/core/dist}/cli/utils/constants.js +0 -0
  879. /package/{dist → packages/core/dist}/cli/utils/constants.js.map +0 -0
  880. /package/{dist → packages/core/dist}/cli/utils/files.d.ts +0 -0
  881. /package/{dist → packages/core/dist}/cli/utils/files.d.ts.map +0 -0
  882. /package/{dist → packages/core/dist}/cli/utils/files.js +0 -0
  883. /package/{dist → packages/core/dist}/cli/utils/files.js.map +0 -0
  884. /package/{dist → packages/core/dist}/cli/utils/logger.d.ts +0 -0
  885. /package/{dist → packages/core/dist}/cli/utils/logger.d.ts.map +0 -0
  886. /package/{dist → packages/core/dist}/cli/utils/logger.js +0 -0
  887. /package/{dist → packages/core/dist}/cli/utils/logger.js.map +0 -0
  888. /package/{dist → packages/core/dist}/cli/utils/manifest.d.ts +0 -0
  889. /package/{dist → packages/core/dist}/cli/utils/manifest.d.ts.map +0 -0
  890. /package/{dist → packages/core/dist}/cli/utils/manifest.js +0 -0
  891. /package/{dist → packages/core/dist}/cli/utils/manifest.js.map +0 -0
  892. /package/{dist → packages/core/dist}/cli/utils/node-modules.d.ts +0 -0
  893. /package/{dist → packages/core/dist}/cli/utils/node-modules.d.ts.map +0 -0
  894. /package/{dist → packages/core/dist}/cli/utils/node-modules.js +0 -0
  895. /package/{dist → packages/core/dist}/cli/utils/node-modules.js.map +0 -0
  896. /package/{dist → packages/core/dist}/cli/utils/prompts.d.ts +0 -0
  897. /package/{dist → packages/core/dist}/cli/utils/prompts.d.ts.map +0 -0
  898. /package/{dist → packages/core/dist}/cli/utils/prompts.js +0 -0
  899. /package/{dist → packages/core/dist}/cli/utils/prompts.js.map +0 -0
  900. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.d.ts +0 -0
  901. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.d.ts.map +0 -0
  902. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.js +0 -0
  903. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.js.map +0 -0
  904. /package/{dist → packages/core/dist}/cli/utils/settings.d.ts +0 -0
  905. /package/{dist → packages/core/dist}/cli/utils/symlinks.d.ts +0 -0
  906. /package/{dist → packages/core/dist}/cli/utils/symlinks.d.ts.map +0 -0
  907. /package/{dist → packages/core/dist}/cli/utils/symlinks.js +0 -0
  908. /package/{dist → packages/core/dist}/cli/utils/symlinks.js.map +0 -0
  909. /package/{dist → packages/core/dist}/cli/utils/themes.js +0 -0
  910. /package/{dist → packages/core/dist}/cli/utils/themes.test.d.ts +0 -0
  911. /package/{dist → packages/core/dist}/cli/utils/themes.test.d.ts.map +0 -0
  912. /package/{dist → packages/core/dist}/cli/utils/themes.test.js +0 -0
  913. /package/{dist → packages/core/dist}/cli/utils/themes.test.js.map +0 -0
  914. /package/{dist → packages/core/dist}/cli/utils/version.d.ts +0 -0
  915. /package/{dist → packages/core/dist}/cli/utils/version.d.ts.map +0 -0
  916. /package/{dist → packages/core/dist}/cli/utils/version.js +0 -0
  917. /package/{dist → packages/core/dist}/cli/utils/version.js.map +0 -0
  918. /package/{dist → packages/core/dist}/cli/workspace.test.d.ts +0 -0
  919. /package/{dist → packages/core/dist}/cli/workspace.test.d.ts.map +0 -0
  920. /package/{dist → packages/core/dist}/cli/workspace.test.js +0 -0
  921. /package/{dist → packages/core/dist}/cli/workspace.test.js.map +0 -0
  922. /package/{dist → packages/core/dist}/index.d.ts +0 -0
  923. /package/{dist → packages/core/dist}/index.d.ts.map +0 -0
  924. /package/{dist → packages/core/dist}/index.js +0 -0
  925. /package/{dist → packages/core/dist}/index.js.map +0 -0
  926. /package/{dist → packages/core/dist}/jira/jira-epic-creation.d.ts +0 -0
  927. /package/{dist → packages/core/dist}/jira/jira-epic-creation.d.ts.map +0 -0
  928. /package/{dist → packages/core/dist}/jira/jira-epic-creation.js +0 -0
  929. /package/{dist → packages/core/dist}/jira/jira-epic-creation.js.map +0 -0
  930. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.d.ts +0 -0
  931. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.d.ts.map +0 -0
  932. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.js +0 -0
  933. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.js.map +0 -0
  934. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.d.ts +0 -0
  935. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.d.ts.map +0 -0
  936. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.js +0 -0
  937. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.js.map +0 -0
  938. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.d.ts +0 -0
  939. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.d.ts.map +0 -0
  940. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.js +0 -0
  941. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.js.map +0 -0
  942. /package/{dist → packages/core/dist}/permissions/index.d.ts +0 -0
  943. /package/{dist → packages/core/dist}/permissions/index.d.ts.map +0 -0
  944. /package/{dist → packages/core/dist}/permissions/index.js +0 -0
  945. /package/{dist → packages/core/dist}/permissions/index.js.map +0 -0
  946. /package/{dist → packages/core/dist}/permissions/permission-schema.d.ts +0 -0
  947. /package/{dist → packages/core/dist}/permissions/permission-schema.d.ts.map +0 -0
  948. /package/{dist → packages/core/dist}/permissions/permission-schema.js +0 -0
  949. /package/{dist → packages/core/dist}/permissions/permission-schema.js.map +0 -0
  950. /package/{dist → packages/core/dist}/permissions/permission-schema.test.d.ts +0 -0
  951. /package/{dist → packages/core/dist}/permissions/permission-schema.test.d.ts.map +0 -0
  952. /package/{dist → packages/core/dist}/permissions/permission-schema.test.js +0 -0
  953. /package/{dist → packages/core/dist}/permissions/permission-schema.test.js.map +0 -0
  954. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.d.ts +0 -0
  955. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.d.ts.map +0 -0
  956. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.js +0 -0
  957. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.js.map +0 -0
  958. /package/{dist → packages/core/dist}/scripts/benchmark-integration.d.ts +0 -0
  959. /package/{dist → packages/core/dist}/scripts/benchmark-integration.d.ts.map +0 -0
  960. /package/{dist → packages/core/dist}/scripts/benchmark-integration.js +0 -0
  961. /package/{dist → packages/core/dist}/scripts/benchmark-integration.js.map +0 -0
  962. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.d.ts +0 -0
  963. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.d.ts.map +0 -0
  964. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.js +0 -0
  965. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.js.map +0 -0
  966. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.d.ts +0 -0
  967. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.d.ts.map +0 -0
  968. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.js +0 -0
  969. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.js.map +0 -0
  970. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.d.ts +0 -0
  971. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.d.ts.map +0 -0
  972. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.js +0 -0
  973. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.js.map +0 -0
  974. /package/{dist → packages/core/dist}/scripts/generate-report.d.ts +0 -0
  975. /package/{dist → packages/core/dist}/scripts/generate-report.d.ts.map +0 -0
  976. /package/{dist → packages/core/dist}/scripts/generate-report.js +0 -0
  977. /package/{dist → packages/core/dist}/scripts/generate-report.js.map +0 -0
  978. /package/{dist → packages/core/dist}/scripts/generate-report.test.d.ts +0 -0
  979. /package/{dist → packages/core/dist}/scripts/generate-report.test.d.ts.map +0 -0
  980. /package/{dist → packages/core/dist}/scripts/generate-report.test.js +0 -0
  981. /package/{dist → packages/core/dist}/scripts/generate-report.test.js.map +0 -0
  982. /package/{dist → packages/core/dist}/scripts/generate-spider-report.d.ts +0 -0
  983. /package/{dist → packages/core/dist}/scripts/generate-spider-report.d.ts.map +0 -0
  984. /package/{dist → packages/core/dist}/scripts/generate-spider-report.js +0 -0
  985. /package/{dist → packages/core/dist}/scripts/generate-spider-report.js.map +0 -0
  986. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.d.ts +0 -0
  987. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.d.ts.map +0 -0
  988. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.js +0 -0
  989. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.js.map +0 -0
  990. /package/{dist → packages/core/dist}/scripts/generate-spider.d.ts +0 -0
  991. /package/{dist → packages/core/dist}/scripts/generate-spider.d.ts.map +0 -0
  992. /package/{dist → packages/core/dist}/scripts/generate-spider.js +0 -0
  993. /package/{dist → packages/core/dist}/scripts/generate-spider.js.map +0 -0
  994. /package/{dist → packages/core/dist}/scripts/generate-spider.test.d.ts +0 -0
  995. /package/{dist → packages/core/dist}/scripts/generate-spider.test.d.ts.map +0 -0
  996. /package/{dist → packages/core/dist}/scripts/generate-spider.test.js +0 -0
  997. /package/{dist → packages/core/dist}/scripts/generate-spider.test.js.map +0 -0
  998. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.d.ts +0 -0
  999. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.d.ts.map +0 -0
  1000. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.js +0 -0
  1001. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.js.map +0 -0
  1002. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.d.ts +0 -0
  1003. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.d.ts.map +0 -0
  1004. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.js +0 -0
  1005. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.js.map +0 -0
  1006. /package/{dist → packages/core/dist}/scripts/run-ci.test.d.ts +0 -0
  1007. /package/{dist → packages/core/dist}/scripts/run-ci.test.d.ts.map +0 -0
  1008. /package/{dist → packages/core/dist}/scripts/run-ci.test.js +0 -0
  1009. /package/{dist → packages/core/dist}/scripts/run-ci.test.js.map +0 -0
  1010. /package/{dist → packages/core/dist}/scripts/theme-detail.test.d.ts +0 -0
  1011. /package/{dist → packages/core/dist}/scripts/theme-detail.test.d.ts.map +0 -0
  1012. /package/{dist → packages/core/dist}/scripts/theme-detail.test.js +0 -0
  1013. /package/{dist → packages/core/dist}/scripts/theme-detail.test.js.map +0 -0
  1014. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.d.ts +0 -0
  1015. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.d.ts.map +0 -0
  1016. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.js +0 -0
  1017. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.js.map +0 -0
  1018. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.d.ts +0 -0
  1019. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.d.ts.map +0 -0
  1020. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.js +0 -0
  1021. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.js.map +0 -0
  1022. /package/{dist → packages/core/dist}/workflow/gate-handler.d.ts +0 -0
  1023. /package/{dist → packages/core/dist}/workflow/gate-handler.d.ts.map +0 -0
  1024. /package/{dist → packages/core/dist}/workflow/gate-handler.js +0 -0
  1025. /package/{dist → packages/core/dist}/workflow/gate-handler.js.map +0 -0
  1026. /package/{dist → packages/core/dist}/workflow/gate-handler.test.d.ts +0 -0
  1027. /package/{dist → packages/core/dist}/workflow/gate-handler.test.d.ts.map +0 -0
  1028. /package/{dist → packages/core/dist}/workflow/gate-handler.test.js +0 -0
  1029. /package/{dist → packages/core/dist}/workflow/gate-handler.test.js.map +0 -0
  1030. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.d.ts +0 -0
  1031. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.d.ts.map +0 -0
  1032. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.js +0 -0
  1033. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.js.map +0 -0
  1034. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.d.ts +0 -0
  1035. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.d.ts.map +0 -0
  1036. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.js +0 -0
  1037. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.js.map +0 -0
  1038. /package/{dist → packages/core/dist}/workflow/handoff.d.ts +0 -0
  1039. /package/{dist → packages/core/dist}/workflow/handoff.d.ts.map +0 -0
  1040. /package/{dist → packages/core/dist}/workflow/handoff.js +0 -0
  1041. /package/{dist → packages/core/dist}/workflow/handoff.js.map +0 -0
  1042. /package/{dist → packages/core/dist}/workflow/handoff.test.d.ts +0 -0
  1043. /package/{dist → packages/core/dist}/workflow/handoff.test.d.ts.map +0 -0
  1044. /package/{dist → packages/core/dist}/workflow/handoff.test.js +0 -0
  1045. /package/{dist → packages/core/dist}/workflow/handoff.test.js.map +0 -0
  1046. /package/{dist → packages/core/dist}/workflow/index.d.ts +0 -0
  1047. /package/{dist → packages/core/dist}/workflow/index.d.ts.map +0 -0
  1048. /package/{dist → packages/core/dist}/workflow/index.js +0 -0
  1049. /package/{dist → packages/core/dist}/workflow/index.js.map +0 -0
  1050. /package/{dist → packages/core/dist}/workflow/session-state.d.ts +0 -0
  1051. /package/{dist → packages/core/dist}/workflow/session-state.d.ts.map +0 -0
  1052. /package/{dist → packages/core/dist}/workflow/session-state.js +0 -0
  1053. /package/{dist → packages/core/dist}/workflow/session-state.js.map +0 -0
  1054. /package/{dist → packages/core/dist}/workflow/session-state.test.d.ts +0 -0
  1055. /package/{dist → packages/core/dist}/workflow/session-state.test.d.ts.map +0 -0
  1056. /package/{dist → packages/core/dist}/workflow/session-state.test.js +0 -0
  1057. /package/{dist → packages/core/dist}/workflow/session-state.test.js.map +0 -0
  1058. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.d.ts +0 -0
  1059. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.d.ts.map +0 -0
  1060. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.js +0 -0
  1061. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.js.map +0 -0
  1062. /package/{dist → packages/core/dist}/workflow/step-parser.d.ts +0 -0
  1063. /package/{dist → packages/core/dist}/workflow/step-parser.d.ts.map +0 -0
  1064. /package/{dist → packages/core/dist}/workflow/step-parser.js +0 -0
  1065. /package/{dist → packages/core/dist}/workflow/step-parser.js.map +0 -0
  1066. /package/{dist → packages/core/dist}/workflow/step-parser.test.d.ts +0 -0
  1067. /package/{dist → packages/core/dist}/workflow/step-parser.test.d.ts.map +0 -0
  1068. /package/{dist → packages/core/dist}/workflow/step-parser.test.js +0 -0
  1069. /package/{dist → packages/core/dist}/workflow/step-parser.test.js.map +0 -0
  1070. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.d.ts +0 -0
  1071. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.d.ts.map +0 -0
  1072. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.js +0 -0
  1073. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.js.map +0 -0
  1074. /package/{dist → packages/core/dist}/workflow/test-cache.d.ts +0 -0
  1075. /package/{dist → packages/core/dist}/workflow/test-cache.d.ts.map +0 -0
  1076. /package/{dist → packages/core/dist}/workflow/test-cache.js +0 -0
  1077. /package/{dist → packages/core/dist}/workflow/test-cache.js.map +0 -0
  1078. /package/{dist → packages/core/dist}/workflow/test-cache.test.d.ts +0 -0
  1079. /package/{dist → packages/core/dist}/workflow/test-cache.test.d.ts.map +0 -0
  1080. /package/{dist → packages/core/dist}/workflow/test-cache.test.js +0 -0
  1081. /package/{dist → packages/core/dist}/workflow/test-cache.test.js.map +0 -0
  1082. /package/{dist → packages/core/dist}/workflow/trimodal.d.ts +0 -0
  1083. /package/{dist → packages/core/dist}/workflow/trimodal.d.ts.map +0 -0
  1084. /package/{dist → packages/core/dist}/workflow/trimodal.js +0 -0
  1085. /package/{dist → packages/core/dist}/workflow/trimodal.js.map +0 -0
  1086. /package/{dist → packages/core/dist}/workflow/trimodal.test.d.ts +0 -0
  1087. /package/{dist → packages/core/dist}/workflow/trimodal.test.d.ts.map +0 -0
  1088. /package/{dist → packages/core/dist}/workflow/trimodal.test.js +0 -0
  1089. /package/{dist → packages/core/dist}/workflow/trimodal.test.js.map +0 -0
  1090. /package/{dist → packages/core/dist}/workflow/variable-resolver.d.ts +0 -0
  1091. /package/{dist → packages/core/dist}/workflow/variable-resolver.d.ts.map +0 -0
  1092. /package/{dist → packages/core/dist}/workflow/variable-resolver.js +0 -0
  1093. /package/{dist → packages/core/dist}/workflow/variable-resolver.js.map +0 -0
  1094. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.d.ts +0 -0
  1095. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.d.ts.map +0 -0
  1096. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.js +0 -0
  1097. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.js.map +0 -0
  1098. /package/{dist → packages/core/dist}/workflow/workflow-executor.d.ts +0 -0
  1099. /package/{dist → packages/core/dist}/workflow/workflow-executor.d.ts.map +0 -0
  1100. /package/{dist → packages/core/dist}/workflow/workflow-executor.js +0 -0
  1101. /package/{dist → packages/core/dist}/workflow/workflow-executor.js.map +0 -0
  1102. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.d.ts +0 -0
  1103. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.d.ts.map +0 -0
  1104. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.js +0 -0
  1105. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.js.map +0 -0
  1106. /package/{dist → packages/core/dist}/workflow/workflow-loader.d.ts +0 -0
  1107. /package/{dist → packages/core/dist}/workflow/workflow-loader.d.ts.map +0 -0
  1108. /package/{dist → packages/core/dist}/workflow/workflow-loader.js +0 -0
  1109. /package/{dist → packages/core/dist}/workflow/workflow-loader.js.map +0 -0
  1110. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.d.ts +0 -0
  1111. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.d.ts.map +0 -0
  1112. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.js +0 -0
  1113. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.js.map +0 -0
  1114. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.d.ts +0 -0
  1115. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.d.ts.map +0 -0
  1116. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.js +0 -0
  1117. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.js.map +0 -0
  1118. /package/{dist → packages/core/dist}/workflow/workflow-permissions.d.ts +0 -0
  1119. /package/{dist → packages/core/dist}/workflow/workflow-permissions.d.ts.map +0 -0
  1120. /package/{dist → packages/core/dist}/workflow/workflow-permissions.js +0 -0
  1121. /package/{dist → packages/core/dist}/workflow/workflow-permissions.js.map +0 -0
  1122. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.d.ts +0 -0
  1123. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.d.ts.map +0 -0
  1124. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.js +0 -0
  1125. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.js.map +0 -0
  1126. /package/{dist → packages/core/dist}/workflow/workflow-router.d.ts +0 -0
  1127. /package/{dist → packages/core/dist}/workflow/workflow-router.d.ts.map +0 -0
  1128. /package/{dist → packages/core/dist}/workflow/workflow-router.js +0 -0
  1129. /package/{dist → packages/core/dist}/workflow/workflow-router.js.map +0 -0
  1130. /package/{dist → packages/core/dist}/workflow/workflow-router.test.d.ts +0 -0
  1131. /package/{dist → packages/core/dist}/workflow/workflow-router.test.d.ts.map +0 -0
  1132. /package/{dist → packages/core/dist}/workflow/workflow-router.test.js +0 -0
  1133. /package/{dist → packages/core/dist}/workflow/workflow-router.test.js.map +0 -0
  1134. /package/{dist → packages/core/dist}/workflow/workflow-schema.d.ts +0 -0
  1135. /package/{dist → packages/core/dist}/workflow/workflow-schema.d.ts.map +0 -0
  1136. /package/{dist → packages/core/dist}/workflow/workflow-schema.js +0 -0
  1137. /package/{dist → packages/core/dist}/workflow/workflow-schema.js.map +0 -0
  1138. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.d.ts +0 -0
  1139. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.d.ts.map +0 -0
  1140. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.js +0 -0
  1141. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.js.map +0 -0
  1142. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.d.ts +0 -0
  1143. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.d.ts.map +0 -0
  1144. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.js +0 -0
  1145. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.js.map +0 -0
@@ -0,0 +1,1650 @@
1
+ import { existsSync, readFileSync, readdirSync, writeFileSync, chmodSync, statSync, readlinkSync, symlinkSync, unlinkSync, mkdirSync, renameSync } from 'fs';
2
+ import { join, relative, dirname } from 'path';
3
+ import YAML from 'yaml';
4
+ import { spawnSync } from 'child_process';
5
+ import fsExtra from 'fs-extra';
6
+ const { removeSync, ensureDirSync } = fsExtra;
7
+ import { logger } from '../utils/logger.js';
8
+ import { readManifest } from '../utils/manifest.js';
9
+ import { pathExists, isDirectory, isSymlink, fileMatchesHash } from '../utils/files.js';
10
+ import { getPackageVersion } from '../utils/version.js';
11
+ import { findNodeModulesPath } from '../utils/node-modules.js';
12
+ import { ALL_SYMLINKS, CORE_AGENTS } from '../utils/constants.js';
13
+ export async function doctorCommand(options) {
14
+ const projectRoot = process.cwd();
15
+ // Handle dogfooding mode - run the dogfood script instead
16
+ if (options.dogfood) {
17
+ const dogfoodScript = join(projectRoot, 'pennyfarthing-dist/scripts/misc/doctor-dogfood.sh');
18
+ if (!existsSync(dogfoodScript)) {
19
+ logger.error('Dogfood mode requires the pennyfarthing repo (pennyfarthing-dist/ not found)');
20
+ logger.info('This flag is for developers working on pennyfarthing itself.');
21
+ process.exit(1);
22
+ }
23
+ const args = options.fix ? ['--fix'] : [];
24
+ const result = spawnSync(dogfoodScript, args, {
25
+ stdio: 'inherit',
26
+ cwd: projectRoot,
27
+ });
28
+ process.exit(result.status ?? 0);
29
+ }
30
+ const results = [];
31
+ if (options.quiet) {
32
+ logger.configure({ quiet: true });
33
+ }
34
+ logger.header('Pennyfarthing Health Check');
35
+ logger.info(`Project: ${projectRoot}`);
36
+ // Get versions
37
+ const packageVersion = getPackageVersion();
38
+ const manifest = readManifest(projectRoot);
39
+ const installedVersion = manifest?.version || 'not installed';
40
+ const installationType = manifest?.installationType || 'copy';
41
+ logger.info(`Version: ${installedVersion} (installed) / ${packageVersion} (package)`);
42
+ logger.info(`Mode: ${installationType}${installationType === 'symlink' ? ' (node_modules)' : ' (file copies)'}`);
43
+ logger.newline();
44
+ // Run checks
45
+ results.push(...checkInstallation(projectRoot, manifest));
46
+ results.push(...checkCoreFiles(projectRoot, manifest));
47
+ results.push(...checkUserFiles(projectRoot));
48
+ results.push(...checkDirectories(projectRoot));
49
+ results.push(...checkHooks(projectRoot));
50
+ results.push(...checkFileLayout(projectRoot));
51
+ results.push(...checkLegacyFiles(projectRoot));
52
+ results.push(checkLegacyStatuslinePath(projectRoot));
53
+ results.push(...checkCyclist(projectRoot));
54
+ // Output results
55
+ if (options.json) {
56
+ console.log(JSON.stringify(results, null, 2));
57
+ return;
58
+ }
59
+ // Display results by category
60
+ const categories = [
61
+ { name: 'Installation', filter: (r) => r.name.startsWith('manifest') },
62
+ { name: 'Core Files', filter: (r) => r.name.startsWith('core/') },
63
+ { name: 'User Files', filter: (r) => r.name.startsWith('project/') || r.name.startsWith('persona') || r.name.startsWith('settings') },
64
+ { name: 'Directories', filter: (r) => r.name.startsWith('dir/') },
65
+ { name: 'Hooks', filter: (r) => r.name.startsWith('hook/') },
66
+ { name: 'File Layout', filter: (r) => r.name.startsWith('layout/') },
67
+ { name: 'Legacy Files', filter: (r) => r.name.startsWith('legacy/') },
68
+ { name: 'Cyclist', filter: (r) => r.name.startsWith('cyclist/') }
69
+ ];
70
+ for (const category of categories) {
71
+ const categoryResults = results.filter(category.filter);
72
+ if (categoryResults.length === 0)
73
+ continue;
74
+ logger.header(category.name);
75
+ for (const result of categoryResults) {
76
+ logger.check(result.name.split('/').pop() || result.name, result.status, result.detail);
77
+ }
78
+ }
79
+ // Summary
80
+ const failCount = results.filter(r => r.status === 'fail').length;
81
+ const warnCount = results.filter(r => r.status === 'warn').length;
82
+ logger.newline();
83
+ if (failCount === 0 && warnCount === 0) {
84
+ logger.success('All checks passed!');
85
+ }
86
+ else {
87
+ const status = failCount > 0 ? 'NEEDS_FIX' : 'NEEDS_ATTENTION';
88
+ logger.warning(`${status}: ${failCount} errors, ${warnCount} warnings`);
89
+ }
90
+ // Apply fixes if requested
91
+ if (options.fix) {
92
+ const fixable = results.filter(r => r.fix && r.status !== 'pass');
93
+ if (fixable.length > 0) {
94
+ logger.newline();
95
+ logger.header('Applying fixes...');
96
+ for (const result of fixable) {
97
+ try {
98
+ result.fix();
99
+ logger.success(`Fixed: ${result.name}`);
100
+ }
101
+ catch (error) {
102
+ logger.error(`Failed to fix ${result.name}: ${error}`);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ else if (results.some(r => r.fix && r.status !== 'pass')) {
108
+ logger.newline();
109
+ logger.info('Run with --fix to auto-repair issues');
110
+ }
111
+ // Exit with error if failures
112
+ if (failCount > 0) {
113
+ process.exit(1);
114
+ }
115
+ }
116
+ function checkInstallation(projectRoot, manifest) {
117
+ const results = [];
118
+ // Check manifest exists
119
+ results.push({
120
+ name: 'manifest/exists',
121
+ status: manifest ? 'pass' : 'fail',
122
+ detail: manifest ? `v${manifest.version}` : 'Run `pennyfarthing init`'
123
+ });
124
+ return results;
125
+ }
126
+ function checkCoreFiles(projectRoot, manifest) {
127
+ const results = [];
128
+ const installationType = manifest?.installationType || 'copy';
129
+ const nodeModulesPath = findNodeModulesPath(projectRoot);
130
+ if (installationType === 'symlink') {
131
+ // Symlink mode: check that symlinks exist and point to valid targets
132
+ results.push(...checkSymlinks(projectRoot, nodeModulesPath));
133
+ }
134
+ else {
135
+ // Copy mode: check that directories exist
136
+ const coreDirs = [
137
+ { path: '.claude/pennyfarthing/agents', name: 'core/agents' },
138
+ { path: '.claude/pennyfarthing/commands', name: 'core/commands' },
139
+ { path: '.claude/pennyfarthing/guides', name: 'core/guides' },
140
+ { path: '.claude/pennyfarthing/skills', name: 'core/skills' },
141
+ { path: '.claude/pennyfarthing/personas', name: 'core/personas' },
142
+ { path: '.claude/pennyfarthing/scripts', name: 'core/scripts' }
143
+ ];
144
+ for (const { path, name } of coreDirs) {
145
+ const fullPath = join(projectRoot, path);
146
+ const exists = pathExists(fullPath) && isDirectory(fullPath);
147
+ results.push({
148
+ name: name,
149
+ status: exists ? 'pass' : 'fail',
150
+ detail: exists ? undefined : 'Missing directory'
151
+ });
152
+ }
153
+ // Check file integrity if manifest has hashes
154
+ if (manifest?.fileHashes && Object.keys(manifest.fileHashes).length > 0) {
155
+ let modifiedCount = 0;
156
+ let missingCount = 0;
157
+ for (const [filePath, expectedHash] of Object.entries(manifest.fileHashes)) {
158
+ const fullPath = join(projectRoot, filePath);
159
+ if (!pathExists(fullPath)) {
160
+ missingCount++;
161
+ }
162
+ else if (!fileMatchesHash(fullPath, expectedHash)) {
163
+ modifiedCount++;
164
+ }
165
+ }
166
+ if (modifiedCount > 0) {
167
+ results.push({
168
+ name: 'core/integrity',
169
+ status: 'warn',
170
+ detail: `${modifiedCount} file(s) modified locally`
171
+ });
172
+ }
173
+ if (missingCount > 0) {
174
+ results.push({
175
+ name: 'core/completeness',
176
+ status: 'fail',
177
+ detail: `${missingCount} file(s) missing`
178
+ });
179
+ }
180
+ }
181
+ }
182
+ return results;
183
+ }
184
+ /**
185
+ * Check symlinks for symlink installation mode
186
+ */
187
+ function checkSymlinks(projectRoot, nodeModulesPath) {
188
+ const results = [];
189
+ // Check if node_modules is available
190
+ if (!nodeModulesPath) {
191
+ results.push({
192
+ name: 'core/node_modules',
193
+ status: 'fail',
194
+ detail: 'pennyfarthing not found in node_modules - run npm install'
195
+ });
196
+ return results;
197
+ }
198
+ results.push({
199
+ name: 'core/node_modules',
200
+ status: 'pass',
201
+ detail: relative(projectRoot, nodeModulesPath)
202
+ });
203
+ for (const { name, link } of ALL_SYMLINKS) {
204
+ const linkPath = join(projectRoot, link);
205
+ const targetPath = join(nodeModulesPath, name);
206
+ const expectedRelative = relative(dirname(linkPath), targetPath);
207
+ if (!isSymlink(linkPath)) {
208
+ // Not a symlink
209
+ if (pathExists(linkPath)) {
210
+ // It's a directory (copy mode remnant)
211
+ results.push({
212
+ name: `symlink/${name}`,
213
+ status: 'warn',
214
+ detail: 'Directory instead of symlink - run update to migrate',
215
+ fix: () => {
216
+ removeSync(linkPath);
217
+ symlinkSync(expectedRelative, linkPath);
218
+ }
219
+ });
220
+ }
221
+ else {
222
+ // Missing entirely
223
+ results.push({
224
+ name: `symlink/${name}`,
225
+ status: 'fail',
226
+ detail: 'Missing symlink',
227
+ fix: () => {
228
+ symlinkSync(expectedRelative, linkPath);
229
+ }
230
+ });
231
+ }
232
+ continue;
233
+ }
234
+ // It's a symlink - check if it resolves
235
+ try {
236
+ const resolved = readlinkSync(linkPath);
237
+ // Verify the target exists
238
+ if (pathExists(linkPath)) {
239
+ results.push({
240
+ name: `symlink/${name}`,
241
+ status: 'pass',
242
+ detail: resolved
243
+ });
244
+ }
245
+ else {
246
+ results.push({
247
+ name: `symlink/${name}`,
248
+ status: 'fail',
249
+ detail: 'Broken symlink - run npm install',
250
+ fix: () => {
251
+ unlinkSync(linkPath);
252
+ symlinkSync(expectedRelative, linkPath);
253
+ }
254
+ });
255
+ }
256
+ }
257
+ catch {
258
+ results.push({
259
+ name: `symlink/${name}`,
260
+ status: 'fail',
261
+ detail: 'Cannot read symlink'
262
+ });
263
+ }
264
+ }
265
+ return results;
266
+ }
267
+ function checkUserFiles(projectRoot) {
268
+ const results = [];
269
+ // Detect installation type from manifest
270
+ const manifest = readManifest(projectRoot);
271
+ const installationType = manifest?.installationType || 'copy';
272
+ // Check project directory
273
+ const projectDir = join(projectRoot, '.claude/project');
274
+ results.push({
275
+ name: 'project/directory',
276
+ status: pathExists(projectDir) ? 'pass' : 'warn',
277
+ detail: pathExists(projectDir) ? undefined : 'Run init to create'
278
+ });
279
+ // Check agent sidecars (now in .pennyfarthing/sidecars/)
280
+ const sidecarsDir = join(projectRoot, '.pennyfarthing/sidecars');
281
+ if (pathExists(sidecarsDir)) {
282
+ const existingSidecars = CORE_AGENTS.filter(a => pathExists(join(sidecarsDir, a)));
283
+ results.push({
284
+ name: 'project/sidecars',
285
+ status: existingSidecars.length > 0 ? 'pass' : 'warn',
286
+ detail: `${existingSidecars.length} agent sidecars configured`
287
+ });
288
+ }
289
+ // Check persona config at canonical location
290
+ const personaConfig = join(projectRoot, '.pennyfarthing/config.local.yaml');
291
+ results.push({
292
+ name: 'persona-config',
293
+ status: pathExists(personaConfig) ? 'pass' : 'warn',
294
+ detail: pathExists(personaConfig) ? undefined : 'No theme configured'
295
+ });
296
+ // Check settings.local.json exists (CRITICAL - registers hooks with Claude Code)
297
+ const settingsLocal = join(projectRoot, '.claude/settings.local.json');
298
+ if (!pathExists(settingsLocal)) {
299
+ results.push({
300
+ name: 'settings.local.json',
301
+ status: 'fail',
302
+ detail: 'Missing - hooks not registered with Claude Code!',
303
+ fix: () => {
304
+ createSettingsLocalJson(projectRoot, installationType);
305
+ }
306
+ });
307
+ }
308
+ else {
309
+ results.push({
310
+ name: 'settings.local.json',
311
+ status: 'pass',
312
+ detail: undefined
313
+ });
314
+ // Check SessionStart hooks are configured (critical for PROJECT_ROOT)
315
+ const hookCheck = checkSessionStartHooks(projectRoot, installationType);
316
+ results.push(hookCheck);
317
+ // Check Stop hook is configured (question reflector enforcement)
318
+ const stopHookCheck = checkStopHook(projectRoot, installationType);
319
+ results.push(stopHookCheck);
320
+ // Check PostToolUse hook is configured (bell mode - MSSCI-12275)
321
+ const postToolUseHookCheck = checkPostToolUseHook(projectRoot, installationType);
322
+ results.push(postToolUseHookCheck);
323
+ // Check benchmark permissions (needed for /benchmark, /solo subagents)
324
+ const benchmarkCheck = checkBenchmarkPermissions(projectRoot);
325
+ results.push(benchmarkCheck);
326
+ // Check PreToolUse hooks for context-circuit-breaker
327
+ const circuitBreakerCheck = checkContextCircuitBreaker(projectRoot, installationType);
328
+ results.push(circuitBreakerCheck);
329
+ // Check PreToolUse hooks for schema-validation
330
+ const schemaValidationCheck = checkSchemaValidationHook(projectRoot, installationType);
331
+ results.push(schemaValidationCheck);
332
+ // Check PostToolUse hooks for sprint-yaml-validation
333
+ const sprintYamlValidationCheck = checkSprintYamlValidationHook(projectRoot, installationType);
334
+ results.push(sprintYamlValidationCheck);
335
+ }
336
+ return results;
337
+ }
338
+ /**
339
+ * Check that benchmark-required permissions are configured in settings.local.json
340
+ * Subagents need explicit Bash(claude:*) permission since they run non-interactively
341
+ */
342
+ function checkBenchmarkPermissions(projectRoot) {
343
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
344
+ try {
345
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
346
+ const permissions = settings.permissions?.allow || [];
347
+ // Check if Bash(claude:*) specifically exists (needed for subagents)
348
+ const hasExplicitClaudeBash = permissions.includes('Bash(claude:*)');
349
+ if (!hasExplicitClaudeBash) {
350
+ return {
351
+ name: 'settings/benchmark-permissions',
352
+ status: 'warn',
353
+ detail: 'Missing Bash(claude:*) for parallel benchmarks (sequential runs unaffected)',
354
+ fix: () => {
355
+ addBenchmarkPermissions(projectRoot);
356
+ }
357
+ };
358
+ }
359
+ return {
360
+ name: 'settings/benchmark-permissions',
361
+ status: 'pass',
362
+ detail: undefined
363
+ };
364
+ }
365
+ catch {
366
+ return {
367
+ name: 'settings/benchmark-permissions',
368
+ status: 'warn',
369
+ detail: 'Could not check benchmark permissions'
370
+ };
371
+ }
372
+ }
373
+ /**
374
+ * Fix function: Add benchmark permissions to settings.local.json
375
+ */
376
+ function addBenchmarkPermissions(projectRoot) {
377
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
378
+ const requiredPermissions = [
379
+ 'Bash(claude:*)',
380
+ 'Bash(date:*)',
381
+ 'Bash(mkdir:*)',
382
+ 'Edit(results/**)',
383
+ 'Write(results/**)',
384
+ 'Skill(solo)',
385
+ 'Skill(benchmark)',
386
+ 'Skill(benchmark-control)',
387
+ 'Skill(judge)',
388
+ 'Skill(finalize-run)'
389
+ ];
390
+ let settings = {};
391
+ if (pathExists(settingsPath)) {
392
+ try {
393
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
394
+ }
395
+ catch {
396
+ // Start fresh if parse fails
397
+ }
398
+ }
399
+ if (!settings.permissions) {
400
+ settings.permissions = { allow: [] };
401
+ }
402
+ const permissions = settings.permissions;
403
+ if (!Array.isArray(permissions.allow)) {
404
+ permissions.allow = [];
405
+ }
406
+ // Add missing permissions
407
+ for (const perm of requiredPermissions) {
408
+ if (!permissions.allow.includes(perm)) {
409
+ permissions.allow.push(perm);
410
+ }
411
+ }
412
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
413
+ }
414
+ /**
415
+ * Check that SessionStart hooks are properly configured in settings.local.json
416
+ * This is critical because session-start.sh exports PROJECT_ROOT
417
+ */
418
+ function checkSessionStartHooks(projectRoot, installationType) {
419
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
420
+ try {
421
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
422
+ // Check if hooks.SessionStart exists and contains session-start.sh
423
+ if (!settings.hooks?.SessionStart) {
424
+ return {
425
+ name: 'settings/session-start-hook',
426
+ status: 'fail',
427
+ detail: 'Missing SessionStart hooks - agents cannot find PROJECT_ROOT',
428
+ fix: () => {
429
+ addSessionStartHooks(projectRoot, installationType);
430
+ }
431
+ };
432
+ }
433
+ // Check if session-start.sh is configured
434
+ const hasSessionStartHook = settings.hooks.SessionStart.some((entry) => {
435
+ if (typeof entry === 'object' && entry !== null) {
436
+ const hookEntry = entry;
437
+ return hookEntry.hooks?.some(h => h.command?.includes('session-start.sh'));
438
+ }
439
+ return false;
440
+ });
441
+ if (!hasSessionStartHook) {
442
+ return {
443
+ name: 'settings/session-start-hook',
444
+ status: 'fail',
445
+ detail: 'session-start.sh not configured - PROJECT_ROOT will be undefined',
446
+ fix: () => {
447
+ addSessionStartHooks(projectRoot, installationType);
448
+ }
449
+ };
450
+ }
451
+ return {
452
+ name: 'settings/session-start-hook',
453
+ status: 'pass',
454
+ detail: undefined
455
+ };
456
+ }
457
+ catch {
458
+ return {
459
+ name: 'settings/session-start-hook',
460
+ status: 'warn',
461
+ detail: 'Could not parse settings.local.json'
462
+ };
463
+ }
464
+ }
465
+ /**
466
+ * Check that Stop hook is properly configured in settings.local.json
467
+ * This is needed for question reflector enforcement in Cyclist
468
+ */
469
+ function checkStopHook(projectRoot, installationType) {
470
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
471
+ try {
472
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
473
+ // Check if hooks.Stop exists and contains question-reflector-check
474
+ if (!settings.hooks?.Stop) {
475
+ return {
476
+ name: 'settings/stop-hook',
477
+ status: 'warn',
478
+ detail: 'Missing Stop hook - question reflector not enforced',
479
+ fix: () => {
480
+ addStopHook(projectRoot, installationType);
481
+ }
482
+ };
483
+ }
484
+ // Check if question-reflector-check is configured
485
+ const hasReflectorHook = settings.hooks.Stop.some((entry) => {
486
+ if (typeof entry === 'object' && entry !== null) {
487
+ const hookEntry = entry;
488
+ return hookEntry.hooks?.some(h => h.command?.includes('question-reflector-check'));
489
+ }
490
+ return false;
491
+ });
492
+ if (!hasReflectorHook) {
493
+ return {
494
+ name: 'settings/stop-hook',
495
+ status: 'warn',
496
+ detail: 'question-reflector-check not configured',
497
+ fix: () => {
498
+ addStopHook(projectRoot, installationType);
499
+ }
500
+ };
501
+ }
502
+ return {
503
+ name: 'settings/stop-hook',
504
+ status: 'pass',
505
+ detail: undefined
506
+ };
507
+ }
508
+ catch {
509
+ return {
510
+ name: 'settings/stop-hook',
511
+ status: 'warn',
512
+ detail: 'Could not parse settings.local.json'
513
+ };
514
+ }
515
+ }
516
+ /**
517
+ * Check that context-circuit-breaker hook is configured in PreToolUse
518
+ * This is needed to prevent context exhaustion (auto-saves session)
519
+ */
520
+ function checkContextCircuitBreaker(projectRoot, installationType) {
521
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
522
+ try {
523
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
524
+ // Check if hooks.PreToolUse exists and contains context-circuit-breaker
525
+ if (!settings.hooks?.PreToolUse) {
526
+ return {
527
+ name: 'settings/context-circuit-breaker',
528
+ status: 'warn',
529
+ detail: 'Missing PreToolUse hooks - context circuit breaker not configured',
530
+ fix: () => {
531
+ addContextCircuitBreaker(projectRoot, installationType);
532
+ }
533
+ };
534
+ }
535
+ // Check if context-circuit-breaker is configured
536
+ const hasCircuitBreaker = settings.hooks.PreToolUse.some((entry) => {
537
+ if (typeof entry === 'object' && entry !== null) {
538
+ const hookEntry = entry;
539
+ return hookEntry.hooks?.some(h => h.command?.includes('context-circuit-breaker'));
540
+ }
541
+ return false;
542
+ });
543
+ if (!hasCircuitBreaker) {
544
+ return {
545
+ name: 'settings/context-circuit-breaker',
546
+ status: 'warn',
547
+ detail: 'context-circuit-breaker not configured - context exhaustion protection disabled',
548
+ fix: () => {
549
+ addContextCircuitBreaker(projectRoot, installationType);
550
+ }
551
+ };
552
+ }
553
+ return {
554
+ name: 'settings/context-circuit-breaker',
555
+ status: 'pass',
556
+ detail: undefined
557
+ };
558
+ }
559
+ catch {
560
+ return {
561
+ name: 'settings/context-circuit-breaker',
562
+ status: 'warn',
563
+ detail: 'Could not parse settings.local.json'
564
+ };
565
+ }
566
+ }
567
+ /**
568
+ * Fix function: Add context-circuit-breaker hook to PreToolUse in settings.local.json
569
+ */
570
+ function addContextCircuitBreaker(projectRoot, installationType) {
571
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
572
+ const scriptBase = getScriptBasePath(installationType);
573
+ const requiredHook = {
574
+ matcher: 'Edit|Write|Bash|Task',
575
+ hooks: [
576
+ {
577
+ type: 'command',
578
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/context-circuit-breaker.sh`
579
+ }
580
+ ]
581
+ };
582
+ let settings = {};
583
+ if (pathExists(settingsPath)) {
584
+ try {
585
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
586
+ }
587
+ catch {
588
+ // Start fresh if parse fails
589
+ }
590
+ }
591
+ if (!settings.hooks) {
592
+ settings.hooks = {};
593
+ }
594
+ const hooks = settings.hooks;
595
+ if (!hooks.PreToolUse) {
596
+ hooks.PreToolUse = [requiredHook];
597
+ }
598
+ else if (Array.isArray(hooks.PreToolUse)) {
599
+ // Append the required hook (circuit breaker should run last)
600
+ hooks.PreToolUse = [...hooks.PreToolUse, requiredHook];
601
+ }
602
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
603
+ }
604
+ /**
605
+ * Check that schema-validation hook is configured in PreToolUse
606
+ * This validates XML schema for session/skill/step files on Write
607
+ */
608
+ function checkSchemaValidationHook(projectRoot, installationType) {
609
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
610
+ try {
611
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
612
+ // Check if hooks.PreToolUse exists
613
+ if (!settings.hooks?.PreToolUse) {
614
+ return {
615
+ name: 'settings/schema-validation',
616
+ status: 'warn',
617
+ detail: 'Missing PreToolUse hooks - schema validation not configured',
618
+ fix: () => {
619
+ addSchemaValidationHook(projectRoot, installationType);
620
+ }
621
+ };
622
+ }
623
+ // Check if schema-validation is configured
624
+ const hasSchemaValidation = settings.hooks.PreToolUse.some((entry) => {
625
+ if (typeof entry === 'object' && entry !== null) {
626
+ const hookEntry = entry;
627
+ return hookEntry.hooks?.some(h => h.command?.includes('schema-validation'));
628
+ }
629
+ return false;
630
+ });
631
+ if (!hasSchemaValidation) {
632
+ return {
633
+ name: 'settings/schema-validation',
634
+ status: 'warn',
635
+ detail: 'schema-validation not configured - XML schema enforcement disabled',
636
+ fix: () => {
637
+ addSchemaValidationHook(projectRoot, installationType);
638
+ }
639
+ };
640
+ }
641
+ return {
642
+ name: 'settings/schema-validation',
643
+ status: 'pass',
644
+ detail: undefined
645
+ };
646
+ }
647
+ catch {
648
+ return {
649
+ name: 'settings/schema-validation',
650
+ status: 'warn',
651
+ detail: 'Could not parse settings.local.json'
652
+ };
653
+ }
654
+ }
655
+ /**
656
+ * Fix function: Add schema-validation hook to PreToolUse in settings.local.json
657
+ */
658
+ function addSchemaValidationHook(projectRoot, installationType) {
659
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
660
+ const scriptBase = getScriptBasePath(installationType);
661
+ const requiredHook = {
662
+ matcher: 'Write',
663
+ hooks: [
664
+ {
665
+ type: 'command',
666
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/schema-validation.sh`
667
+ }
668
+ ]
669
+ };
670
+ let settings = {};
671
+ if (pathExists(settingsPath)) {
672
+ try {
673
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
674
+ }
675
+ catch {
676
+ // Start fresh if parse fails
677
+ }
678
+ }
679
+ if (!settings.hooks) {
680
+ settings.hooks = {};
681
+ }
682
+ const hooks = settings.hooks;
683
+ if (!hooks.PreToolUse) {
684
+ hooks.PreToolUse = [requiredHook];
685
+ }
686
+ else if (Array.isArray(hooks.PreToolUse)) {
687
+ // Insert schema validation early (after pre-edit-check but before circuit breaker)
688
+ hooks.PreToolUse = [requiredHook, ...hooks.PreToolUse];
689
+ }
690
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
691
+ }
692
+ /**
693
+ * Check that PostToolUse hook is properly configured in settings.local.json
694
+ * This is needed for bell mode to inject queued messages (MSSCI-12275)
695
+ */
696
+ function checkPostToolUseHook(projectRoot, installationType) {
697
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
698
+ try {
699
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
700
+ // Check if hooks.PostToolUse exists and contains bell-mode-hook
701
+ if (!settings.hooks?.PostToolUse) {
702
+ return {
703
+ name: 'settings/post-tool-use-hook',
704
+ status: 'warn',
705
+ detail: 'Missing PostToolUse hook - bell mode will not work',
706
+ fix: () => {
707
+ addPostToolUseHook(projectRoot, installationType);
708
+ }
709
+ };
710
+ }
711
+ // Check if bell-mode-hook is configured
712
+ const hasBellModeHook = settings.hooks.PostToolUse.some((entry) => {
713
+ if (typeof entry === 'object' && entry !== null) {
714
+ const hookEntry = entry;
715
+ return hookEntry.hooks?.some(h => h.command?.includes('bell-mode-hook'));
716
+ }
717
+ return false;
718
+ });
719
+ if (!hasBellModeHook) {
720
+ return {
721
+ name: 'settings/post-tool-use-hook',
722
+ status: 'warn',
723
+ detail: 'bell-mode-hook not configured - bell mode will not work',
724
+ fix: () => {
725
+ addPostToolUseHook(projectRoot, installationType);
726
+ }
727
+ };
728
+ }
729
+ return {
730
+ name: 'settings/post-tool-use-hook',
731
+ status: 'pass',
732
+ detail: undefined
733
+ };
734
+ }
735
+ catch {
736
+ return {
737
+ name: 'settings/post-tool-use-hook',
738
+ status: 'warn',
739
+ detail: 'Could not parse settings.local.json'
740
+ };
741
+ }
742
+ }
743
+ /**
744
+ * Fix function: Add PostToolUse hook to settings.local.json
745
+ * Required for bell mode to inject queued messages via additionalContext
746
+ */
747
+ function addPostToolUseHook(projectRoot, installationType) {
748
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
749
+ const scriptBase = getScriptBasePath(installationType);
750
+ const requiredHook = {
751
+ matcher: '',
752
+ hooks: [
753
+ {
754
+ type: 'command',
755
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/bell-mode-hook.sh`
756
+ }
757
+ ]
758
+ };
759
+ let settings = {};
760
+ if (pathExists(settingsPath)) {
761
+ try {
762
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
763
+ }
764
+ catch {
765
+ // Start fresh if parse fails
766
+ }
767
+ }
768
+ if (!settings.hooks) {
769
+ settings.hooks = {};
770
+ }
771
+ const hooks = settings.hooks;
772
+ if (!hooks.PostToolUse) {
773
+ hooks.PostToolUse = [requiredHook];
774
+ }
775
+ else if (Array.isArray(hooks.PostToolUse)) {
776
+ // Prepend the required hook
777
+ hooks.PostToolUse = [requiredHook, ...hooks.PostToolUse];
778
+ }
779
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
780
+ }
781
+ /**
782
+ * Check that sprint-yaml-validation hook is configured in PostToolUse
783
+ * This validates sprint YAML files after Edit/Write to ensure Cyclist compatibility
784
+ */
785
+ function checkSprintYamlValidationHook(projectRoot, installationType) {
786
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
787
+ try {
788
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
789
+ // Check if hooks.PostToolUse exists
790
+ if (!settings.hooks?.PostToolUse) {
791
+ return {
792
+ name: 'settings/sprint-yaml-validation',
793
+ status: 'warn',
794
+ detail: 'Missing PostToolUse hooks - sprint YAML validation not configured',
795
+ fix: () => {
796
+ addSprintYamlValidationHook(projectRoot, installationType);
797
+ }
798
+ };
799
+ }
800
+ // Check if sprint-yaml-validation is configured
801
+ const hasSprintYamlValidation = settings.hooks.PostToolUse.some((entry) => {
802
+ if (typeof entry === 'object' && entry !== null) {
803
+ const hookEntry = entry;
804
+ return hookEntry.hooks?.some(h => h.command?.includes('sprint-yaml-validation'));
805
+ }
806
+ return false;
807
+ });
808
+ if (!hasSprintYamlValidation) {
809
+ return {
810
+ name: 'settings/sprint-yaml-validation',
811
+ status: 'warn',
812
+ detail: 'sprint-yaml-validation not configured - sprint YAML errors may break SprintPanel',
813
+ fix: () => {
814
+ addSprintYamlValidationHook(projectRoot, installationType);
815
+ }
816
+ };
817
+ }
818
+ return {
819
+ name: 'settings/sprint-yaml-validation',
820
+ status: 'pass',
821
+ detail: undefined
822
+ };
823
+ }
824
+ catch {
825
+ return {
826
+ name: 'settings/sprint-yaml-validation',
827
+ status: 'warn',
828
+ detail: 'Could not parse settings.local.json'
829
+ };
830
+ }
831
+ }
832
+ /**
833
+ * Fix function: Add sprint-yaml-validation hook to PostToolUse in settings.local.json
834
+ * Validates sprint YAML files after Edit/Write for Cyclist SprintPanel compatibility
835
+ */
836
+ function addSprintYamlValidationHook(projectRoot, installationType) {
837
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
838
+ const scriptBase = getScriptBasePath(installationType);
839
+ const requiredHook = {
840
+ matcher: 'Edit|Write',
841
+ hooks: [
842
+ {
843
+ type: 'command',
844
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/sprint-yaml-validation.sh`
845
+ }
846
+ ]
847
+ };
848
+ let settings = {};
849
+ if (pathExists(settingsPath)) {
850
+ try {
851
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
852
+ }
853
+ catch {
854
+ // Start fresh if parse fails
855
+ }
856
+ }
857
+ if (!settings.hooks) {
858
+ settings.hooks = {};
859
+ }
860
+ const hooks = settings.hooks;
861
+ if (!hooks.PostToolUse) {
862
+ hooks.PostToolUse = [requiredHook];
863
+ }
864
+ else if (Array.isArray(hooks.PostToolUse)) {
865
+ // Append the sprint YAML validation hook
866
+ hooks.PostToolUse = [...hooks.PostToolUse, requiredHook];
867
+ }
868
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
869
+ }
870
+ /**
871
+ * Fix function: Add Stop hook to settings.local.json
872
+ */
873
+ function addStopHook(projectRoot, installationType) {
874
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
875
+ const scriptBase = getScriptBasePath(installationType);
876
+ const requiredHook = {
877
+ matcher: '',
878
+ hooks: [
879
+ {
880
+ type: 'command',
881
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/question-reflector-check.sh`
882
+ }
883
+ ]
884
+ };
885
+ let settings = {};
886
+ if (pathExists(settingsPath)) {
887
+ try {
888
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
889
+ }
890
+ catch {
891
+ // Start fresh if parse fails
892
+ }
893
+ }
894
+ if (!settings.hooks) {
895
+ settings.hooks = {};
896
+ }
897
+ const hooks = settings.hooks;
898
+ if (!hooks.Stop) {
899
+ hooks.Stop = [requiredHook];
900
+ }
901
+ else if (Array.isArray(hooks.Stop)) {
902
+ // Prepend the required hook
903
+ hooks.Stop = [requiredHook, ...hooks.Stop];
904
+ }
905
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
906
+ }
907
+ /**
908
+ * Get the script base path based on installation type
909
+ * - symlink mode: .pennyfarthing/scripts/
910
+ * - copy mode: .claude/pennyfarthing/scripts/ (legacy)
911
+ */
912
+ function getScriptBasePath(installationType) {
913
+ return installationType === 'symlink'
914
+ ? '.pennyfarthing/scripts'
915
+ : '.claude/pennyfarthing/scripts';
916
+ }
917
+ /**
918
+ * Fix function: Add SessionStart hooks to settings.local.json
919
+ */
920
+ function addSessionStartHooks(projectRoot, installationType) {
921
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
922
+ const scriptBase = getScriptBasePath(installationType);
923
+ const requiredHooks = [
924
+ {
925
+ hooks: [
926
+ {
927
+ type: 'command',
928
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/session-start.sh`
929
+ }
930
+ ]
931
+ },
932
+ {
933
+ hooks: [
934
+ {
935
+ type: 'command',
936
+ command: '"$CLAUDE_PROJECT_DIR"/.pennyfarthing/project/hooks/setup-env.sh'
937
+ }
938
+ ]
939
+ }
940
+ ];
941
+ let settings = {};
942
+ if (pathExists(settingsPath)) {
943
+ try {
944
+ settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
945
+ }
946
+ catch {
947
+ // Start fresh if parse fails
948
+ }
949
+ }
950
+ if (!settings.hooks) {
951
+ settings.hooks = {};
952
+ }
953
+ const hooks = settings.hooks;
954
+ if (!hooks.SessionStart) {
955
+ hooks.SessionStart = requiredHooks;
956
+ }
957
+ else if (Array.isArray(hooks.SessionStart)) {
958
+ // Prepend the required hooks
959
+ hooks.SessionStart = [...requiredHooks, ...hooks.SessionStart];
960
+ }
961
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
962
+ }
963
+ /**
964
+ * Create settings.local.json from template
965
+ * This is the critical fix for installations that are missing this file
966
+ */
967
+ function createSettingsLocalJson(projectRoot, installationType) {
968
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
969
+ const scriptBase = getScriptBasePath(installationType);
970
+ // Create full settings structure matching the template
971
+ const settings = {
972
+ permissions: {
973
+ allow: [
974
+ 'Read',
975
+ 'Grep',
976
+ 'Glob',
977
+ 'Bash',
978
+ 'Bash(claude:*)',
979
+ 'Bash(date:*)',
980
+ 'Bash(mkdir:*)',
981
+ 'Edit(.claude/**)',
982
+ 'Edit(.pennyfarthing/**)',
983
+ 'Edit(sprint/**)',
984
+ 'Edit(.session/**)',
985
+ 'Edit(results/**)',
986
+ 'Write(.claude/**)',
987
+ 'Write(.pennyfarthing/**)',
988
+ 'Write(sprint/**)',
989
+ 'Write(.session/**)',
990
+ 'Write(results/**)',
991
+ 'Skill(sm)',
992
+ 'Skill(tea)',
993
+ 'Skill(dev)',
994
+ 'Skill(reviewer)',
995
+ 'Skill(solo)',
996
+ 'Skill(benchmark)',
997
+ 'Skill(benchmark-control)',
998
+ 'Skill(judge)',
999
+ 'Skill(finalize-run)'
1000
+ ]
1001
+ },
1002
+ context_budget: {
1003
+ warning_threshold: 70,
1004
+ critical_threshold: 85,
1005
+ max_tokens: 200000
1006
+ },
1007
+ hooks: {
1008
+ SessionStart: [
1009
+ {
1010
+ hooks: [
1011
+ {
1012
+ type: 'command',
1013
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/session-start.sh`
1014
+ }
1015
+ ]
1016
+ },
1017
+ {
1018
+ hooks: [
1019
+ {
1020
+ type: 'command',
1021
+ command: '"$CLAUDE_PROJECT_DIR"/.pennyfarthing/project/hooks/setup-env.sh'
1022
+ }
1023
+ ]
1024
+ }
1025
+ ],
1026
+ PostToolUse: [
1027
+ {
1028
+ matcher: '',
1029
+ hooks: [
1030
+ {
1031
+ type: 'command',
1032
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/bell-mode-hook.sh`
1033
+ }
1034
+ ]
1035
+ },
1036
+ {
1037
+ matcher: 'Edit|Write',
1038
+ hooks: [
1039
+ {
1040
+ type: 'command',
1041
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/sprint-yaml-validation.sh`
1042
+ }
1043
+ ]
1044
+ }
1045
+ ],
1046
+ Stop: [
1047
+ {
1048
+ matcher: '',
1049
+ hooks: [
1050
+ {
1051
+ type: 'command',
1052
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/question-reflector-check.sh`
1053
+ }
1054
+ ]
1055
+ }
1056
+ ],
1057
+ PreToolUse: [
1058
+ {
1059
+ matcher: 'Edit|Write',
1060
+ hooks: [
1061
+ {
1062
+ type: 'command',
1063
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/pre-edit-check.sh`
1064
+ }
1065
+ ]
1066
+ },
1067
+ {
1068
+ matcher: 'Edit|Write|Bash|Task',
1069
+ hooks: [
1070
+ {
1071
+ type: 'command',
1072
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/context-warning.sh`
1073
+ }
1074
+ ]
1075
+ },
1076
+ {
1077
+ matcher: 'Edit|Write|Bash|Task',
1078
+ hooks: [
1079
+ {
1080
+ type: 'command',
1081
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/hooks/context-circuit-breaker.sh`
1082
+ }
1083
+ ]
1084
+ }
1085
+ ]
1086
+ },
1087
+ statusLine: {
1088
+ type: 'command',
1089
+ command: `"$CLAUDE_PROJECT_DIR"/${scriptBase}/misc/statusline.sh`
1090
+ }
1091
+ };
1092
+ ensureDirSync(join(projectRoot, '.claude'));
1093
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
1094
+ }
1095
+ function checkDirectories(projectRoot) {
1096
+ const results = [];
1097
+ const dirs = [
1098
+ { path: 'sprint', name: 'dir/sprint' },
1099
+ { path: '.session', name: 'dir/session' }
1100
+ ];
1101
+ for (const { path, name } of dirs) {
1102
+ const fullPath = join(projectRoot, path);
1103
+ results.push({
1104
+ name,
1105
+ status: pathExists(fullPath) ? 'pass' : 'warn',
1106
+ detail: pathExists(fullPath) ? undefined : 'Directory missing'
1107
+ });
1108
+ }
1109
+ return results;
1110
+ }
1111
+ function checkHooks(projectRoot) {
1112
+ const results = [];
1113
+ // Detect installation type from manifest
1114
+ const manifest = readManifest(projectRoot);
1115
+ const installationType = manifest?.installationType || 'copy';
1116
+ const scriptBase = getScriptBasePath(installationType);
1117
+ // Check hook scripts exist based on installation type
1118
+ const hooks = [
1119
+ { path: `${scriptBase}/hooks/session-start.sh`, name: 'hook/session-start' },
1120
+ { path: `${scriptBase}/hooks/pre-edit-check.sh`, name: 'hook/pre-edit-check' },
1121
+ { path: `${scriptBase}/hooks/context-warning.sh`, name: 'hook/context-warning' },
1122
+ { path: `${scriptBase}/hooks/context-circuit-breaker.sh`, name: 'hook/context-circuit-breaker' },
1123
+ { path: `${scriptBase}/hooks/bell-mode-hook.sh`, name: 'hook/bell-mode' },
1124
+ { path: `${scriptBase}/hooks/question-reflector-check.sh`, name: 'hook/question-reflector' },
1125
+ { path: `${scriptBase}/hooks/sprint-yaml-validation.sh`, name: 'hook/sprint-yaml-validation' }
1126
+ ];
1127
+ for (const { path, name } of hooks) {
1128
+ const fullPath = join(projectRoot, path);
1129
+ const exists = pathExists(fullPath);
1130
+ if (!exists) {
1131
+ results.push({
1132
+ name,
1133
+ status: 'warn',
1134
+ detail: `Hook script missing at ${path} - run pennyfarthing update`
1135
+ });
1136
+ continue;
1137
+ }
1138
+ // Check if executable
1139
+ try {
1140
+ const stats = statSync(fullPath);
1141
+ const isExecutable = (stats.mode & 0o111) !== 0;
1142
+ results.push({
1143
+ name,
1144
+ status: isExecutable ? 'pass' : 'warn',
1145
+ detail: isExecutable ? undefined : 'Not executable',
1146
+ fix: isExecutable ? undefined : () => {
1147
+ chmodSync(fullPath, 0o755);
1148
+ }
1149
+ });
1150
+ }
1151
+ catch {
1152
+ results.push({
1153
+ name,
1154
+ status: 'fail',
1155
+ detail: 'Cannot read hook'
1156
+ });
1157
+ }
1158
+ }
1159
+ return results;
1160
+ }
1161
+ /**
1162
+ * Check Cyclist installation health (if installed as a workspace package)
1163
+ * Detects node-pty spawn-helper permission issues that cause posix_spawnp failures
1164
+ */
1165
+ function checkCyclist(projectRoot) {
1166
+ const results = [];
1167
+ // Detect Cyclist package — check common locations
1168
+ const cyclistLocations = [
1169
+ join(projectRoot, 'packages/cyclist'),
1170
+ join(projectRoot, 'node_modules/@pennyfarthing/cyclist'),
1171
+ ];
1172
+ let cyclistDir = null;
1173
+ for (const loc of cyclistLocations) {
1174
+ if (pathExists(join(loc, 'package.json'))) {
1175
+ cyclistDir = loc;
1176
+ break;
1177
+ }
1178
+ }
1179
+ if (!cyclistDir) {
1180
+ // Cyclist not installed — skip silently
1181
+ return results;
1182
+ }
1183
+ results.push({
1184
+ name: 'cyclist/installed',
1185
+ status: 'pass',
1186
+ detail: relative(projectRoot, cyclistDir)
1187
+ });
1188
+ // Check node-pty spawn-helper permissions
1189
+ const os = process.platform === 'darwin' ? 'darwin' : process.platform === 'linux' ? 'linux' : null;
1190
+ const arch = process.arch === 'arm64' ? 'arm64' : process.arch === 'x64' ? 'x64' : null;
1191
+ if (!os || !arch) {
1192
+ return results;
1193
+ }
1194
+ // Look for node-pty prebuilds — check cyclist's own node_modules first, then monorepo root
1195
+ const searchPaths = [
1196
+ join(cyclistDir, 'node_modules/node-pty'),
1197
+ join(projectRoot, 'node_modules/node-pty'),
1198
+ ];
1199
+ let nodePtyDir = null;
1200
+ for (const p of searchPaths) {
1201
+ if (pathExists(join(p, 'prebuilds'))) {
1202
+ nodePtyDir = p;
1203
+ break;
1204
+ }
1205
+ }
1206
+ // Also check pnpm store path (node_modules/.pnpm/node-pty@*/node_modules/node-pty)
1207
+ if (!nodePtyDir) {
1208
+ const pnpmBase = join(projectRoot, 'node_modules/.pnpm');
1209
+ if (pathExists(pnpmBase)) {
1210
+ try {
1211
+ const entries = readdirSync(pnpmBase);
1212
+ const nodePtyEntry = entries.find((e) => e.startsWith('node-pty@'));
1213
+ if (nodePtyEntry) {
1214
+ const candidate = join(pnpmBase, nodePtyEntry, 'node_modules/node-pty');
1215
+ if (pathExists(join(candidate, 'prebuilds'))) {
1216
+ nodePtyDir = candidate;
1217
+ }
1218
+ }
1219
+ }
1220
+ catch {
1221
+ // ignore
1222
+ }
1223
+ }
1224
+ }
1225
+ if (!nodePtyDir) {
1226
+ results.push({
1227
+ name: 'cyclist/node-pty',
1228
+ status: 'warn',
1229
+ detail: 'node-pty not found — terminal panel will not work'
1230
+ });
1231
+ return results;
1232
+ }
1233
+ const spawnHelper = join(nodePtyDir, 'prebuilds', `${os}-${arch}`, 'spawn-helper');
1234
+ if (!pathExists(spawnHelper)) {
1235
+ results.push({
1236
+ name: 'cyclist/spawn-helper',
1237
+ status: 'warn',
1238
+ detail: `spawn-helper not found for ${os}-${arch}`
1239
+ });
1240
+ return results;
1241
+ }
1242
+ try {
1243
+ const stats = statSync(spawnHelper);
1244
+ const isExecutable = (stats.mode & 0o111) !== 0;
1245
+ results.push({
1246
+ name: 'cyclist/spawn-helper',
1247
+ status: isExecutable ? 'pass' : 'fail',
1248
+ detail: isExecutable ? undefined : 'Missing execute permission (causes posix_spawnp failure)',
1249
+ fix: isExecutable ? undefined : () => {
1250
+ chmodSync(spawnHelper, 0o755);
1251
+ }
1252
+ });
1253
+ }
1254
+ catch {
1255
+ results.push({
1256
+ name: 'cyclist/spawn-helper',
1257
+ status: 'warn',
1258
+ detail: 'Cannot read spawn-helper'
1259
+ });
1260
+ }
1261
+ return results;
1262
+ }
1263
+ /**
1264
+ * Known legacy statusline paths from various Pennyfarthing versions.
1265
+ * These should be detected and cleaned up when proper statusline exists.
1266
+ */
1267
+ const LEGACY_STATUSLINE_PATHS = [
1268
+ '.claude/core/statusline.sh',
1269
+ '.claude/statusline.sh',
1270
+ '.claude/pennyfarthing/statusline.sh', // v4.0.0-4.0.3
1271
+ '.claude/pennyfarthing/scripts/statusline.sh', // v4.0.5
1272
+ '.claude/scripts/statusline.sh', // pre-v6.6
1273
+ '.pennyfarthing/scripts/statusline.sh' // before v7.0.3
1274
+ ];
1275
+ /**
1276
+ * Canonical statusline path for current version (v7.x)
1277
+ */
1278
+ const CANONICAL_STATUSLINE_PATH = '.pennyfarthing/scripts/misc/statusline.sh';
1279
+ /**
1280
+ * Check for legacy files that may shadow or conflict with current Pennyfarthing files.
1281
+ * Returns results with fix functions for --fix mode.
1282
+ */
1283
+ export function checkLegacyFiles(projectRoot) {
1284
+ const results = [];
1285
+ // Check for legacy .claude/scripts/statusline.sh
1286
+ const legacyStatusline = join(projectRoot, '.claude/scripts/statusline.sh');
1287
+ const properStatusline = join(projectRoot, CANONICAL_STATUSLINE_PATH);
1288
+ if (pathExists(legacyStatusline)) {
1289
+ if (pathExists(properStatusline)) {
1290
+ // Both exist - legacy shadows proper
1291
+ results.push({
1292
+ name: 'legacy/.claude/scripts/statusline.sh',
1293
+ status: 'warn',
1294
+ detail: 'Shadows proper pennyfarthing statusline',
1295
+ fix: () => {
1296
+ unlinkSync(legacyStatusline);
1297
+ }
1298
+ });
1299
+ }
1300
+ // If only legacy exists, don't warn - user may have custom setup
1301
+ }
1302
+ // Check for legacy .claude/persona-config.yaml
1303
+ const legacyPersonaConfig = join(projectRoot, '.claude/persona-config.yaml');
1304
+ const properThemeConfig = join(projectRoot, '.pennyfarthing/config.local.yaml');
1305
+ if (pathExists(legacyPersonaConfig)) {
1306
+ const detail = pathExists(properThemeConfig)
1307
+ ? 'May conflict with .pennyfarthing/config.local.yaml'
1308
+ : 'Should be migrated to .pennyfarthing/config.local.yaml';
1309
+ results.push({
1310
+ name: 'legacy/.claude/persona-config.yaml',
1311
+ status: 'warn',
1312
+ detail,
1313
+ fix: () => {
1314
+ // Read theme from legacy file
1315
+ try {
1316
+ const legacyContent = readFileSync(legacyPersonaConfig, 'utf8');
1317
+ const legacyConfig = YAML.parse(legacyContent);
1318
+ const legacyTheme = legacyConfig?.theme;
1319
+ if (legacyTheme) {
1320
+ // Read existing config.local.yaml or start fresh
1321
+ let config = {};
1322
+ if (pathExists(properThemeConfig)) {
1323
+ try {
1324
+ config = YAML.parse(readFileSync(properThemeConfig, 'utf8')) || {};
1325
+ }
1326
+ catch {
1327
+ config = {};
1328
+ }
1329
+ }
1330
+ // Only set theme if not already present in config.local.yaml
1331
+ if (!config.theme) {
1332
+ config.theme = legacyTheme;
1333
+ const configDir = dirname(properThemeConfig);
1334
+ if (!existsSync(configDir)) {
1335
+ mkdirSync(configDir, { recursive: true });
1336
+ }
1337
+ writeFileSync(properThemeConfig, YAML.stringify(config), 'utf8');
1338
+ }
1339
+ }
1340
+ }
1341
+ catch {
1342
+ // If we can't read/parse legacy, just remove it
1343
+ }
1344
+ unlinkSync(legacyPersonaConfig);
1345
+ }
1346
+ });
1347
+ }
1348
+ // Check for legacy sidecar directories at .claude/project/agents/{agent}-sidecar/
1349
+ const legacyAgentsDir = join(projectRoot, '.claude/project/agents');
1350
+ if (pathExists(legacyAgentsDir)) {
1351
+ const legacySidecars = CORE_AGENTS.filter(a => pathExists(join(legacyAgentsDir, `${a}-sidecar`)));
1352
+ if (legacySidecars.length > 0) {
1353
+ results.push({
1354
+ name: 'legacy/.claude/project/agents/sidecars',
1355
+ status: 'warn',
1356
+ detail: `${legacySidecars.length} legacy sidecar dirs (should be at .pennyfarthing/sidecars/)`,
1357
+ fix: () => {
1358
+ for (const agent of legacySidecars) {
1359
+ const legacyDir = join(legacyAgentsDir, `${agent}-sidecar`);
1360
+ const newDir = join(projectRoot, `.pennyfarthing/sidecars/${agent}`);
1361
+ // Only remove if new location already has the sidecar
1362
+ if (pathExists(newDir)) {
1363
+ removeSync(legacyDir);
1364
+ }
1365
+ }
1366
+ // Remove agents/ dir if empty
1367
+ try {
1368
+ const remaining = readdirSync(legacyAgentsDir);
1369
+ if (remaining.length === 0) {
1370
+ removeSync(legacyAgentsDir);
1371
+ }
1372
+ }
1373
+ catch {
1374
+ // Ignore
1375
+ }
1376
+ }
1377
+ });
1378
+ }
1379
+ }
1380
+ // Check for legacy sidecar directories at sprint/sidecars/
1381
+ const legacySprintSidecars = join(projectRoot, 'sprint/sidecars');
1382
+ if (pathExists(legacySprintSidecars)) {
1383
+ results.push({
1384
+ name: 'legacy/sprint/sidecars',
1385
+ status: 'warn',
1386
+ detail: 'Legacy sidecar location (should be at .pennyfarthing/sidecars/)',
1387
+ fix: () => {
1388
+ // Only remove if all agents have been migrated
1389
+ try {
1390
+ const remaining = readdirSync(legacySprintSidecars);
1391
+ const allMigrated = remaining.every(item => {
1392
+ const itemPath = join(legacySprintSidecars, item);
1393
+ if (!isDirectory(itemPath))
1394
+ return false;
1395
+ return pathExists(join(projectRoot, `.pennyfarthing/sidecars/${item}`));
1396
+ });
1397
+ if (allMigrated) {
1398
+ removeSync(legacySprintSidecars);
1399
+ }
1400
+ }
1401
+ catch {
1402
+ // Ignore
1403
+ }
1404
+ }
1405
+ });
1406
+ }
1407
+ // Check for legacy .claude/project/hooks/setup-env.sh
1408
+ const legacyProjectHook = join(projectRoot, '.claude/project/hooks/setup-env.sh');
1409
+ const properProjectHook = join(projectRoot, '.pennyfarthing/project/hooks/setup-env.sh');
1410
+ if (pathExists(legacyProjectHook)) {
1411
+ const detail = pathExists(properProjectHook)
1412
+ ? 'May conflict with .pennyfarthing/project/hooks/setup-env.sh'
1413
+ : 'Should be migrated to .pennyfarthing/project/hooks/setup-env.sh';
1414
+ results.push({
1415
+ name: 'legacy/.claude/project/hooks/setup-env.sh',
1416
+ status: 'warn',
1417
+ detail,
1418
+ fix: () => {
1419
+ if (!pathExists(properProjectHook)) {
1420
+ const destDir = dirname(properProjectHook);
1421
+ if (!existsSync(destDir)) {
1422
+ mkdirSync(destDir, { recursive: true });
1423
+ }
1424
+ renameSync(legacyProjectHook, properProjectHook);
1425
+ }
1426
+ else {
1427
+ unlinkSync(legacyProjectHook);
1428
+ }
1429
+ }
1430
+ });
1431
+ }
1432
+ return results;
1433
+ }
1434
+ /**
1435
+ * Check if settings.local.json has statusline configured.
1436
+ * The statusLine config is a TOP-LEVEL key (not inside hooks), with structure:
1437
+ * { "statusLine": { "type": "command", "command": "path/to/script" } }
1438
+ *
1439
+ * Returns result with fix function to update to canonical path if needed.
1440
+ */
1441
+ export function checkLegacyStatuslinePath(projectRoot) {
1442
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
1443
+ // No settings file - nothing to check
1444
+ if (!pathExists(settingsPath)) {
1445
+ return {
1446
+ name: 'settings/statusline-path',
1447
+ status: 'pass',
1448
+ detail: 'No settings file'
1449
+ };
1450
+ }
1451
+ let settings;
1452
+ try {
1453
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
1454
+ }
1455
+ catch {
1456
+ return {
1457
+ name: 'settings/statusline-path',
1458
+ status: 'warn',
1459
+ detail: 'Cannot parse settings.local.json'
1460
+ };
1461
+ }
1462
+ // statusLine is a TOP-LEVEL key, not inside hooks
1463
+ // Format: { type: "command", command: "..." }
1464
+ const statusLine = settings.statusLine;
1465
+ if (!statusLine || !statusLine.command) {
1466
+ // No statusline configured
1467
+ return {
1468
+ name: 'settings/statusline-path',
1469
+ status: 'pass',
1470
+ detail: 'No statusline configured'
1471
+ };
1472
+ }
1473
+ // Extract the path from the command (may have $CLAUDE_PROJECT_DIR prefix)
1474
+ const command = statusLine.command;
1475
+ // Match patterns like "$CLAUDE_PROJECT_DIR"/.pennyfarthing/scripts/misc/statusline.sh
1476
+ // or plain paths like .pennyfarthing/scripts/misc/statusline.sh
1477
+ const pathMatch = command.match(/(?:\"\$CLAUDE_PROJECT_DIR\"\/)?([^\s"]+)/);
1478
+ const currentPath = pathMatch ? pathMatch[1] : command;
1479
+ // Check if it contains the canonical path
1480
+ if (currentPath.includes('misc/statusline.sh') || command.includes('misc/statusline.sh')) {
1481
+ return {
1482
+ name: 'settings/statusline-path',
1483
+ status: 'pass',
1484
+ detail: 'Configured'
1485
+ };
1486
+ }
1487
+ // Check if it's a known legacy path
1488
+ const isLegacy = LEGACY_STATUSLINE_PATHS.some(legacyPath => currentPath.includes(legacyPath) || command.includes(legacyPath));
1489
+ if (isLegacy) {
1490
+ // Check if proper statusline exists before offering fix
1491
+ const properStatusline = join(projectRoot, CANONICAL_STATUSLINE_PATH);
1492
+ if (pathExists(properStatusline)) {
1493
+ return {
1494
+ name: 'settings/statusline-path',
1495
+ status: 'warn',
1496
+ detail: `Legacy path in command`,
1497
+ fix: () => {
1498
+ const updatedSettings = { ...settings };
1499
+ updatedSettings.statusLine = {
1500
+ type: 'command',
1501
+ command: `"$CLAUDE_PROJECT_DIR"/${CANONICAL_STATUSLINE_PATH}`
1502
+ };
1503
+ writeFileSync(settingsPath, JSON.stringify(updatedSettings, null, 2));
1504
+ }
1505
+ };
1506
+ }
1507
+ }
1508
+ // Has statusline configured (custom or valid)
1509
+ return {
1510
+ name: 'settings/statusline-path',
1511
+ status: 'pass',
1512
+ detail: 'Configured'
1513
+ };
1514
+ }
1515
+ /**
1516
+ * Check file layout — validate files are at correct .pennyfarthing/ locations.
1517
+ * Flags old .claude/ locations with migration instructions.
1518
+ * Fix functions migrate files automatically without overwriting existing files.
1519
+ *
1520
+ * MSSCI-14372
1521
+ */
1522
+ export function checkFileLayout(projectRoot) {
1523
+ const results = [];
1524
+ // 1. Manifest at .pennyfarthing/manifest.json
1525
+ const manifestPath = join(projectRoot, '.pennyfarthing/manifest.json');
1526
+ results.push({
1527
+ name: 'layout/manifest',
1528
+ status: existsSync(manifestPath) ? 'pass' : 'fail',
1529
+ detail: existsSync(manifestPath) ? undefined : 'Missing .pennyfarthing/manifest.json'
1530
+ });
1531
+ // 2. Config at .pennyfarthing/config.local.yaml
1532
+ const configPath = join(projectRoot, '.pennyfarthing/config.local.yaml');
1533
+ results.push({
1534
+ name: 'layout/config',
1535
+ status: existsSync(configPath) ? 'pass' : 'warn',
1536
+ detail: existsSync(configPath) ? undefined : 'No theme configured at .pennyfarthing/config.local.yaml'
1537
+ });
1538
+ // 3. Old config at .claude/persona-config.yaml
1539
+ const oldConfigPath = join(projectRoot, '.claude/persona-config.yaml');
1540
+ if (existsSync(oldConfigPath)) {
1541
+ results.push({
1542
+ name: 'layout/config-old-location',
1543
+ status: 'warn',
1544
+ detail: 'Migrate to .pennyfarthing/config.local.yaml',
1545
+ fix: () => {
1546
+ if (!existsSync(configPath)) {
1547
+ const configDir = dirname(configPath);
1548
+ if (!existsSync(configDir)) {
1549
+ mkdirSync(configDir, { recursive: true });
1550
+ }
1551
+ renameSync(oldConfigPath, configPath);
1552
+ }
1553
+ else {
1554
+ unlinkSync(oldConfigPath);
1555
+ }
1556
+ }
1557
+ });
1558
+ }
1559
+ // 4. Settings at .claude/settings.local.json
1560
+ const settingsPath = join(projectRoot, '.claude/settings.local.json');
1561
+ results.push({
1562
+ name: 'layout/settings',
1563
+ status: existsSync(settingsPath) ? 'pass' : 'fail',
1564
+ detail: existsSync(settingsPath) ? undefined : 'Missing .claude/settings.local.json — hooks not registered'
1565
+ });
1566
+ // 5. Sidecars at .pennyfarthing/sidecars/
1567
+ const sidecarsPath = join(projectRoot, '.pennyfarthing/sidecars');
1568
+ if (existsSync(sidecarsPath) && isDirectory(sidecarsPath)) {
1569
+ results.push({
1570
+ name: 'layout/sidecars',
1571
+ status: 'pass',
1572
+ detail: undefined
1573
+ });
1574
+ }
1575
+ // 6. Old sidecars at .claude/project/agents/*-sidecar/
1576
+ const oldAgentsDir = join(projectRoot, '.claude/project/agents');
1577
+ if (existsSync(oldAgentsDir)) {
1578
+ try {
1579
+ const entries = readdirSync(oldAgentsDir);
1580
+ const sidecarDirs = entries.filter(e => e.endsWith('-sidecar') && isDirectory(join(oldAgentsDir, e)));
1581
+ if (sidecarDirs.length > 0) {
1582
+ results.push({
1583
+ name: 'layout/sidecars-old-location',
1584
+ status: 'warn',
1585
+ detail: `${sidecarDirs.length} legacy sidecar dir(s) — migrate to .pennyfarthing/sidecars/`,
1586
+ fix: () => {
1587
+ for (const dir of sidecarDirs) {
1588
+ const agentName = dir.replace(/-sidecar$/, '');
1589
+ const srcDir = join(oldAgentsDir, dir);
1590
+ const destDir = join(projectRoot, `.pennyfarthing/sidecars/${agentName}`);
1591
+ if (!existsSync(destDir)) {
1592
+ ensureDirSync(destDir);
1593
+ const files = readdirSync(srcDir);
1594
+ for (const file of files) {
1595
+ renameSync(join(srcDir, file), join(destDir, file));
1596
+ }
1597
+ }
1598
+ removeSync(srcDir);
1599
+ }
1600
+ }
1601
+ });
1602
+ }
1603
+ }
1604
+ catch {
1605
+ // Ignore read errors
1606
+ }
1607
+ }
1608
+ // 7. Project hooks at .pennyfarthing/project/hooks/
1609
+ const projectHooksPath = join(projectRoot, '.pennyfarthing/project/hooks');
1610
+ if (existsSync(projectHooksPath) && isDirectory(projectHooksPath)) {
1611
+ results.push({
1612
+ name: 'layout/project-hooks',
1613
+ status: 'pass',
1614
+ detail: undefined
1615
+ });
1616
+ }
1617
+ // 8. Old project hooks at .claude/project/hooks/
1618
+ const oldProjectHooksPath = join(projectRoot, '.claude/project/hooks');
1619
+ if (existsSync(oldProjectHooksPath) && isDirectory(oldProjectHooksPath)) {
1620
+ results.push({
1621
+ name: 'layout/project-hooks-old-location',
1622
+ status: 'warn',
1623
+ detail: 'Migrate to .pennyfarthing/project/hooks/',
1624
+ fix: () => {
1625
+ if (!existsSync(projectHooksPath)) {
1626
+ ensureDirSync(dirname(projectHooksPath));
1627
+ renameSync(oldProjectHooksPath, projectHooksPath);
1628
+ }
1629
+ else {
1630
+ // Copy individual files that don't exist at destination
1631
+ try {
1632
+ const files = readdirSync(oldProjectHooksPath);
1633
+ for (const file of files) {
1634
+ const dest = join(projectHooksPath, file);
1635
+ if (!existsSync(dest)) {
1636
+ renameSync(join(oldProjectHooksPath, file), dest);
1637
+ }
1638
+ }
1639
+ }
1640
+ catch {
1641
+ // Ignore
1642
+ }
1643
+ removeSync(oldProjectHooksPath);
1644
+ }
1645
+ }
1646
+ });
1647
+ }
1648
+ return results;
1649
+ }
1650
+ //# sourceMappingURL=doctor.js.map