@pennyfarthing/core 11.2.2 → 11.3.2

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 (168) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/packages/core/dist/cli/commands/doctor-legacy.test.js +2 -2
  4. package/packages/core/dist/cli/commands/doctor-legacy.test.js.map +1 -1
  5. package/packages/core/dist/cli/commands/doctor.d.ts +63 -0
  6. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
  7. package/packages/core/dist/cli/commands/doctor.js +280 -43
  8. package/packages/core/dist/cli/commands/doctor.js.map +1 -1
  9. package/packages/core/dist/cli/commands/init.d.ts +12 -0
  10. package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
  11. package/packages/core/dist/cli/commands/init.js +45 -0
  12. package/packages/core/dist/cli/commands/init.js.map +1 -1
  13. package/packages/core/dist/cli/commands/pyproject-install.test.d.ts +19 -0
  14. package/packages/core/dist/cli/commands/pyproject-install.test.d.ts.map +1 -0
  15. package/packages/core/dist/cli/commands/pyproject-install.test.js +261 -0
  16. package/packages/core/dist/cli/commands/pyproject-install.test.js.map +1 -0
  17. package/packages/core/dist/cli/commands/update-consolidation.test.js +14 -6
  18. package/packages/core/dist/cli/commands/update-consolidation.test.js.map +1 -1
  19. package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
  20. package/packages/core/dist/cli/commands/update.js +5 -1
  21. package/packages/core/dist/cli/commands/update.js.map +1 -1
  22. package/packages/core/dist/cli/index.js +2 -0
  23. package/packages/core/dist/cli/index.js.map +1 -1
  24. package/packages/core/dist/cli/utils/python.d.ts +1 -0
  25. package/packages/core/dist/cli/utils/python.d.ts.map +1 -1
  26. package/packages/core/dist/cli/utils/python.js +22 -1
  27. package/packages/core/dist/cli/utils/python.js.map +1 -1
  28. package/packages/core/dist/cli/utils/settings-hook-migration.test.d.ts +17 -0
  29. package/packages/core/dist/cli/utils/settings-hook-migration.test.d.ts.map +1 -0
  30. package/packages/core/dist/cli/utils/settings-hook-migration.test.js +382 -0
  31. package/packages/core/dist/cli/utils/settings-hook-migration.test.js.map +1 -0
  32. package/packages/core/dist/cli/utils/settings-pf-wrapper.test.d.ts +16 -0
  33. package/packages/core/dist/cli/utils/settings-pf-wrapper.test.d.ts.map +1 -0
  34. package/packages/core/dist/cli/utils/settings-pf-wrapper.test.js +377 -0
  35. package/packages/core/dist/cli/utils/settings-pf-wrapper.test.js.map +1 -0
  36. package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
  37. package/packages/core/dist/cli/utils/settings.js +15 -2
  38. package/packages/core/dist/cli/utils/settings.js.map +1 -1
  39. package/packages/core/dist/server/paths.d.ts.map +1 -1
  40. package/packages/core/dist/server/paths.js +6 -0
  41. package/packages/core/dist/server/paths.js.map +1 -1
  42. package/packages/core/dist/server/settings.d.ts.map +1 -1
  43. package/packages/core/dist/server/settings.js +5 -0
  44. package/packages/core/dist/server/settings.js.map +1 -1
  45. package/packages/core/dist/workflow/tandem-workflow-templates.test.js +7 -5
  46. package/packages/core/dist/workflow/tandem-workflow-templates.test.js.map +1 -1
  47. package/packages/core/dist/workflow/workflow-graph-validation.d.ts +65 -0
  48. package/packages/core/dist/workflow/workflow-graph-validation.d.ts.map +1 -0
  49. package/packages/core/dist/workflow/workflow-graph-validation.js +190 -0
  50. package/packages/core/dist/workflow/workflow-graph-validation.js.map +1 -0
  51. package/packages/core/dist/workflow/workflow-graph-validation.test.d.ts +18 -0
  52. package/packages/core/dist/workflow/workflow-graph-validation.test.d.ts.map +1 -0
  53. package/packages/core/dist/workflow/workflow-graph-validation.test.js +706 -0
  54. package/packages/core/dist/workflow/workflow-graph-validation.test.js.map +1 -0
  55. package/packages/core/dist/workflow/workflow-migration.test.js +6 -5
  56. package/packages/core/dist/workflow/workflow-migration.test.js.map +1 -1
  57. package/pennyfarthing-dist/agents/dev.md +4 -2
  58. package/pennyfarthing-dist/agents/devops.md +2 -10
  59. package/pennyfarthing-dist/agents/reviewer-preflight.md +4 -5
  60. package/pennyfarthing-dist/agents/sm.md +4 -17
  61. package/pennyfarthing-dist/commands/pf-health-check.md +30 -11
  62. package/pennyfarthing-dist/gates/{confidence-sm.md → confidence.md} +16 -17
  63. package/pennyfarthing-dist/gates/dev-exit.md +75 -0
  64. package/pennyfarthing-dist/gates/merge-ready.md +49 -0
  65. package/pennyfarthing-dist/gates/release-ready.md +95 -0
  66. package/pennyfarthing-dist/gates/reviewer-preflight-check.md +90 -0
  67. package/pennyfarthing-dist/gates/sm-setup-exit.md +82 -0
  68. package/pennyfarthing-dist/guides/agent-behavior.md +88 -30
  69. package/pennyfarthing-dist/guides/gates.md +7 -2
  70. package/pennyfarthing-dist/scripts/lib/find-root.sh +5 -0
  71. package/pennyfarthing-dist/scripts/lib/run-pf.sh +7 -0
  72. package/pennyfarthing-dist/skills/pf-settings/skill.md +42 -0
  73. package/pennyfarthing-dist/skills/skill-registry.yaml +15 -0
  74. package/pennyfarthing-dist/templates/pyproject.toml +27 -0
  75. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +7 -3
  76. package/pennyfarthing-dist/workflows/bdd.yaml +7 -3
  77. package/pennyfarthing-dist/workflows/installation-check/steps/step-01-foundation.md +77 -0
  78. package/pennyfarthing-dist/workflows/installation-check/steps/step-02-commands.md +82 -0
  79. package/pennyfarthing-dist/workflows/installation-check/steps/step-03-hooks.md +121 -0
  80. package/pennyfarthing-dist/workflows/installation-check/steps/step-04-scripts.md +83 -0
  81. package/pennyfarthing-dist/workflows/installation-check/steps/step-05-layout.md +81 -0
  82. package/pennyfarthing-dist/workflows/installation-check/steps/step-06-legacy.md +94 -0
  83. package/pennyfarthing-dist/workflows/installation-check/steps/step-07-tools.md +80 -0
  84. package/pennyfarthing-dist/workflows/installation-check/steps/step-08-summary.md +99 -0
  85. package/pennyfarthing-dist/workflows/installation-check/workflow.yaml +47 -0
  86. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +7 -3
  87. package/pennyfarthing-dist/workflows/tdd.yaml +7 -3
  88. package/pennyfarthing-dist/workflows/trivial.yaml +7 -3
  89. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  90. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  91. package/pennyfarthing_scripts/__pycache__/context.cpython-314.pyc +0 -0
  92. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  93. package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
  94. package/pennyfarthing_scripts/bc/__pycache__/split.cpython-314.pyc +0 -0
  95. package/pennyfarthing_scripts/bc/cli.py +21 -0
  96. package/pennyfarthing_scripts/bc/focus.py +1 -0
  97. package/pennyfarthing_scripts/bc/split.py +52 -0
  98. package/pennyfarthing_scripts/bikerack/__pycache__/audit_log_panel.cpython-314.pyc +0 -0
  99. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  100. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  101. package/pennyfarthing_scripts/bikerack/__pycache__/context_meter_footer.cpython-314.pyc +0 -0
  102. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  103. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  104. package/pennyfarthing_scripts/bikerack/__pycache__/events.cpython-314.pyc +0 -0
  105. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  106. package/pennyfarthing_scripts/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
  107. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  108. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  109. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  110. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  111. package/pennyfarthing_scripts/bikerack/context_meter_footer.py +53 -3
  112. package/pennyfarthing_scripts/bikerack/tui.py +202 -8
  113. package/pennyfarthing_scripts/bmad/__init__.py +1 -0
  114. package/pennyfarthing_scripts/bmad/__pycache__/__init__.cpython-314.pyc +0 -0
  115. package/pennyfarthing_scripts/bmad/__pycache__/cli.cpython-314.pyc +0 -0
  116. package/pennyfarthing_scripts/bmad/__pycache__/parser.cpython-314.pyc +0 -0
  117. package/pennyfarthing_scripts/bmad/__pycache__/sync.cpython-314.pyc +0 -0
  118. package/pennyfarthing_scripts/bmad/__pycache__/test_parser.cpython-314-pytest-9.0.2.pyc +0 -0
  119. package/pennyfarthing_scripts/bmad/__pycache__/test_sync.cpython-314-pytest-9.0.2.pyc +0 -0
  120. package/pennyfarthing_scripts/bmad/cli.py +197 -0
  121. package/pennyfarthing_scripts/bmad/importer.py +200 -0
  122. package/pennyfarthing_scripts/bmad/parser.py +233 -0
  123. package/pennyfarthing_scripts/bmad/sync.py +464 -0
  124. package/pennyfarthing_scripts/bmad/test_parser.py +253 -0
  125. package/pennyfarthing_scripts/bmad/test_sync.py +223 -0
  126. package/pennyfarthing_scripts/cli.py +10 -0
  127. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  128. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  129. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  130. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  131. package/pennyfarthing_scripts/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
  132. package/pennyfarthing_scripts/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
  133. package/pennyfarthing_scripts/handoff/__pycache__/marker.cpython-314.pyc +0 -0
  134. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  135. package/pennyfarthing_scripts/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  136. package/pennyfarthing_scripts/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
  137. package/pennyfarthing_scripts/hooks/__pycache__/cli.cpython-314.pyc +0 -0
  138. package/pennyfarthing_scripts/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
  139. package/pennyfarthing_scripts/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
  140. package/pennyfarthing_scripts/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
  141. package/pennyfarthing_scripts/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
  142. package/pennyfarthing_scripts/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
  143. package/pennyfarthing_scripts/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
  144. package/pennyfarthing_scripts/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
  145. package/pennyfarthing_scripts/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
  146. package/pennyfarthing_scripts/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
  147. package/pennyfarthing_scripts/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
  148. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  149. package/pennyfarthing_scripts/settings/__init__.py +0 -0
  150. package/pennyfarthing_scripts/settings/__pycache__/__init__.cpython-314.pyc +0 -0
  151. package/pennyfarthing_scripts/settings/__pycache__/cli.cpython-314.pyc +0 -0
  152. package/pennyfarthing_scripts/settings/__pycache__/settings.cpython-314.pyc +0 -0
  153. package/pennyfarthing_scripts/settings/cli.py +55 -0
  154. package/pennyfarthing_scripts/settings/settings.py +98 -0
  155. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  156. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  157. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  158. package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_evaluation.cpython-314-pytest-9.0.2.pyc +0 -0
  159. package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_gate.cpython-314-pytest-9.0.2.pyc +0 -0
  160. package/pennyfarthing_scripts/tests/__pycache__/test_gate_file_resolution.cpython-314-pytest-9.0.2.pyc +0 -0
  161. package/pennyfarthing_scripts/tests/__pycache__/test_gate_runner.cpython-314-pytest-9.0.2.pyc +0 -0
  162. package/pennyfarthing_scripts/tests/__pycache__/test_resolve_gate_file_field.cpython-314-pytest-9.0.2.pyc +0 -0
  163. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_list_team.cpython-314.pyc +0 -0
  164. package/pennyfarthing_scripts/tests/test_confidence_sm_gate.py +17 -16
  165. package/pennyfarthing_scripts/tests/test_resolve_gate_file_field.py +45 -47
  166. package/pennyfarthing_scripts/tests/test_workflow_list_team.py +0 -4
  167. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Pennyfarthing
2
2
 
3
- **v11.2.2** | *The outer loop goes once, the inner loop goes many times.*
3
+ **v11.3.2** | *The outer loop goes once, the inner loop goes many times.*
4
4
 
5
5
  <img src="pennyfarthing.png" alt="Pennyfarthing Logo" width="75" style="float:left; margin:10px">
6
6
 
@@ -15,9 +15,9 @@ A Claude Code agent orchestration framework built around three pillars: a flexib
15
15
  A multi-agent system with customizable BikeLane workflows for structured software development:
16
16
 
17
17
  - **11 Coordinated Agents** - SM, TEA, Dev, Reviewer, Architect, PM, Tech Writer, UX Designer, DevOps, Orchestrator, BA
18
- - **12 BikeLane Workflows** - Phased (TDD, BDD, Trivial, 2pTDD, TDD-Tandem, BDD-Tandem, Review-Tandem, Patch, Agent-Docs), Stepped (Architecture, Release, Git Cleanup)
18
+ - **14 BikeLane Workflows** - Phased (TDD, BDD, Trivial, 2pTDD, TDD-Tandem, BDD-Tandem, TDD-Team, BDD-Team, Review-Tandem, Patch, Agent-Docs), Stepped (Architecture, Release, Git Cleanup)
19
19
  - **60 Slash Commands** - Entry points for agent activation and workflows
20
- - **22 Skills** - Reusable knowledge domains (testing, code-review, jira, mermaid, etc.)
20
+ - **23 Skills** - Reusable knowledge domains (testing, code-review, jira, settings, mermaid, etc.)
21
21
  - **Prime Context System** - Tiered context injection assembles agent definition, persona, session state, and sidecar memory
22
22
  - **Automatic Handoffs** - Context-aware agent transitions via subagent delegation
23
23
  - **Agent Sidecars** - Persistent learning files where agents record patterns, gotchas, and decisions across stories
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pennyfarthing/core",
3
- "version": "11.2.2",
3
+ "version": "11.3.2",
4
4
  "description": "Claude Code agent framework with TDD workflow and persona system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -196,9 +196,9 @@ describe('MSSCI-12346: Legacy Install Cleanup', () => {
196
196
  assert.ok(result.fix, 'Should have fix function');
197
197
  // Execute the fix
198
198
  result.fix();
199
- // Verify the path was updated
199
+ // Verify the path was updated (fix now writes pf.sh hooks statusline)
200
200
  const updatedSettings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
201
- assert.ok(updatedSettings.statusLine.command.includes('.pennyfarthing/scripts/misc/statusline.sh'), 'Should update to proper path');
201
+ assert.ok(updatedSettings.statusLine.command.includes('.pennyfarthing/scripts/core/pf.sh hooks statusline'), 'Should update to pf.sh hooks statusline path');
202
202
  assert.strictEqual(updatedSettings.otherSetting, 'preserved', 'Should preserve other settings');
203
203
  });
204
204
  it('should detect multiple legacy statusline paths', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-legacy.test.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor-legacy.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor-legacy.test.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor-legacy.test.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,17 @@
1
+ import { readManifest } from '../utils/manifest.js';
1
2
  interface DoctorOptions {
2
3
  fix?: boolean;
3
4
  json?: boolean;
4
5
  quiet?: boolean;
5
6
  dogfood?: boolean;
7
+ category?: string;
8
+ listCategories?: boolean;
6
9
  }
10
+ /**
11
+ * Category-to-check-function mapping for --category filtering.
12
+ * Each category maps to the check functions that produce results in that group.
13
+ */
14
+ export declare const CATEGORY_CHECKS: Record<string, string[]>;
7
15
  export interface CheckResult {
8
16
  name: string;
9
17
  status: 'pass' | 'warn' | 'fail';
@@ -11,6 +19,55 @@ export interface CheckResult {
11
19
  fix?: () => void;
12
20
  }
13
21
  export declare function doctorCommand(options: DoctorOptions): Promise<void>;
22
+ export declare function checkInstallation(projectRoot: string, manifest: ReturnType<typeof readManifest>): CheckResult[];
23
+ export declare function checkCoreFiles(projectRoot: string, manifest: ReturnType<typeof readManifest>): CheckResult[];
24
+ /**
25
+ * Check commands and skills are properly copied (not symlinked) and up to date.
26
+ * Commands and skills are file copies since v11.3.0 to avoid node_modules drift.
27
+ */
28
+ export declare function checkCommandsAndSkills(projectRoot: string, _nodeModulesPath: string | null): CheckResult[];
29
+ /**
30
+ * Check basic user files only (project dir, sidecars, persona config, settings.local.json existence).
31
+ * Does NOT include the settings hook checks — use checkSettingsHooks() for those.
32
+ * Used by --category commands to separate user file checks from hook configuration checks.
33
+ */
34
+ export declare function checkUserFilesBasic(projectRoot: string): CheckResult[];
35
+ /**
36
+ * Check all settings hook configurations in settings.local.json.
37
+ * Returns results for all 9 hook checks (session-start, otel, auto-load-sm,
38
+ * stop, post-tool-use, benchmark-permissions, context-circuit-breaker,
39
+ * schema-validation, sprint-yaml-validation).
40
+ * Used by --category hooks for targeted hook configuration checking.
41
+ */
42
+ export declare function checkSettingsHooks(projectRoot: string): CheckResult[];
43
+ export declare function checkDirectories(projectRoot: string): CheckResult[];
44
+ export declare function checkHooks(projectRoot: string): CheckResult[];
45
+ /**
46
+ * Check git hooks in .git/hooks/ are up-to-date with package source.
47
+ *
48
+ * Supports two installation patterns:
49
+ *
50
+ * 1. **Dispatcher pattern** (current): `.git/hooks/{name}` is a generic dispatcher that
51
+ * runs scripts from `.git/hooks/{name}.d/`. The dispatcher is generated from
52
+ * `dispatcher-template.sh` and the actual hook implementation lives in the `.d/` dir.
53
+ *
54
+ * 2. **Direct-copy pattern** (legacy): `.git/hooks/{name}` is a direct copy of `{name}.sh`.
55
+ *
56
+ * For framework/orchestrator repos (has pennyfarthing-dist/), checks that hooks are
57
+ * symlinked rather than copied, since symlinks stay current automatically.
58
+ * Provides --fix to refresh stale hooks or replace copies with symlinks.
59
+ */
60
+ export declare function checkGitHooks(projectRoot: string, nodeModulesPath: string | null): CheckResult[];
61
+ /**
62
+ * Check Cyclist installation health (if installed as a workspace package)
63
+ * Detects node-pty spawn-helper permission issues that cause posix_spawnp failures
64
+ */
65
+ export declare function checkCyclist(projectRoot: string): CheckResult[];
66
+ /**
67
+ * Check if the pf CLI is installed and working.
68
+ * The pf CLI is required for agent commands (e.g., `pf agent start "dev"`).
69
+ */
70
+ export declare function checkPfCli(nodeModulesPath: string | null): CheckResult;
14
71
  /**
15
72
  * Check for legacy files that may shadow or conflict with current Pennyfarthing files.
16
73
  * Returns results with fix functions for --fix mode.
@@ -24,6 +81,12 @@ export declare function checkLegacyFiles(projectRoot: string): CheckResult[];
24
81
  * Returns result with fix function to update to canonical path if needed.
25
82
  */
26
83
  export declare function checkLegacyStatuslinePath(projectRoot: string): CheckResult;
84
+ /**
85
+ * Check if settings.local.json contains legacy .sh hook commands that should
86
+ * be migrated to `pf hooks` commands. The .sh scripts still work (they're shims)
87
+ * but `pf hooks` is the canonical path — faster, no shell indirection.
88
+ */
89
+ export declare function checkLegacyHookCommands(projectRoot: string): CheckResult;
27
90
  /**
28
91
  * Check file layout — validate files are at correct .pennyfarthing/ locations.
29
92
  * Flags old .claude/ locations with migration instructions.
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAwBA,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HzE;AAm+DD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA+JnE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAkF1E;AAqFD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAsIlE"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EACb,MAAM,sBAAsB,CAAC;AAc9B,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAQpD,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsKzE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,WAAW,EAAE,CAW/G;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,WAAW,EAAE,CAiE5G;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,EAAE,CA4I1G;AA0JD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAsDtE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA2BrE;AA8tCD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAkBnE;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAuD7D;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,EAAE,CA+NhG;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA8G/D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CAoBtE;AAoBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA+JnE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAkF1E;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CA4ExE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAsIlE"}
@@ -12,8 +12,35 @@ import { findNodeModulesPath } from '../utils/node-modules.js';
12
12
  import { ALL_SYMLINKS, CORE_AGENTS } from '../utils/constants.js';
13
13
  import { getPfVersion, installPfCli } from '../utils/python.js';
14
14
  import { LEGACY_HOOK_MIGRATIONS, migrateHookPaths } from '../utils/settings.js';
15
+ /**
16
+ * Category-to-check-function mapping for --category filtering.
17
+ * Each category maps to the check functions that produce results in that group.
18
+ */
19
+ export const CATEGORY_CHECKS = {
20
+ 'installation': ['checkInstallation', 'checkCoreFiles'],
21
+ 'commands': ['checkCommandsAndSkills', 'checkUserFilesBasic'],
22
+ 'hooks': ['checkSettingsHooks'],
23
+ 'scripts': ['checkHooks', 'checkGitHooks'],
24
+ 'layout': ['checkDirectories', 'checkFileLayout'],
25
+ 'legacy': ['checkLegacyFiles', 'checkLegacyStatuslinePath', 'checkLegacyHookCommands'],
26
+ 'tools': ['checkCyclist', 'checkPfCli'],
27
+ };
15
28
  export async function doctorCommand(options) {
16
29
  const projectRoot = process.cwd();
30
+ // Handle --list-categories
31
+ if (options.listCategories) {
32
+ console.log('Available check categories:');
33
+ for (const [name, checks] of Object.entries(CATEGORY_CHECKS)) {
34
+ console.log(` ${name.padEnd(14)} ${checks.join(', ')}`);
35
+ }
36
+ return;
37
+ }
38
+ // Validate --category if provided
39
+ if (options.category && !CATEGORY_CHECKS[options.category]) {
40
+ logger.error(`Unknown category: ${options.category}`);
41
+ logger.info(`Available categories: ${Object.keys(CATEGORY_CHECKS).join(', ')}`);
42
+ process.exit(1);
43
+ }
17
44
  // Handle dogfood mode - run checks for framework/orchestrator development
18
45
  if (options.dogfood) {
19
46
  const dogfoodScript = join(projectRoot, 'pennyfarthing-dist/scripts/misc/doctor-dogfood.sh');
@@ -45,20 +72,58 @@ export async function doctorCommand(options) {
45
72
  logger.newline();
46
73
  // Resolve node_modules path for checks that need it
47
74
  const nodeModulesPath = findNodeModulesPath(projectRoot);
48
- // Run checks
49
- results.push(...checkInstallation(projectRoot, manifest));
50
- results.push(...checkCoreFiles(projectRoot, manifest));
51
- results.push(...checkCommandsAndSkills(projectRoot, nodeModulesPath));
52
- results.push(...checkUserFiles(projectRoot));
53
- results.push(...checkDirectories(projectRoot));
54
- results.push(...checkHooks(projectRoot));
55
- results.push(...checkGitHooks(projectRoot, nodeModulesPath));
56
- results.push(...checkFileLayout(projectRoot));
57
- results.push(...checkLegacyFiles(projectRoot));
58
- results.push(checkLegacyStatuslinePath(projectRoot));
59
- results.push(checkLegacyHookCommands(projectRoot));
60
- results.push(...checkCyclist(projectRoot));
61
- results.push(checkPfCli(nodeModulesPath));
75
+ // Determine which checks to run
76
+ const activeChecks = options.category
77
+ ? new Set(CATEGORY_CHECKS[options.category])
78
+ : null; // null = run all
79
+ // Run checks — when category is specified, only run matching subset
80
+ if (activeChecks) {
81
+ // Category-filtered run
82
+ if (activeChecks.has('checkInstallation'))
83
+ results.push(...checkInstallation(projectRoot, manifest));
84
+ if (activeChecks.has('checkCoreFiles'))
85
+ results.push(...checkCoreFiles(projectRoot, manifest));
86
+ if (activeChecks.has('checkCommandsAndSkills'))
87
+ results.push(...checkCommandsAndSkills(projectRoot, nodeModulesPath));
88
+ if (activeChecks.has('checkUserFilesBasic'))
89
+ results.push(...checkUserFilesBasic(projectRoot));
90
+ if (activeChecks.has('checkSettingsHooks'))
91
+ results.push(...checkSettingsHooks(projectRoot));
92
+ if (activeChecks.has('checkDirectories'))
93
+ results.push(...checkDirectories(projectRoot));
94
+ if (activeChecks.has('checkHooks'))
95
+ results.push(...checkHooks(projectRoot));
96
+ if (activeChecks.has('checkGitHooks'))
97
+ results.push(...checkGitHooks(projectRoot, nodeModulesPath));
98
+ if (activeChecks.has('checkFileLayout'))
99
+ results.push(...checkFileLayout(projectRoot));
100
+ if (activeChecks.has('checkLegacyFiles'))
101
+ results.push(...checkLegacyFiles(projectRoot));
102
+ if (activeChecks.has('checkLegacyStatuslinePath'))
103
+ results.push(checkLegacyStatuslinePath(projectRoot));
104
+ if (activeChecks.has('checkLegacyHookCommands'))
105
+ results.push(checkLegacyHookCommands(projectRoot));
106
+ if (activeChecks.has('checkCyclist'))
107
+ results.push(...checkCyclist(projectRoot));
108
+ if (activeChecks.has('checkPfCli'))
109
+ results.push(checkPfCli(nodeModulesPath));
110
+ }
111
+ else {
112
+ // Full run — original behavior
113
+ results.push(...checkInstallation(projectRoot, manifest));
114
+ results.push(...checkCoreFiles(projectRoot, manifest));
115
+ results.push(...checkCommandsAndSkills(projectRoot, nodeModulesPath));
116
+ results.push(...checkUserFiles(projectRoot));
117
+ results.push(...checkDirectories(projectRoot));
118
+ results.push(...checkHooks(projectRoot));
119
+ results.push(...checkGitHooks(projectRoot, nodeModulesPath));
120
+ results.push(...checkFileLayout(projectRoot));
121
+ results.push(...checkLegacyFiles(projectRoot));
122
+ results.push(checkLegacyStatuslinePath(projectRoot));
123
+ results.push(checkLegacyHookCommands(projectRoot));
124
+ results.push(...checkCyclist(projectRoot));
125
+ results.push(checkPfCli(nodeModulesPath));
126
+ }
62
127
  // Output results
63
128
  if (options.json) {
64
129
  console.log(JSON.stringify(results, null, 2));
@@ -124,7 +189,7 @@ export async function doctorCommand(options) {
124
189
  process.exit(1);
125
190
  }
126
191
  }
127
- function checkInstallation(projectRoot, manifest) {
192
+ export function checkInstallation(projectRoot, manifest) {
128
193
  const results = [];
129
194
  // Check manifest exists
130
195
  results.push({
@@ -134,7 +199,7 @@ function checkInstallation(projectRoot, manifest) {
134
199
  });
135
200
  return results;
136
201
  }
137
- function checkCoreFiles(projectRoot, manifest) {
202
+ export function checkCoreFiles(projectRoot, manifest) {
138
203
  const results = [];
139
204
  const installationType = manifest?.installationType || 'copy';
140
205
  const nodeModulesPath = findNodeModulesPath(projectRoot);
@@ -196,7 +261,7 @@ function checkCoreFiles(projectRoot, manifest) {
196
261
  * Check commands and skills are properly copied (not symlinked) and up to date.
197
262
  * Commands and skills are file copies since v11.3.0 to avoid node_modules drift.
198
263
  */
199
- function checkCommandsAndSkills(projectRoot, _nodeModulesPath) {
264
+ export function checkCommandsAndSkills(projectRoot, _nodeModulesPath) {
200
265
  const results = [];
201
266
  // Use assetsPath for source resolution (correct pf-* prefix in dogfood)
202
267
  let assetsPath = null;
@@ -480,6 +545,91 @@ function checkSymlinks(projectRoot, nodeModulesPath) {
480
545
  }
481
546
  return results;
482
547
  }
548
+ /**
549
+ * Check basic user files only (project dir, sidecars, persona config, settings.local.json existence).
550
+ * Does NOT include the settings hook checks — use checkSettingsHooks() for those.
551
+ * Used by --category commands to separate user file checks from hook configuration checks.
552
+ */
553
+ export function checkUserFilesBasic(projectRoot) {
554
+ const results = [];
555
+ const manifest = readManifest(projectRoot);
556
+ const installationType = manifest?.installationType || 'copy';
557
+ // Check project directory
558
+ const projectDir = join(projectRoot, '.claude/project');
559
+ results.push({
560
+ name: 'project/directory',
561
+ status: pathExists(projectDir) ? 'pass' : 'warn',
562
+ detail: pathExists(projectDir) ? undefined : 'Run init to create'
563
+ });
564
+ // Check agent sidecars (now in .pennyfarthing/sidecars/)
565
+ const sidecarsDir = join(projectRoot, '.pennyfarthing/sidecars');
566
+ if (pathExists(sidecarsDir)) {
567
+ const existingSidecars = CORE_AGENTS.filter(a => pathExists(join(sidecarsDir, a)));
568
+ results.push({
569
+ name: 'project/sidecars',
570
+ status: existingSidecars.length > 0 ? 'pass' : 'warn',
571
+ detail: `${existingSidecars.length} agent sidecars configured`
572
+ });
573
+ }
574
+ // Check persona config at canonical location
575
+ const personaConfig = join(projectRoot, '.pennyfarthing/config.local.yaml');
576
+ results.push({
577
+ name: 'persona-config',
578
+ status: pathExists(personaConfig) ? 'pass' : 'warn',
579
+ detail: pathExists(personaConfig) ? undefined : 'No theme configured'
580
+ });
581
+ // Check settings.local.json exists (CRITICAL - registers hooks with Claude Code)
582
+ const settingsLocal = join(projectRoot, '.claude/settings.local.json');
583
+ if (!pathExists(settingsLocal)) {
584
+ results.push({
585
+ name: 'settings.local.json',
586
+ status: 'fail',
587
+ detail: 'Missing - hooks not registered with Claude Code!',
588
+ fix: () => {
589
+ createSettingsLocalJson(projectRoot, installationType);
590
+ }
591
+ });
592
+ }
593
+ else {
594
+ results.push({
595
+ name: 'settings.local.json',
596
+ status: 'pass',
597
+ detail: undefined
598
+ });
599
+ }
600
+ return results;
601
+ }
602
+ /**
603
+ * Check all settings hook configurations in settings.local.json.
604
+ * Returns results for all 9 hook checks (session-start, otel, auto-load-sm,
605
+ * stop, post-tool-use, benchmark-permissions, context-circuit-breaker,
606
+ * schema-validation, sprint-yaml-validation).
607
+ * Used by --category hooks for targeted hook configuration checking.
608
+ */
609
+ export function checkSettingsHooks(projectRoot) {
610
+ const results = [];
611
+ const manifest = readManifest(projectRoot);
612
+ const installationType = manifest?.installationType || 'copy';
613
+ const settingsLocal = join(projectRoot, '.claude/settings.local.json');
614
+ if (!pathExists(settingsLocal)) {
615
+ results.push({
616
+ name: 'settings.local.json',
617
+ status: 'fail',
618
+ detail: 'Missing - cannot check hook configuration'
619
+ });
620
+ return results;
621
+ }
622
+ results.push(checkSessionStartHooks(projectRoot, installationType));
623
+ results.push(checkOtelAutoStart(projectRoot, installationType));
624
+ results.push(checkAutoLoadSmHook(projectRoot));
625
+ results.push(checkStopHook(projectRoot, installationType));
626
+ results.push(checkPostToolUseHook(projectRoot, installationType));
627
+ results.push(checkBenchmarkPermissions(projectRoot));
628
+ results.push(checkContextCircuitBreaker(projectRoot, installationType));
629
+ results.push(checkSchemaValidationHook(projectRoot, installationType));
630
+ results.push(checkSprintYamlValidationHook(projectRoot, installationType));
631
+ return results;
632
+ }
483
633
  function checkUserFiles(projectRoot) {
484
634
  const results = [];
485
635
  // Detect installation type from manifest
@@ -1586,7 +1736,7 @@ function createSettingsLocalJson(projectRoot, _installationType) {
1586
1736
  ensureDirSync(join(projectRoot, '.claude'));
1587
1737
  writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
1588
1738
  }
1589
- function checkDirectories(projectRoot) {
1739
+ export function checkDirectories(projectRoot) {
1590
1740
  const results = [];
1591
1741
  const dirs = [
1592
1742
  { path: 'sprint', name: 'dir/sprint' },
@@ -1602,7 +1752,7 @@ function checkDirectories(projectRoot) {
1602
1752
  }
1603
1753
  return results;
1604
1754
  }
1605
- function checkHooks(projectRoot) {
1755
+ export function checkHooks(projectRoot) {
1606
1756
  const results = [];
1607
1757
  // Detect installation type from manifest
1608
1758
  const manifest = readManifest(projectRoot);
@@ -1652,14 +1802,28 @@ function checkHooks(projectRoot) {
1652
1802
  }
1653
1803
  return results;
1654
1804
  }
1805
+ /**
1806
+ * Render the dispatcher template by substituting __HOOK_NAME__ with the actual hook name.
1807
+ */
1808
+ function renderDispatcherTemplate(template, hookName) {
1809
+ return template.replace(/__HOOK_NAME__/g, hookName);
1810
+ }
1655
1811
  /**
1656
1812
  * Check git hooks in .git/hooks/ are up-to-date with package source.
1657
- * Detects stale copies that were installed by `pennyfarthing init` but never refreshed.
1813
+ *
1814
+ * Supports two installation patterns:
1815
+ *
1816
+ * 1. **Dispatcher pattern** (current): `.git/hooks/{name}` is a generic dispatcher that
1817
+ * runs scripts from `.git/hooks/{name}.d/`. The dispatcher is generated from
1818
+ * `dispatcher-template.sh` and the actual hook implementation lives in the `.d/` dir.
1819
+ *
1820
+ * 2. **Direct-copy pattern** (legacy): `.git/hooks/{name}` is a direct copy of `{name}.sh`.
1821
+ *
1658
1822
  * For framework/orchestrator repos (has pennyfarthing-dist/), checks that hooks are
1659
1823
  * symlinked rather than copied, since symlinks stay current automatically.
1660
1824
  * Provides --fix to refresh stale hooks or replace copies with symlinks.
1661
1825
  */
1662
- function checkGitHooks(projectRoot, nodeModulesPath) {
1826
+ export function checkGitHooks(projectRoot, nodeModulesPath) {
1663
1827
  const results = [];
1664
1828
  // Use git rev-parse to find the actual git dir (handles worktrees where .git is a file)
1665
1829
  const gitDirResult = spawnSync('git', ['rev-parse', '--git-dir'], { cwd: projectRoot, encoding: 'utf8' });
@@ -1679,17 +1843,23 @@ function checkGitHooks(projectRoot, nodeModulesPath) {
1679
1843
  if (!nodeModulesPath && !frameworkHooksDir) {
1680
1844
  return results;
1681
1845
  }
1846
+ // Resolve the hooks source directory
1847
+ const hooksSourceDir = frameworkHooksDir ?? join(nodeModulesPath, 'scripts/hooks');
1848
+ // Load dispatcher template for comparison (used by dispatcher pattern detection)
1849
+ const dispatcherTemplatePath = join(hooksSourceDir, 'dispatcher-template.sh');
1850
+ const hasDispatcherTemplate = pathExists(dispatcherTemplatePath);
1851
+ const dispatcherTemplate = hasDispatcherTemplate
1852
+ ? readFileSync(dispatcherTemplatePath, 'utf8')
1853
+ : null;
1682
1854
  const hooks = [
1683
1855
  { source: 'pre-commit.sh', dest: 'pre-commit', marker: 'pennyfarthing' },
1684
1856
  { source: 'pre-push.sh', dest: 'pre-push', marker: 'pennyfarthing' },
1685
1857
  { source: 'post-merge.sh', dest: 'post-merge', marker: 'pennyfarthing' },
1686
1858
  ];
1687
1859
  for (const hook of hooks) {
1688
- // Prefer framework source (pennyfarthing-dist/) over node_modules
1689
- const sourcePath = frameworkHooksDir
1690
- ? join(frameworkHooksDir, hook.source)
1691
- : join(nodeModulesPath, 'scripts/hooks', hook.source);
1860
+ const sourcePath = join(hooksSourceDir, hook.source);
1692
1861
  const destPath = join(gitHooksDir, hook.dest);
1862
+ const dDir = join(gitHooksDir, `${hook.dest}.d`);
1693
1863
  if (!pathExists(sourcePath)) {
1694
1864
  continue;
1695
1865
  }
@@ -1778,23 +1948,90 @@ function checkGitHooks(projectRoot, nodeModulesPath) {
1778
1948
  });
1779
1949
  continue;
1780
1950
  }
1781
- const sourceContent = readFileSync(sourcePath, 'utf8');
1782
- if (existingContent === sourceContent) {
1783
- results.push({
1784
- name: `git-hook/${hook.dest}`,
1785
- status: 'pass',
1786
- detail: undefined
1787
- });
1951
+ // Detect dispatcher pattern: the installed hook is a dispatcher (from dispatcher-template.sh)
1952
+ // and the actual implementation lives in .git/hooks/{name}.d/
1953
+ const isDispatcherPattern = dispatcherTemplate
1954
+ && existingContent.includes('pennyfarthing-dispatcher')
1955
+ && pathExists(dDir);
1956
+ if (isDispatcherPattern) {
1957
+ // --- Dispatcher pattern: check dispatcher + .d/ scripts separately ---
1958
+ // 1. Check the dispatcher itself against the rendered template
1959
+ const expectedDispatcher = renderDispatcherTemplate(dispatcherTemplate, hook.dest);
1960
+ if (existingContent !== expectedDispatcher) {
1961
+ results.push({
1962
+ name: `git-hook/${hook.dest}`,
1963
+ status: 'warn',
1964
+ detail: 'Stale dispatcher — content differs from template',
1965
+ fix: () => {
1966
+ writeFileSync(destPath, expectedDispatcher, { mode: 0o755 });
1967
+ }
1968
+ });
1969
+ }
1970
+ else {
1971
+ results.push({
1972
+ name: `git-hook/${hook.dest}`,
1973
+ status: 'pass',
1974
+ detail: 'Dispatcher'
1975
+ });
1976
+ }
1977
+ // 2. Check the .d/ script against its source
1978
+ const dScripts = readdirSync(dDir).filter(f => f.includes('pennyfarthing'));
1979
+ if (dScripts.length === 0) {
1980
+ results.push({
1981
+ name: `git-hook/${hook.dest}.d`,
1982
+ status: 'warn',
1983
+ detail: 'No pennyfarthing script in .d/ directory',
1984
+ fix: () => {
1985
+ const sourceContent = readFileSync(sourcePath, 'utf8');
1986
+ const dScriptPath = join(dDir, `10-pennyfarthing-${hook.dest}.sh`);
1987
+ writeFileSync(dScriptPath, sourceContent, { mode: 0o755 });
1988
+ }
1989
+ });
1990
+ }
1991
+ else {
1992
+ // Compare the first matching .d/ script against the source
1993
+ const dScriptPath = join(dDir, dScripts[0]);
1994
+ const dScriptContent = readFileSync(dScriptPath, 'utf8');
1995
+ const sourceContent = readFileSync(sourcePath, 'utf8');
1996
+ if (dScriptContent === sourceContent) {
1997
+ results.push({
1998
+ name: `git-hook/${hook.dest}.d`,
1999
+ status: 'pass',
2000
+ detail: undefined
2001
+ });
2002
+ }
2003
+ else {
2004
+ results.push({
2005
+ name: `git-hook/${hook.dest}.d`,
2006
+ status: 'warn',
2007
+ detail: 'Stale — content differs from package',
2008
+ fix: () => {
2009
+ writeFileSync(dScriptPath, sourceContent, { mode: 0o755 });
2010
+ }
2011
+ });
2012
+ }
2013
+ }
1788
2014
  }
1789
2015
  else {
1790
- results.push({
1791
- name: `git-hook/${hook.dest}`,
1792
- status: 'warn',
1793
- detail: 'Stale — content differs from package',
1794
- fix: () => {
1795
- writeFileSync(destPath, sourceContent, { mode: 0o755 });
1796
- }
1797
- });
2016
+ // --- Legacy direct-copy pattern: compare hook directly against source ---
2017
+ const sourceContent = readFileSync(sourcePath, 'utf8');
2018
+ if (existingContent === sourceContent) {
2019
+ results.push({
2020
+ name: `git-hook/${hook.dest}`,
2021
+ status: 'pass',
2022
+ detail: undefined
2023
+ });
2024
+ }
2025
+ else {
2026
+ results.push({
2027
+ name: `git-hook/${hook.dest}`,
2028
+ status: 'warn',
2029
+ detail: 'Stale — content differs from package',
2030
+ fix: () => {
2031
+ writeFileSync(destPath, sourceContent, { mode: 0o755 });
2032
+ }
2033
+ });
2034
+ }
1798
2035
  }
1799
2036
  }
1800
2037
  return results;
@@ -1803,7 +2040,7 @@ function checkGitHooks(projectRoot, nodeModulesPath) {
1803
2040
  * Check Cyclist installation health (if installed as a workspace package)
1804
2041
  * Detects node-pty spawn-helper permission issues that cause posix_spawnp failures
1805
2042
  */
1806
- function checkCyclist(projectRoot) {
2043
+ export function checkCyclist(projectRoot) {
1807
2044
  const results = [];
1808
2045
  // Detect Cyclist package — check common locations
1809
2046
  const cyclistLocations = [
@@ -1905,7 +2142,7 @@ function checkCyclist(projectRoot) {
1905
2142
  * Check if the pf CLI is installed and working.
1906
2143
  * The pf CLI is required for agent commands (e.g., `pf agent start "dev"`).
1907
2144
  */
1908
- function checkPfCli(nodeModulesPath) {
2145
+ export function checkPfCli(nodeModulesPath) {
1909
2146
  const version = getPfVersion();
1910
2147
  if (version) {
1911
2148
  return {
@@ -2182,7 +2419,7 @@ export function checkLegacyStatuslinePath(projectRoot) {
2182
2419
  * be migrated to `pf hooks` commands. The .sh scripts still work (they're shims)
2183
2420
  * but `pf hooks` is the canonical path — faster, no shell indirection.
2184
2421
  */
2185
- function checkLegacyHookCommands(projectRoot) {
2422
+ export function checkLegacyHookCommands(projectRoot) {
2186
2423
  const settingsPath = join(projectRoot, '.claude/settings.local.json');
2187
2424
  if (!pathExists(settingsPath)) {
2188
2425
  return { name: 'legacy/hook-commands', status: 'pass', detail: 'No settings file' };