@pennyfarthing/core 10.4.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/package.json +16 -14
- package/packages/core/dist/benchmark/benchmark-integration.d.ts +182 -0
- package/packages/core/dist/benchmark/benchmark-integration.d.ts.map +1 -0
- package/packages/core/dist/benchmark/benchmark-integration.js +710 -0
- package/packages/core/dist/benchmark/benchmark-integration.js.map +1 -0
- package/packages/core/dist/benchmark/benchmark-integration.test.d.ts +6 -0
- package/packages/core/dist/benchmark/benchmark-integration.test.d.ts.map +1 -0
- package/packages/core/dist/benchmark/benchmark-integration.test.js +41 -0
- package/packages/core/dist/benchmark/benchmark-integration.test.js.map +1 -0
- package/packages/core/dist/benchmark/index.d.ts +3 -0
- package/packages/core/dist/benchmark/index.d.ts.map +1 -0
- package/packages/core/dist/benchmark/index.js +5 -0
- package/packages/core/dist/benchmark/index.js.map +1 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.d.ts +150 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.d.ts.map +1 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.js +547 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.js.map +1 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.test.d.ts +6 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.test.d.ts.map +1 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.test.js +35 -0
- package/packages/core/dist/benchmark/job-fair-aggregator.test.js.map +1 -0
- package/packages/core/dist/cli/commands/hook-chaining.test.d.ts +17 -0
- package/packages/core/dist/cli/commands/hook-chaining.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/hook-chaining.test.js +386 -0
- package/packages/core/dist/cli/commands/hook-chaining.test.js.map +1 -0
- package/packages/core/dist/cli/commands/init.d.ts +6 -1
- package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/init.js +83 -30
- package/packages/core/dist/cli/commands/init.js.map +1 -1
- package/packages/core/dist/cli/commands/uninstall.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/uninstall.js +20 -3
- package/packages/core/dist/cli/commands/uninstall.js.map +1 -1
- package/packages/core/dist/cli/commands/uninstall.test.d.ts +8 -0
- package/packages/core/dist/cli/commands/uninstall.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/uninstall.test.js +120 -0
- package/packages/core/dist/cli/commands/uninstall.test.js.map +1 -0
- package/packages/core/dist/cli/commands/update.js +4 -4
- package/packages/core/dist/cli/commands/update.js.map +1 -1
- package/packages/core/dist/cli/cyclist-migration.test.js +2 -1
- package/packages/core/dist/cli/cyclist-migration.test.js.map +1 -1
- package/packages/core/dist/cli/ocean-profiles.test.js +5 -4
- package/packages/core/dist/cli/ocean-profiles.test.js.map +1 -1
- package/packages/core/dist/cli/theme-maker.test.js +5 -4
- package/packages/core/dist/cli/theme-maker.test.js.map +1 -1
- package/packages/core/dist/cli/utils/008-sprint-shard-migration.test.d.ts +15 -0
- package/packages/core/dist/cli/utils/008-sprint-shard-migration.test.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/008-sprint-shard-migration.test.js +295 -0
- package/packages/core/dist/cli/utils/008-sprint-shard-migration.test.js.map +1 -0
- package/packages/core/dist/cli/utils/settings-consolidation.test.js +26 -0
- package/packages/core/dist/cli/utils/settings-consolidation.test.js.map +1 -1
- package/packages/core/dist/cli/utils/settings-merge.d.ts +128 -0
- package/packages/core/dist/cli/utils/settings-merge.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/settings-merge.js +303 -0
- package/packages/core/dist/cli/utils/settings-merge.js.map +1 -0
- package/packages/core/dist/cli/utils/settings-merge.test.d.ts +15 -0
- package/packages/core/dist/cli/utils/settings-merge.test.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/settings-merge.test.js +781 -0
- package/packages/core/dist/cli/utils/settings-merge.test.js.map +1 -0
- package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/settings.js +3 -0
- package/packages/core/dist/cli/utils/settings.js.map +1 -1
- package/packages/core/dist/cli/utils/symlinks.d.ts +6 -16
- package/packages/core/dist/cli/utils/symlinks.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/symlinks.js +100 -171
- package/packages/core/dist/cli/utils/symlinks.js.map +1 -1
- package/packages/core/dist/cli/utils/symlinks.test.d.ts +10 -0
- package/packages/core/dist/cli/utils/symlinks.test.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/symlinks.test.js +266 -0
- package/packages/core/dist/cli/utils/symlinks.test.js.map +1 -0
- package/packages/core/dist/cli/utils/themes.js +1 -1
- package/packages/core/dist/cli/workspace.test.js +2 -5
- package/packages/core/dist/cli/workspace.test.js.map +1 -1
- package/packages/core/dist/consolidation.test.d.ts +11 -0
- package/packages/core/dist/consolidation.test.d.ts.map +1 -0
- package/packages/core/dist/consolidation.test.js +249 -0
- package/packages/core/dist/consolidation.test.js.map +1 -0
- package/packages/core/dist/index.d.ts +2 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +4 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/plugins/plugin-discovery.js +1 -1
- package/packages/core/dist/plugins/plugin-discovery.js.map +1 -1
- package/packages/core/dist/plugins/plugin-discovery.test.d.ts +1 -1
- package/packages/core/dist/plugins/plugin-discovery.test.js +47 -36
- package/packages/core/dist/plugins/plugin-discovery.test.js.map +1 -1
- package/packages/core/dist/public/css/react.css +1 -0
- package/packages/core/dist/public/js/react/react.js +82 -0
- package/packages/core/dist/scripts/generate-report.test.js +2 -2
- package/packages/core/dist/scripts/generate-spider-report.test.js +2 -2
- package/packages/core/dist/scripts/generate-spider.test.js +2 -1
- package/packages/core/dist/scripts/generate-spider.test.js.map +1 -1
- package/packages/core/dist/server/agent-context.d.ts +5 -0
- package/packages/core/dist/server/agent-context.d.ts.map +1 -0
- package/packages/core/dist/server/agent-context.js +5 -0
- package/packages/core/dist/server/agent-context.js.map +1 -0
- package/packages/core/dist/server/agent-evaluation.d.ts +17 -0
- package/packages/core/dist/server/agent-evaluation.d.ts.map +1 -0
- package/packages/core/dist/server/agent-evaluation.js +15 -0
- package/packages/core/dist/server/agent-evaluation.js.map +1 -0
- package/packages/core/dist/server/api/agent-load.d.ts +3 -0
- package/packages/core/dist/server/api/agent-load.d.ts.map +1 -0
- package/packages/core/dist/server/api/agent-load.js +19 -0
- package/packages/core/dist/server/api/agent-load.js.map +1 -0
- package/packages/core/dist/server/api/audit-log.d.ts +3 -0
- package/packages/core/dist/server/api/audit-log.d.ts.map +1 -0
- package/packages/core/dist/server/api/audit-log.js +31 -0
- package/packages/core/dist/server/api/audit-log.js.map +1 -0
- package/packages/core/dist/server/api/background-tasks.d.ts +27 -0
- package/packages/core/dist/server/api/background-tasks.d.ts.map +1 -0
- package/packages/core/dist/server/api/background-tasks.js +56 -0
- package/packages/core/dist/server/api/background-tasks.js.map +1 -0
- package/packages/core/dist/server/api/bell.d.ts +19 -0
- package/packages/core/dist/server/api/bell.d.ts.map +1 -0
- package/packages/core/dist/server/api/bell.js +34 -0
- package/packages/core/dist/server/api/bell.js.map +1 -0
- package/packages/core/dist/server/api/code-markers.d.ts +9 -0
- package/packages/core/dist/server/api/code-markers.d.ts.map +1 -0
- package/packages/core/dist/server/api/code-markers.js +62 -0
- package/packages/core/dist/server/api/code-markers.js.map +1 -0
- package/packages/core/dist/server/api/complexity.d.ts +3 -0
- package/packages/core/dist/server/api/complexity.d.ts.map +1 -0
- package/packages/core/dist/server/api/complexity.js +47 -0
- package/packages/core/dist/server/api/complexity.js.map +1 -0
- package/packages/core/dist/server/api/context.d.ts +38 -0
- package/packages/core/dist/server/api/context.d.ts.map +1 -0
- package/packages/core/dist/server/api/context.js +144 -0
- package/packages/core/dist/server/api/context.js.map +1 -0
- package/packages/core/dist/server/api/dead-code.d.ts +3 -0
- package/packages/core/dist/server/api/dead-code.d.ts.map +1 -0
- package/packages/core/dist/server/api/dead-code.js +70 -0
- package/packages/core/dist/server/api/dead-code.js.map +1 -0
- package/packages/core/dist/server/api/dependencies.d.ts +3 -0
- package/packages/core/dist/server/api/dependencies.d.ts.map +1 -0
- package/packages/core/dist/server/api/dependencies.js +43 -0
- package/packages/core/dist/server/api/dependencies.js.map +1 -0
- package/packages/core/dist/server/api/evaluation.d.ts +3 -0
- package/packages/core/dist/server/api/evaluation.d.ts.map +1 -0
- package/packages/core/dist/server/api/evaluation.js +33 -0
- package/packages/core/dist/server/api/evaluation.js.map +1 -0
- package/packages/core/dist/server/api/file-browser.d.ts +9 -0
- package/packages/core/dist/server/api/file-browser.d.ts.map +1 -0
- package/packages/core/dist/server/api/file-browser.js +133 -0
- package/packages/core/dist/server/api/file-browser.js.map +1 -0
- package/packages/core/dist/server/api/git-fetch-cooldown.test.d.ts +10 -0
- package/packages/core/dist/server/api/git-fetch-cooldown.test.d.ts.map +1 -0
- package/packages/core/dist/server/api/git-fetch-cooldown.test.js +30 -0
- package/packages/core/dist/server/api/git-fetch-cooldown.test.js.map +1 -0
- package/packages/core/dist/server/api/git.d.ts +55 -0
- package/packages/core/dist/server/api/git.d.ts.map +1 -0
- package/packages/core/dist/server/api/git.js +382 -0
- package/packages/core/dist/server/api/git.js.map +1 -0
- package/packages/core/dist/server/api/health-score.d.ts +3 -0
- package/packages/core/dist/server/api/health-score.d.ts.map +1 -0
- package/packages/core/dist/server/api/health-score.js +47 -0
- package/packages/core/dist/server/api/health-score.js.map +1 -0
- package/packages/core/dist/server/api/hook-request.d.ts +41 -0
- package/packages/core/dist/server/api/hook-request.d.ts.map +1 -0
- package/packages/core/dist/server/api/hook-request.js +278 -0
- package/packages/core/dist/server/api/hook-request.js.map +1 -0
- package/packages/core/dist/server/api/hotspots.d.ts +3 -0
- package/packages/core/dist/server/api/hotspots.d.ts.map +1 -0
- package/packages/core/dist/server/api/hotspots.js +62 -0
- package/packages/core/dist/server/api/hotspots.js.map +1 -0
- package/packages/core/dist/server/api/identity.d.ts +17 -0
- package/packages/core/dist/server/api/identity.d.ts.map +1 -0
- package/packages/core/dist/server/api/identity.js +79 -0
- package/packages/core/dist/server/api/identity.js.map +1 -0
- package/packages/core/dist/server/api/index.d.ts +36 -0
- package/packages/core/dist/server/api/index.d.ts.map +1 -0
- package/packages/core/dist/server/api/index.js +47 -0
- package/packages/core/dist/server/api/index.js.map +1 -0
- package/packages/core/dist/server/api/mode.d.ts +24 -0
- package/packages/core/dist/server/api/mode.d.ts.map +1 -0
- package/packages/core/dist/server/api/mode.js +40 -0
- package/packages/core/dist/server/api/mode.js.map +1 -0
- package/packages/core/dist/server/api/otlp.d.ts +3 -0
- package/packages/core/dist/server/api/otlp.d.ts.map +1 -0
- package/packages/core/dist/server/api/otlp.js +40 -0
- package/packages/core/dist/server/api/otlp.js.map +1 -0
- package/packages/core/dist/server/api/permissions.d.ts +16 -0
- package/packages/core/dist/server/api/permissions.d.ts.map +1 -0
- package/packages/core/dist/server/api/permissions.js +67 -0
- package/packages/core/dist/server/api/permissions.js.map +1 -0
- package/packages/core/dist/server/api/persona.d.ts +9 -0
- package/packages/core/dist/server/api/persona.d.ts.map +1 -0
- package/packages/core/dist/server/api/persona.js +68 -0
- package/packages/core/dist/server/api/persona.js.map +1 -0
- package/packages/core/dist/server/api/portrait.d.ts +6 -0
- package/packages/core/dist/server/api/portrait.d.ts.map +1 -0
- package/packages/core/dist/server/api/portrait.js +28 -0
- package/packages/core/dist/server/api/portrait.js.map +1 -0
- package/packages/core/dist/server/api/settings.d.ts +14 -0
- package/packages/core/dist/server/api/settings.d.ts.map +1 -0
- package/packages/core/dist/server/api/settings.js +68 -0
- package/packages/core/dist/server/api/settings.js.map +1 -0
- package/packages/core/dist/server/api/spans.d.ts +3 -0
- package/packages/core/dist/server/api/spans.d.ts.map +1 -0
- package/packages/core/dist/server/api/spans.js +33 -0
- package/packages/core/dist/server/api/spans.js.map +1 -0
- package/packages/core/dist/server/api/stats.d.ts +13 -0
- package/packages/core/dist/server/api/stats.d.ts.map +1 -0
- package/packages/core/dist/server/api/stats.js +85 -0
- package/packages/core/dist/server/api/stats.js.map +1 -0
- package/packages/core/dist/server/api/story.d.ts +3 -0
- package/packages/core/dist/server/api/story.d.ts.map +1 -0
- package/packages/core/dist/server/api/story.js +15 -0
- package/packages/core/dist/server/api/story.js.map +1 -0
- package/packages/core/dist/server/api/telemetry.d.ts +3 -0
- package/packages/core/dist/server/api/telemetry.d.ts.map +1 -0
- package/packages/core/dist/server/api/telemetry.js +30 -0
- package/packages/core/dist/server/api/telemetry.js.map +1 -0
- package/packages/core/dist/server/api/theme-agents.d.ts +10 -0
- package/packages/core/dist/server/api/theme-agents.d.ts.map +1 -0
- package/packages/core/dist/server/api/theme-agents.js +39 -0
- package/packages/core/dist/server/api/theme-agents.js.map +1 -0
- package/packages/core/dist/server/api/todos.d.ts +33 -0
- package/packages/core/dist/server/api/todos.d.ts.map +1 -0
- package/packages/core/dist/server/api/todos.js +44 -0
- package/packages/core/dist/server/api/todos.js.map +1 -0
- package/packages/core/dist/server/api/token-stats.d.ts +8 -0
- package/packages/core/dist/server/api/token-stats.d.ts.map +1 -0
- package/packages/core/dist/server/api/token-stats.js +36 -0
- package/packages/core/dist/server/api/token-stats.js.map +1 -0
- package/packages/core/dist/server/api/welcome.d.ts +22 -0
- package/packages/core/dist/server/api/welcome.d.ts.map +1 -0
- package/packages/core/dist/server/api/welcome.js +35 -0
- package/packages/core/dist/server/api/welcome.js.map +1 -0
- package/packages/core/dist/server/bell-mode.d.ts +7 -0
- package/packages/core/dist/server/bell-mode.d.ts.map +1 -0
- package/packages/core/dist/server/bell-mode.js +7 -0
- package/packages/core/dist/server/bell-mode.js.map +1 -0
- package/packages/core/dist/server/dangerous-path.d.ts +36 -0
- package/packages/core/dist/server/dangerous-path.d.ts.map +1 -0
- package/packages/core/dist/server/dangerous-path.js +159 -0
- package/packages/core/dist/server/dangerous-path.js.map +1 -0
- package/packages/core/dist/server/enriched-span-exporter.d.ts +17 -0
- package/packages/core/dist/server/enriched-span-exporter.d.ts.map +1 -0
- package/packages/core/dist/server/enriched-span-exporter.js +12 -0
- package/packages/core/dist/server/enriched-span-exporter.js.map +1 -0
- package/packages/core/dist/server/env.d.ts +6 -0
- package/packages/core/dist/server/env.d.ts.map +1 -0
- package/packages/core/dist/server/env.js +10 -0
- package/packages/core/dist/server/env.js.map +1 -0
- package/packages/core/dist/server/file-browser.d.ts +17 -0
- package/packages/core/dist/server/file-browser.d.ts.map +1 -0
- package/packages/core/dist/server/file-browser.js +11 -0
- package/packages/core/dist/server/file-browser.js.map +1 -0
- package/packages/core/dist/server/otlp-receiver.d.ts +87 -0
- package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -0
- package/packages/core/dist/server/otlp-receiver.js +106 -0
- package/packages/core/dist/server/otlp-receiver.js.map +1 -0
- package/packages/core/dist/server/parser.d.ts +11 -0
- package/packages/core/dist/server/parser.d.ts.map +1 -0
- package/packages/core/dist/server/parser.js +6 -0
- package/packages/core/dist/server/parser.js.map +1 -0
- package/packages/core/dist/server/paths.d.ts +37 -0
- package/packages/core/dist/server/paths.d.ts.map +1 -0
- package/packages/core/dist/server/paths.js +227 -0
- package/packages/core/dist/server/paths.js.map +1 -0
- package/packages/core/dist/server/pennyfarthing.d.ts +56 -0
- package/packages/core/dist/server/pennyfarthing.d.ts.map +1 -0
- package/packages/core/dist/server/pennyfarthing.js +356 -0
- package/packages/core/dist/server/pennyfarthing.js.map +1 -0
- package/packages/core/dist/server/plugin-loader.d.ts +22 -0
- package/packages/core/dist/server/plugin-loader.d.ts.map +1 -0
- package/packages/core/dist/server/plugin-loader.js +67 -0
- package/packages/core/dist/server/plugin-loader.js.map +1 -0
- package/packages/core/dist/server/prime.d.ts +12 -0
- package/packages/core/dist/server/prime.d.ts.map +1 -0
- package/packages/core/dist/server/prime.js +8 -0
- package/packages/core/dist/server/prime.js.map +1 -0
- package/packages/core/dist/server/server.d.ts +47 -0
- package/packages/core/dist/server/server.d.ts.map +1 -0
- package/packages/core/dist/server/server.js +353 -0
- package/packages/core/dist/server/server.js.map +1 -0
- package/packages/core/dist/server/server.test.d.ts +26 -0
- package/packages/core/dist/server/server.test.d.ts.map +1 -0
- package/packages/core/dist/server/server.test.js +447 -0
- package/packages/core/dist/server/server.test.js.map +1 -0
- package/packages/core/dist/server/settings-store.d.ts +195 -0
- package/packages/core/dist/server/settings-store.d.ts.map +1 -0
- package/packages/core/dist/server/settings-store.js +398 -0
- package/packages/core/dist/server/settings-store.js.map +1 -0
- package/packages/core/dist/server/settings.d.ts +136 -0
- package/packages/core/dist/server/settings.d.ts.map +1 -0
- package/packages/core/dist/server/settings.js +417 -0
- package/packages/core/dist/server/settings.js.map +1 -0
- package/packages/core/dist/server/span-hierarchy.d.ts +5 -0
- package/packages/core/dist/server/span-hierarchy.d.ts.map +1 -0
- package/packages/core/dist/server/span-hierarchy.js +5 -0
- package/packages/core/dist/server/span-hierarchy.js.map +1 -0
- package/packages/core/dist/server/story-context.d.ts +5 -0
- package/packages/core/dist/server/story-context.d.ts.map +1 -0
- package/packages/core/dist/server/story-context.js +5 -0
- package/packages/core/dist/server/story-context.js.map +1 -0
- package/packages/core/dist/server/story-parser.d.ts +74 -0
- package/packages/core/dist/server/story-parser.d.ts.map +1 -0
- package/packages/core/dist/server/story-parser.js +748 -0
- package/packages/core/dist/server/story-parser.js.map +1 -0
- package/packages/core/dist/server/tdd-metrics.d.ts +5 -0
- package/packages/core/dist/server/tdd-metrics.d.ts.map +1 -0
- package/packages/core/dist/server/tdd-metrics.js +5 -0
- package/packages/core/dist/server/tdd-metrics.js.map +1 -0
- package/packages/core/dist/server/ui-build.test.d.ts +19 -0
- package/packages/core/dist/server/ui-build.test.d.ts.map +1 -0
- package/packages/core/dist/server/ui-build.test.js +152 -0
- package/packages/core/dist/server/ui-build.test.js.map +1 -0
- package/packages/core/dist/server/websocket.d.ts +7 -0
- package/packages/core/dist/server/websocket.d.ts.map +1 -0
- package/packages/core/dist/server/websocket.js +8 -0
- package/packages/core/dist/server/websocket.js.map +1 -0
- package/packages/core/dist/shared/browser.d.ts +6 -0
- package/packages/core/dist/shared/browser.d.ts.map +1 -0
- package/packages/core/dist/shared/browser.js +8 -0
- package/packages/core/dist/shared/browser.js.map +1 -0
- package/packages/core/dist/shared/generate-skill-docs.d.ts +35 -0
- package/packages/core/dist/shared/generate-skill-docs.d.ts.map +1 -0
- package/packages/core/dist/shared/generate-skill-docs.js +442 -0
- package/packages/core/dist/shared/generate-skill-docs.js.map +1 -0
- package/packages/core/dist/shared/generate-skill-docs.test.d.ts +13 -0
- package/packages/core/dist/shared/generate-skill-docs.test.d.ts.map +1 -0
- package/packages/core/dist/shared/generate-skill-docs.test.js +519 -0
- package/packages/core/dist/shared/generate-skill-docs.test.js.map +1 -0
- package/packages/core/dist/shared/index.d.ts +11 -0
- package/packages/core/dist/shared/index.d.ts.map +1 -0
- package/packages/core/dist/shared/index.js +13 -0
- package/packages/core/dist/shared/index.js.map +1 -0
- package/packages/core/dist/shared/marker/constants.d.ts +39 -0
- package/packages/core/dist/shared/marker/constants.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/constants.js +46 -0
- package/packages/core/dist/shared/marker/constants.js.map +1 -0
- package/packages/core/dist/shared/marker/continue.test.d.ts +12 -0
- package/packages/core/dist/shared/marker/continue.test.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/continue.test.js +76 -0
- package/packages/core/dist/shared/marker/continue.test.js.map +1 -0
- package/packages/core/dist/shared/marker/detect.d.ts +25 -0
- package/packages/core/dist/shared/marker/detect.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/detect.js +53 -0
- package/packages/core/dist/shared/marker/detect.js.map +1 -0
- package/packages/core/dist/shared/marker/detect.test.d.ts +10 -0
- package/packages/core/dist/shared/marker/detect.test.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/detect.test.js +418 -0
- package/packages/core/dist/shared/marker/detect.test.js.map +1 -0
- package/packages/core/dist/shared/marker/index.d.ts +14 -0
- package/packages/core/dist/shared/marker/index.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/index.js +15 -0
- package/packages/core/dist/shared/marker/index.js.map +1 -0
- package/packages/core/dist/shared/marker/strip.d.ts +26 -0
- package/packages/core/dist/shared/marker/strip.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/strip.js +39 -0
- package/packages/core/dist/shared/marker/strip.js.map +1 -0
- package/packages/core/dist/shared/marker/types.d.ts +23 -0
- package/packages/core/dist/shared/marker/types.d.ts.map +1 -0
- package/packages/core/dist/shared/marker/types.js +7 -0
- package/packages/core/dist/shared/marker/types.js.map +1 -0
- package/packages/core/dist/shared/migrate-theme-schema.test.d.ts +8 -0
- package/packages/core/dist/shared/migrate-theme-schema.test.d.ts.map +1 -0
- package/packages/core/dist/shared/migrate-theme-schema.test.js +100 -0
- package/packages/core/dist/shared/migrate-theme-schema.test.js.map +1 -0
- package/packages/core/dist/shared/portrait-resolver.d.ts +35 -0
- package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -0
- package/packages/core/dist/shared/portrait-resolver.js +259 -0
- package/packages/core/dist/shared/portrait-resolver.js.map +1 -0
- package/packages/core/dist/shared/portrait-resolver.test.d.ts +2 -0
- package/packages/core/dist/shared/portrait-resolver.test.d.ts.map +1 -0
- package/packages/core/dist/shared/portrait-resolver.test.js +157 -0
- package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -0
- package/packages/core/dist/shared/repos-topology.d.ts +49 -0
- package/packages/core/dist/shared/repos-topology.d.ts.map +1 -0
- package/packages/core/dist/shared/repos-topology.js +101 -0
- package/packages/core/dist/shared/repos-topology.js.map +1 -0
- package/packages/core/dist/shared/repos-topology.test.d.ts +8 -0
- package/packages/core/dist/shared/repos-topology.test.d.ts.map +1 -0
- package/packages/core/dist/shared/repos-topology.test.js +250 -0
- package/packages/core/dist/shared/repos-topology.test.js.map +1 -0
- package/packages/core/dist/shared/skill-search.d.ts +36 -0
- package/packages/core/dist/shared/skill-search.d.ts.map +1 -0
- package/packages/core/dist/shared/skill-search.js +300 -0
- package/packages/core/dist/shared/skill-search.js.map +1 -0
- package/packages/core/dist/shared/skill-search.test.d.ts +16 -0
- package/packages/core/dist/shared/skill-search.test.d.ts.map +1 -0
- package/packages/core/dist/shared/skill-search.test.js +177 -0
- package/packages/core/dist/shared/skill-search.test.js.map +1 -0
- package/packages/core/dist/shared/skill-suggest.d.ts +76 -0
- package/packages/core/dist/shared/skill-suggest.d.ts.map +1 -0
- package/packages/core/dist/shared/skill-suggest.js +256 -0
- package/packages/core/dist/shared/skill-suggest.js.map +1 -0
- package/packages/core/dist/shared/skill-suggest.test.d.ts +12 -0
- package/packages/core/dist/shared/skill-suggest.test.d.ts.map +1 -0
- package/packages/core/dist/shared/skill-suggest.test.js +257 -0
- package/packages/core/dist/shared/skill-suggest.test.js.map +1 -0
- package/packages/core/dist/shared/theme-loader.d.ts +81 -0
- package/packages/core/dist/shared/theme-loader.d.ts.map +1 -0
- package/packages/core/dist/shared/theme-loader.js +491 -0
- package/packages/core/dist/shared/theme-loader.js.map +1 -0
- package/packages/core/dist/shared/theme-loader.test.d.ts +8 -0
- package/packages/core/dist/shared/theme-loader.test.d.ts.map +1 -0
- package/packages/core/dist/shared/theme-loader.test.js +62 -0
- package/packages/core/dist/shared/theme-loader.test.js.map +1 -0
- package/packages/core/dist/workflow/context-watch.test.js +1 -1
- package/packages/core/dist/workflow/context-watch.test.js.map +1 -1
- package/packages/core/dist/workflow/variable-resolver.test.js +1 -1
- package/packages/core/dist/workflow/variable-resolver.test.js.map +1 -1
- package/packages/core/dist/workflow/workflow-migration.test.js +4 -3
- package/packages/core/dist/workflow/workflow-migration.test.js.map +1 -1
- package/pennyfarthing-dist/agents/architect.md +1 -2
- package/pennyfarthing-dist/agents/ba.md +1 -1
- package/pennyfarthing-dist/agents/dev.md +2 -3
- package/pennyfarthing-dist/agents/devops.md +1 -1
- package/pennyfarthing-dist/agents/orchestrator.md +2 -3
- package/pennyfarthing-dist/agents/pm.md +2 -2
- package/pennyfarthing-dist/agents/reviewer.md +2 -2
- package/pennyfarthing-dist/agents/sm-setup.md +7 -7
- package/pennyfarthing-dist/agents/sm.md +19 -18
- package/pennyfarthing-dist/agents/tea.md +3 -2
- package/pennyfarthing-dist/agents/tech-writer.md +1 -1
- package/pennyfarthing-dist/agents/ux-designer.md +0 -1
- package/pennyfarthing-dist/commands/benchmark-control.md +69 -0
- package/pennyfarthing-dist/commands/benchmark.md +485 -0
- package/pennyfarthing-dist/commands/job-fair.md +102 -0
- package/pennyfarthing-dist/commands/{close-epic.md → pf-close-epic.md} +1 -1
- package/pennyfarthing-dist/commands/{new-work.md → pf-new-work.md} +4 -4
- package/pennyfarthing-dist/commands/{party-mode.md → pf-party-mode.md} +15 -2
- package/pennyfarthing-dist/commands/{patch.md → pf-patch.md} +3 -3
- package/pennyfarthing-dist/commands/{release.md → pf-release.md} +17 -10
- package/pennyfarthing-dist/commands/{setup.md → pf-setup.md} +2 -2
- package/pennyfarthing-dist/commands/{sprint.md → pf-sprint.md} +19 -19
- package/pennyfarthing-dist/commands/{standalone.md → pf-standalone.md} +2 -2
- package/pennyfarthing-dist/commands/{workflow.md → pf-workflow.md} +7 -7
- package/pennyfarthing-dist/commands/solo.md +447 -0
- package/pennyfarthing-dist/guides/agent-behavior.md +2 -2
- package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -2
- package/pennyfarthing-dist/guides/agent-template-strategic.md +1 -1
- package/pennyfarthing-dist/guides/agent-template-tactical.md +2 -2
- package/pennyfarthing-dist/guides/bikelane.md +6 -6
- package/pennyfarthing-dist/guides/permission-protocol.md +1 -1
- package/pennyfarthing-dist/guides/scale-levels.md +2 -2
- package/pennyfarthing-dist/guides/skill-schema.md +9 -9
- package/pennyfarthing-dist/guides/xml-tags.md +2 -2
- package/pennyfarthing-dist/personas/themes/dune.yaml +0 -1
- package/pennyfarthing-dist/personas/themes/hogans-heroes.yaml +260 -0
- package/pennyfarthing-dist/personas/themes/monty-python.yaml +312 -0
- package/pennyfarthing-dist/personas/themes/stephen-king.yaml +260 -0
- package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
- package/pennyfarthing-dist/scripts/core/check-context.sh +0 -0
- package/pennyfarthing-dist/scripts/core/handoff-marker.sh +0 -0
- package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
- package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
- package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
- package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +0 -0
- package/pennyfarthing-dist/scripts/git/git-status-all.sh +0 -0
- package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +84 -21
- package/pennyfarthing-dist/scripts/git/release.sh +0 -0
- package/pennyfarthing-dist/scripts/git/worktree-manager.sh +0 -0
- package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +45 -0
- package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +27 -2
- package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
- package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/session-start.sh +25 -89
- package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/README.md +1 -1
- package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
- package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
- package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
- package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
- package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +50 -26
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +18 -6
- package/pennyfarthing-dist/scripts/sprint/README.md +1 -1
- package/pennyfarthing-dist/scripts/story/README.md +1 -1
- package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
- package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
- package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
- package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/README.md +1 -1
- package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +0 -0
- package/pennyfarthing-dist/skills/pf-bc/examples.md +83 -0
- package/pennyfarthing-dist/skills/pf-bc/skill.md +51 -0
- package/pennyfarthing-dist/skills/pf-bc/usage.md +113 -0
- package/pennyfarthing-dist/skills/{cyclist → pf-cyclist}/SKILL.md +5 -5
- package/pennyfarthing-dist/skills/pf-finalize-run/SKILL.md +261 -0
- package/pennyfarthing-dist/skills/pf-jira/SKILL.md +61 -0
- package/pennyfarthing-dist/skills/pf-jira/examples.md +163 -0
- package/pennyfarthing-dist/skills/pf-jira/usage.md +213 -0
- package/pennyfarthing-dist/skills/pf-judge/SKILL.md +644 -0
- package/pennyfarthing-dist/skills/{just → pf-just}/SKILL.md +23 -23
- package/pennyfarthing-dist/skills/{permissions → pf-permissions}/skill.md +8 -8
- package/pennyfarthing-dist/skills/pf-persona-benchmark/SKILL.md +187 -0
- package/pennyfarthing-dist/skills/pf-sprint/examples.md +189 -0
- package/pennyfarthing-dist/skills/pf-sprint/skill.md +85 -0
- package/pennyfarthing-dist/skills/pf-sprint/usage.md +293 -0
- package/pennyfarthing-dist/skills/{story → pf-story}/scripts/create-story.sh +0 -0
- package/pennyfarthing-dist/skills/{story → pf-story}/scripts/size-story.sh +0 -0
- package/pennyfarthing-dist/skills/{story → pf-story}/scripts/story-template.sh +0 -0
- package/pennyfarthing-dist/skills/pf-story/skill.md +27 -0
- package/pennyfarthing-dist/skills/{systematic-debugging → pf-systematic-debugging}/SKILL.md +5 -6
- package/pennyfarthing-dist/skills/pf-theme/examples.md +92 -0
- package/pennyfarthing-dist/skills/pf-theme/skill.md +42 -0
- package/pennyfarthing-dist/skills/pf-theme/usage.md +149 -0
- package/pennyfarthing-dist/skills/pf-workflow/examples.md +101 -0
- package/pennyfarthing-dist/skills/{workflow → pf-workflow}/scripts/list-workflows.sh +0 -0
- package/pennyfarthing-dist/skills/{workflow → pf-workflow}/scripts/resume-workflow.sh +0 -0
- package/pennyfarthing-dist/skills/{workflow → pf-workflow}/scripts/show-workflow.sh +0 -0
- package/pennyfarthing-dist/skills/{workflow → pf-workflow}/scripts/start-workflow.sh +0 -0
- package/pennyfarthing-dist/skills/{workflow → pf-workflow}/scripts/workflow-status.sh +0 -0
- package/pennyfarthing-dist/skills/pf-workflow/skill.md +49 -0
- package/pennyfarthing-dist/skills/pf-workflow/usage.md +145 -0
- package/pennyfarthing-dist/skills/skill-registry.yaml +63 -81
- package/pennyfarthing-dist/workflows/architecture/data/domain-complexity.csv +13 -0
- package/pennyfarthing-dist/workflows/architecture/data/project-types.csv +7 -0
- package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +40 -11
- package/pennyfarthing-dist/workflows/party-mode-roleplay/steps/step-01-agent-loading.md +99 -0
- package/pennyfarthing-dist/workflows/party-mode-roleplay/steps/step-02-discussion.md +130 -0
- package/pennyfarthing-dist/workflows/party-mode-roleplay/steps/step-03-exit.md +100 -0
- package/pennyfarthing-dist/workflows/party-mode-roleplay/workflow.yaml +62 -0
- package/pennyfarthing-dist/workflows/prd/data/domain-complexity.csv +2 -0
- package/pennyfarthing-dist/workflows/prd/data/prd-purpose.md +2 -0
- package/pennyfarthing-dist/workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +16 -0
- package/pennyfarthing-dist/workflows/project-setup/steps/step-04-claude-md.md +3 -3
- package/pennyfarthing-dist/workflows/quick-spec/steps/step-01-understand.md +193 -0
- package/pennyfarthing-dist/workflows/quick-spec/steps/step-02-investigate.md +148 -0
- package/pennyfarthing-dist/workflows/quick-spec/steps/step-03-generate.md +141 -0
- package/pennyfarthing-dist/workflows/quick-spec/steps/step-04-review.md +192 -0
- package/pennyfarthing-dist/workflows/quick-spec/tech-spec-template.md +74 -0
- package/pennyfarthing-dist/workflows/quick-spec/workflow.yaml +35 -0
- package/pennyfarthing-dist/workflows/release/steps/step-01-preflight.md +42 -3
- package/pennyfarthing-dist/workflows/release/steps/step-02-bump.md +10 -3
- package/pennyfarthing-dist/workflows/release/steps/step-03-changelog.md +1 -1
- package/pennyfarthing-dist/workflows/release/steps/step-07-commit.md +13 -4
- package/pennyfarthing-dist/workflows/release/steps/step-08-merge.md +31 -6
- package/pennyfarthing-dist/workflows/release/steps/step-09-push.md +12 -6
- package/pennyfarthing-dist/workflows/release/steps/step-10-publish.md +30 -5
- package/pennyfarthing-dist/workflows/release/steps/step-11-finalize.md +29 -0
- package/pennyfarthing-dist/workflows/release.yaml +7 -0
- package/pennyfarthing_scripts/CLAUDE.md +182 -0
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__init__.py +1 -0
- package/pennyfarthing_scripts/bc/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/cli.py +223 -0
- package/pennyfarthing_scripts/bc/focus.py +333 -0
- package/pennyfarthing_scripts/bikerack/__init__.py +8 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/background_panel.py +81 -0
- package/pennyfarthing_scripts/bikerack/base_panel.py +100 -0
- package/pennyfarthing_scripts/bikerack/changed_panel.py +105 -0
- package/pennyfarthing_scripts/bikerack/cli.py +22 -24
- package/pennyfarthing_scripts/bikerack/diffs_panel.py +146 -0
- package/pennyfarthing_scripts/bikerack/git_panel.py +69 -0
- package/pennyfarthing_scripts/bikerack/launcher.py +63 -4
- package/pennyfarthing_scripts/bikerack/sprint_panel.py +72 -0
- package/pennyfarthing_scripts/bikerack/tui.py +193 -0
- package/pennyfarthing_scripts/bikerack/ws_client.py +176 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/cli.py +60 -16
- package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/analyze.py +15 -1
- package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/cli.py +10 -2
- package/pennyfarthing_scripts/launch/__init__.py +1 -0
- package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/launch/cli.py +231 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/version_sentinel.py +0 -1
- package/pennyfarthing_scripts/session_start_hook.py +192 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/archive_epic.py +109 -1
- package/pennyfarthing_scripts/sprint/cli.py +30 -9
- package/pennyfarthing_scripts/sprint/epic_add.py +7 -1
- package/pennyfarthing_scripts/sprint/epic_update.py +148 -0
- package/pennyfarthing_scripts/sprint/loader.py +33 -0
- package/pennyfarthing_scripts/sprint/story_add.py +11 -1
- package/pennyfarthing_scripts/sprint/story_finish.py +14 -10
- package/pennyfarthing_scripts/sprint/story_update.py +7 -0
- package/pennyfarthing_scripts/sprint/validate_cmd.py +2 -1
- package/pennyfarthing_scripts/sprint/yaml_io.py +64 -6
- package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/test_archive_epic.py +185 -0
- package/pennyfarthing_scripts/tests/test_bc.py +490 -0
- package/pennyfarthing_scripts/tests/test_cli_normalization.py +295 -0
- package/pennyfarthing_scripts/tests/test_sprint_panel.py +531 -0
- package/pennyfarthing_scripts/tests/test_tui_focus.py +411 -0
- package/pennyfarthing_scripts/tests/test_tui_panel_persistence.py +411 -0
- package/pennyfarthing_scripts/tests/test_version_sentinel.py +1 -5
- package/pennyfarthing_scripts/tests/test_yaml_io.py +5 -5
- package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/theme/cli.py +25 -2
- package/scripts/README.md +41 -0
- package/packages/core/dist/scripts/benchmark-integration.test.d.ts +0 -13
- package/packages/core/dist/scripts/benchmark-integration.test.d.ts.map +0 -1
- package/packages/core/dist/scripts/benchmark-integration.test.js +0 -680
- package/packages/core/dist/scripts/benchmark-integration.test.js.map +0 -1
- package/packages/core/dist/scripts/debugging-scenarios.test.d.ts +0 -18
- package/packages/core/dist/scripts/debugging-scenarios.test.d.ts.map +0 -1
- package/packages/core/dist/scripts/debugging-scenarios.test.js +0 -317
- package/packages/core/dist/scripts/debugging-scenarios.test.js.map +0 -1
- package/packages/core/dist/scripts/job-fair-aggregator.test.d.ts +0 -14
- package/packages/core/dist/scripts/job-fair-aggregator.test.d.ts.map +0 -1
- package/packages/core/dist/scripts/job-fair-aggregator.test.js +0 -616
- package/packages/core/dist/scripts/job-fair-aggregator.test.js.map +0 -1
- package/packages/core/dist/scripts/theme-detail.test.d.ts +0 -10
- package/packages/core/dist/scripts/theme-detail.test.js +0 -199
- package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +0 -392
- package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +0 -461
- package/pennyfarthing-dist/skills/jira/SKILL.md +0 -207
- package/pennyfarthing-dist/skills/sprint/skill.md +0 -806
- package/pennyfarthing-dist/skills/story/skill.md +0 -27
- package/pennyfarthing-dist/skills/theme/skill.md +0 -356
- package/pennyfarthing-dist/skills/workflow/skill.md +0 -368
- /package/pennyfarthing-dist/commands/{architect.md → pf-architect.md} +0 -0
- /package/pennyfarthing-dist/commands/{ba.md → pf-ba.md} +0 -0
- /package/pennyfarthing-dist/commands/{brainstorming.md → pf-brainstorming.md} +0 -0
- /package/pennyfarthing-dist/commands/{check.md → pf-check.md} +0 -0
- /package/pennyfarthing-dist/commands/{chore.md → pf-chore.md} +0 -0
- /package/pennyfarthing-dist/commands/{continue-session.md → pf-continue-session.md} +0 -0
- /package/pennyfarthing-dist/commands/{create-branches-from-story.md → pf-create-branches-from-story.md} +0 -0
- /package/pennyfarthing-dist/commands/{create-theme.md → pf-create-theme.md} +0 -0
- /package/pennyfarthing-dist/commands/{dev.md → pf-dev.md} +0 -0
- /package/pennyfarthing-dist/commands/{devops.md → pf-devops.md} +0 -0
- /package/pennyfarthing-dist/commands/{fix-blocker.md → pf-fix-blocker.md} +0 -0
- /package/pennyfarthing-dist/commands/{git-cleanup.md → pf-git-cleanup.md} +0 -0
- /package/pennyfarthing-dist/commands/{health-check.md → pf-health-check.md} +0 -0
- /package/pennyfarthing-dist/commands/{help.md → pf-help.md} +0 -0
- /package/pennyfarthing-dist/commands/{list-themes.md → pf-list-themes.md} +0 -0
- /package/pennyfarthing-dist/commands/{orchestrator.md → pf-orchestrator.md} +0 -0
- /package/pennyfarthing-dist/commands/{parallel-work.md → pf-parallel-work.md} +0 -0
- /package/pennyfarthing-dist/commands/{permissions.md → pf-permissions.md} +0 -0
- /package/pennyfarthing-dist/commands/{pm.md → pf-pm.md} +0 -0
- /package/pennyfarthing-dist/commands/{prime.md → pf-prime.md} +0 -0
- /package/pennyfarthing-dist/commands/{repo-status.md → pf-repo-status.md} +0 -0
- /package/pennyfarthing-dist/commands/{retro.md → pf-retro.md} +0 -0
- /package/pennyfarthing-dist/commands/{reviewer.md → pf-reviewer.md} +0 -0
- /package/pennyfarthing-dist/commands/{run-ci.md → pf-run-ci.md} +0 -0
- /package/pennyfarthing-dist/commands/{set-theme.md → pf-set-theme.md} +0 -0
- /package/pennyfarthing-dist/commands/{show-theme.md → pf-show-theme.md} +0 -0
- /package/pennyfarthing-dist/commands/{sm.md → pf-sm.md} +0 -0
- /package/pennyfarthing-dist/commands/{sprint-planning.md → pf-sprint-planning.md} +0 -0
- /package/pennyfarthing-dist/commands/{start-epic.md → pf-start-epic.md} +0 -0
- /package/pennyfarthing-dist/commands/{sync-epic-to-jira.md → pf-sync-epic-to-jira.md} +0 -0
- /package/pennyfarthing-dist/commands/{sync-work-with-sprint.md → pf-sync-work-with-sprint.md} +0 -0
- /package/pennyfarthing-dist/commands/{tea.md → pf-tea.md} +0 -0
- /package/pennyfarthing-dist/commands/{tech-writer.md → pf-tech-writer.md} +0 -0
- /package/pennyfarthing-dist/commands/{theme-maker.md → pf-theme-maker.md} +0 -0
- /package/pennyfarthing-dist/commands/{theme.md → pf-theme.md} +0 -0
- /package/pennyfarthing-dist/commands/{update-domain-docs.md → pf-update-domain-docs.md} +0 -0
- /package/pennyfarthing-dist/commands/{ux-designer.md → pf-ux-designer.md} +0 -0
- /package/pennyfarthing-dist/commands/{work.md → pf-work.md} +0 -0
- /package/pennyfarthing-dist/skills/{agentic-patterns → pf-agentic-patterns}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{changelog → pf-changelog}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{code-review → pf-code-review}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{context-engineering → pf-context-engineering}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{mermaid → pf-mermaid}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{otel → pf-otel}/skill.md +0 -0
- /package/pennyfarthing-dist/skills/{testing → pf-testing}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{testing → pf-testing}/references/troubleshooting.md +0 -0
- /package/pennyfarthing-dist/skills/{theme-creation → pf-theme-creation}/SKILL.md +0 -0
- /package/pennyfarthing-dist/skills/{yq → pf-yq}/SKILL.md +0 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Story 98-12: Git hook chaining with .d/ dispatcher pattern
|
|
3
|
+
*
|
|
4
|
+
* These tests verify that git hooks use a .d/ dispatcher pattern allowing
|
|
5
|
+
* multiple hook scripts to coexist without conflicts.
|
|
6
|
+
*
|
|
7
|
+
* Acceptance Criteria:
|
|
8
|
+
* AC1: .d/ dispatcher architecture — hooks installed via dispatcher + .d/ directory
|
|
9
|
+
* AC2: Hooks can be extended and composed without conflicts
|
|
10
|
+
* AC3: Support pre-commit, pre-push, and post-merge hooks
|
|
11
|
+
* AC4: Integrate with the framework's install/upgrade flow
|
|
12
|
+
* AC5: Maintain backward compatibility with existing hooks
|
|
13
|
+
*
|
|
14
|
+
* Run with: cd packages/core && pnpm build && pnpm test
|
|
15
|
+
*/
|
|
16
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
17
|
+
import assert from 'node:assert';
|
|
18
|
+
import { existsSync, mkdirSync, writeFileSync, rmSync, readFileSync, readdirSync, statSync, } from 'fs';
|
|
19
|
+
import { join } from 'path';
|
|
20
|
+
import { tmpdir } from 'os';
|
|
21
|
+
import { execSync } from 'child_process';
|
|
22
|
+
import { installGitHooks } from './init.js';
|
|
23
|
+
// Marker string used by pennyfarthing to identify its own hooks
|
|
24
|
+
const PF_MARKER = 'pennyfarthing';
|
|
25
|
+
// Dispatcher marker to identify the dispatcher script
|
|
26
|
+
const DISPATCHER_MARKER = 'pennyfarthing-dispatcher';
|
|
27
|
+
describe('Story 98-12: Git hook chaining with .d/ dispatcher pattern', () => {
|
|
28
|
+
let testDir;
|
|
29
|
+
let gitDir;
|
|
30
|
+
let gitHooksDir;
|
|
31
|
+
let nodeModulesPath;
|
|
32
|
+
let hooksSourceDir;
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
testDir = join(tmpdir(), `pf-hook-chaining-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
35
|
+
gitDir = join(testDir, '.git');
|
|
36
|
+
gitHooksDir = join(gitDir, 'hooks');
|
|
37
|
+
nodeModulesPath = join(testDir, 'node_modules/@pennyfarthing/core/pennyfarthing-dist');
|
|
38
|
+
hooksSourceDir = join(nodeModulesPath, 'scripts/hooks');
|
|
39
|
+
// Create directory structure
|
|
40
|
+
mkdirSync(gitHooksDir, { recursive: true });
|
|
41
|
+
mkdirSync(hooksSourceDir, { recursive: true });
|
|
42
|
+
// Create dispatcher template (shared source of truth)
|
|
43
|
+
writeFileSync(join(hooksSourceDir, 'dispatcher-template.sh'), '#!/bin/bash\n' +
|
|
44
|
+
'# pennyfarthing-dispatcher: Git hook dispatcher for __HOOK_NAME__\n' +
|
|
45
|
+
'# Runs all executable scripts in __HOOK_NAME__.d/ in sorted order.\n' +
|
|
46
|
+
'# Installed by pennyfarthing — do not edit manually.\n' +
|
|
47
|
+
'\n' +
|
|
48
|
+
'set -uo pipefail\n' +
|
|
49
|
+
'\n' +
|
|
50
|
+
'HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"\n' +
|
|
51
|
+
'HOOK_NAME="__HOOK_NAME__"\n' +
|
|
52
|
+
'D_DIR="${HOOK_DIR}/${HOOK_NAME}.d"\n' +
|
|
53
|
+
'\n' +
|
|
54
|
+
'# If .d/ directory doesn\'t exist or is empty, exit successfully\n' +
|
|
55
|
+
'if [[ ! -d "${D_DIR}" ]]; then\n' +
|
|
56
|
+
' exit 0\n' +
|
|
57
|
+
'fi\n' +
|
|
58
|
+
'\n' +
|
|
59
|
+
'# Capture stdin for hooks that receive input (e.g., pre-push)\n' +
|
|
60
|
+
'STDIN_DATA=""\n' +
|
|
61
|
+
'if [[ ! -t 0 ]]; then\n' +
|
|
62
|
+
' STDIN_DATA="$(cat /dev/stdin)"\n' +
|
|
63
|
+
'fi\n' +
|
|
64
|
+
'\n' +
|
|
65
|
+
'# Run each executable script in sorted order\n' +
|
|
66
|
+
'for hook_script in $(ls "${D_DIR}/" 2>/dev/null | sort); do\n' +
|
|
67
|
+
' script_path="${D_DIR}/${hook_script}"\n' +
|
|
68
|
+
'\n' +
|
|
69
|
+
' # Skip non-executable files\n' +
|
|
70
|
+
' if [[ ! -x "${script_path}" ]]; then\n' +
|
|
71
|
+
' continue\n' +
|
|
72
|
+
' fi\n' +
|
|
73
|
+
'\n' +
|
|
74
|
+
' # Run the hook, forwarding arguments and stdin\n' +
|
|
75
|
+
' if [[ -n "${STDIN_DATA}" ]]; then\n' +
|
|
76
|
+
' echo "${STDIN_DATA}" | "${script_path}" "$@"\n' +
|
|
77
|
+
' else\n' +
|
|
78
|
+
' "${script_path}" "$@"\n' +
|
|
79
|
+
' fi\n' +
|
|
80
|
+
'\n' +
|
|
81
|
+
' exit_code=$?\n' +
|
|
82
|
+
' if [[ ${exit_code} -ne 0 ]]; then\n' +
|
|
83
|
+
' exit ${exit_code}\n' +
|
|
84
|
+
' fi\n' +
|
|
85
|
+
'done\n' +
|
|
86
|
+
'\n' +
|
|
87
|
+
'exit 0\n');
|
|
88
|
+
// Create source hook files (mimicking pennyfarthing-dist/scripts/hooks/)
|
|
89
|
+
writeFileSync(join(hooksSourceDir, 'pre-commit.sh'), '#!/bin/bash\n# pennyfarthing pre-commit hook\necho "pre-commit check"\nexit 0\n');
|
|
90
|
+
writeFileSync(join(hooksSourceDir, 'pre-push.sh'), '#!/bin/bash\n# pennyfarthing pre-push hook\necho "pre-push check"\nexit 0\n');
|
|
91
|
+
writeFileSync(join(hooksSourceDir, 'post-merge.sh'), '#!/bin/bash\n# pennyfarthing post-merge hook\necho "post-merge check"\nexit 0\n');
|
|
92
|
+
});
|
|
93
|
+
afterEach(() => {
|
|
94
|
+
if (existsSync(testDir)) {
|
|
95
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// ─── AC1: .d/ dispatcher architecture ──────────────────────────────
|
|
99
|
+
describe('AC1: Dispatcher architecture with .d/ directories', () => {
|
|
100
|
+
it('should create .d/ directory for each hook type', async () => {
|
|
101
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
102
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-commit.d')), 'pre-commit.d/ directory should be created');
|
|
103
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-push.d')), 'pre-push.d/ directory should be created');
|
|
104
|
+
assert.ok(existsSync(join(gitHooksDir, 'post-merge.d')), 'post-merge.d/ directory should be created');
|
|
105
|
+
});
|
|
106
|
+
it('should install dispatcher script at .git/hooks/{hook}', async () => {
|
|
107
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
108
|
+
const dispatcherPath = join(gitHooksDir, 'pre-commit');
|
|
109
|
+
assert.ok(existsSync(dispatcherPath), 'Dispatcher should exist at .git/hooks/pre-commit');
|
|
110
|
+
const content = readFileSync(dispatcherPath, 'utf8');
|
|
111
|
+
assert.ok(content.includes(DISPATCHER_MARKER), `Dispatcher should contain '${DISPATCHER_MARKER}' marker, got:\n${content.slice(0, 200)}`);
|
|
112
|
+
});
|
|
113
|
+
it('should install pennyfarthing hook into .d/ directory', async () => {
|
|
114
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
115
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
116
|
+
assert.ok(existsSync(dDir), 'pre-commit.d/ should exist');
|
|
117
|
+
const files = readdirSync(dDir);
|
|
118
|
+
const pfHook = files.find((f) => f.includes('pennyfarthing'));
|
|
119
|
+
assert.ok(pfHook, `Should have a pennyfarthing hook in pre-commit.d/, found: [${files.join(', ')}]`);
|
|
120
|
+
const hookContent = readFileSync(join(dDir, pfHook), 'utf8');
|
|
121
|
+
assert.ok(hookContent.includes(PF_MARKER), 'Hook in .d/ should contain pennyfarthing marker');
|
|
122
|
+
});
|
|
123
|
+
it('dispatcher should iterate and run all scripts in .d/ directory', async () => {
|
|
124
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
125
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
126
|
+
// Dispatcher must reference the .d/ directory
|
|
127
|
+
assert.ok(dispatcherContent.includes('pre-commit.d') || dispatcherContent.includes('.d/') || dispatcherContent.includes('${HOOK_NAME}.d'), 'Dispatcher should reference the .d/ directory for script iteration');
|
|
128
|
+
// Dispatcher should have loop logic to run scripts
|
|
129
|
+
assert.ok(dispatcherContent.includes('for ') || dispatcherContent.includes('find '), 'Dispatcher should iterate over scripts in .d/ directory');
|
|
130
|
+
});
|
|
131
|
+
it('dispatcher should be executable', async () => {
|
|
132
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
133
|
+
const dispatcherPath = join(gitHooksDir, 'pre-commit');
|
|
134
|
+
const stat = statSync(dispatcherPath);
|
|
135
|
+
const isExecutable = (stat.mode & 0o111) !== 0;
|
|
136
|
+
assert.ok(isExecutable, 'Dispatcher script should be executable');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
// ─── AC2: Hooks can be extended and composed without conflicts ─────
|
|
140
|
+
describe('AC2: Extension and composition without conflicts', () => {
|
|
141
|
+
it('should preserve user hooks already in .d/ directory', async () => {
|
|
142
|
+
// Pre-create a user hook in .d/
|
|
143
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
144
|
+
mkdirSync(dDir, { recursive: true });
|
|
145
|
+
const userHookContent = '#!/bin/bash\necho "user hook"\nexit 0\n';
|
|
146
|
+
writeFileSync(join(dDir, '99-user-lint.sh'), userHookContent);
|
|
147
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
148
|
+
// User hook should still be there
|
|
149
|
+
assert.ok(existsSync(join(dDir, '99-user-lint.sh')), 'User hook in .d/ should be preserved');
|
|
150
|
+
assert.strictEqual(readFileSync(join(dDir, '99-user-lint.sh'), 'utf8'), userHookContent, 'User hook content should be unchanged');
|
|
151
|
+
});
|
|
152
|
+
it('should not duplicate pennyfarthing hook on re-install', async () => {
|
|
153
|
+
// Install twice
|
|
154
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
155
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
156
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
157
|
+
const files = readdirSync(dDir);
|
|
158
|
+
const pfHooks = files.filter((f) => f.includes('pennyfarthing'));
|
|
159
|
+
assert.strictEqual(pfHooks.length, 1, `Should have exactly 1 pennyfarthing hook after re-install, found ${pfHooks.length}: [${pfHooks.join(', ')}]`);
|
|
160
|
+
});
|
|
161
|
+
it('should update stale pennyfarthing hook in .d/ directory', async () => {
|
|
162
|
+
// First install
|
|
163
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
164
|
+
// Update the source hook
|
|
165
|
+
const updatedContent = '#!/bin/bash\n# pennyfarthing pre-commit hook v2\necho "updated"\nexit 0\n';
|
|
166
|
+
writeFileSync(join(hooksSourceDir, 'pre-commit.sh'), updatedContent);
|
|
167
|
+
// Re-install
|
|
168
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
169
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
170
|
+
const files = readdirSync(dDir);
|
|
171
|
+
const pfHook = files.find((f) => f.includes('pennyfarthing'));
|
|
172
|
+
const installedContent = readFileSync(join(dDir, pfHook), 'utf8');
|
|
173
|
+
assert.strictEqual(installedContent, updatedContent, 'Pennyfarthing hook in .d/ should be updated with new content');
|
|
174
|
+
});
|
|
175
|
+
it('should allow multiple tools to add hooks to .d/', async () => {
|
|
176
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
177
|
+
// Simulate another tool adding a hook
|
|
178
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
179
|
+
writeFileSync(join(dDir, '50-husky-lint-staged.sh'), '#!/bin/bash\nnpx lint-staged\n');
|
|
180
|
+
// Re-install pennyfarthing — should not disturb other tool's hook
|
|
181
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
182
|
+
assert.ok(existsSync(join(dDir, '50-husky-lint-staged.sh')), 'Third-party tool hook should survive pennyfarthing re-install');
|
|
183
|
+
const files = readdirSync(dDir);
|
|
184
|
+
assert.ok(files.length >= 2, `Should have at least 2 hooks (pennyfarthing + husky), found: [${files.join(', ')}]`);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
// ─── AC3: Support all three hook types ─────────────────────────────
|
|
188
|
+
describe('AC3: Support pre-commit, pre-push, and post-merge hooks', () => {
|
|
189
|
+
it('should install dispatcher + .d/ for pre-commit', async () => {
|
|
190
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
191
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-commit')), 'pre-commit dispatcher exists');
|
|
192
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-commit.d')), 'pre-commit.d/ exists');
|
|
193
|
+
const files = readdirSync(join(gitHooksDir, 'pre-commit.d'));
|
|
194
|
+
assert.ok(files.length > 0, 'pre-commit.d/ should have at least one hook');
|
|
195
|
+
});
|
|
196
|
+
it('should install dispatcher + .d/ for pre-push', async () => {
|
|
197
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
198
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-push')), 'pre-push dispatcher exists');
|
|
199
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-push.d')), 'pre-push.d/ exists');
|
|
200
|
+
const files = readdirSync(join(gitHooksDir, 'pre-push.d'));
|
|
201
|
+
assert.ok(files.length > 0, 'pre-push.d/ should have at least one hook');
|
|
202
|
+
});
|
|
203
|
+
it('should install dispatcher + .d/ for post-merge', async () => {
|
|
204
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
205
|
+
assert.ok(existsSync(join(gitHooksDir, 'post-merge')), 'post-merge dispatcher exists');
|
|
206
|
+
assert.ok(existsSync(join(gitHooksDir, 'post-merge.d')), 'post-merge.d/ exists');
|
|
207
|
+
const files = readdirSync(join(gitHooksDir, 'post-merge.d'));
|
|
208
|
+
assert.ok(files.length > 0, 'post-merge.d/ should have at least one hook');
|
|
209
|
+
});
|
|
210
|
+
it('should pass arguments through to hooks in .d/', async () => {
|
|
211
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
212
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-push'), 'utf8');
|
|
213
|
+
// pre-push receives remote name and URL as args — dispatcher must forward them
|
|
214
|
+
assert.ok(dispatcherContent.includes('"$@"') || dispatcherContent.includes('$@'), 'Dispatcher should forward arguments to hook scripts');
|
|
215
|
+
});
|
|
216
|
+
it('should pass stdin through to hooks in .d/ (for pre-push)', async () => {
|
|
217
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
218
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-push'), 'utf8');
|
|
219
|
+
// pre-push receives ref info on stdin — dispatcher should handle stdin
|
|
220
|
+
assert.ok(dispatcherContent.includes('stdin') ||
|
|
221
|
+
dispatcherContent.includes('tee') ||
|
|
222
|
+
dispatcherContent.includes('/dev/stdin') ||
|
|
223
|
+
dispatcherContent.includes('STDIN'), 'Dispatcher should handle stdin forwarding for hooks like pre-push');
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
// ─── AC4: Integration with install/upgrade flow ────────────────────
|
|
227
|
+
describe('AC4: Integration with install/upgrade flow', () => {
|
|
228
|
+
it('should create dispatcher from a template or generate it', async () => {
|
|
229
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
230
|
+
// Dispatcher should exist and be a proper bash script
|
|
231
|
+
const dispatcherPath = join(gitHooksDir, 'pre-commit');
|
|
232
|
+
const content = readFileSync(dispatcherPath, 'utf8');
|
|
233
|
+
assert.ok(content.startsWith('#!/bin/bash') || content.startsWith('#!/usr/bin/env bash'), 'Dispatcher should start with bash shebang');
|
|
234
|
+
});
|
|
235
|
+
it('dry-run should not create .d/ directories or dispatcher', async () => {
|
|
236
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: true });
|
|
237
|
+
assert.ok(!existsSync(join(gitHooksDir, 'pre-commit.d')), '.d/ directory should not be created in dry-run mode');
|
|
238
|
+
// If a dispatcher was placed, it should not exist in dry-run
|
|
239
|
+
// (unless it was pre-existing — but our test starts clean)
|
|
240
|
+
if (existsSync(join(gitHooksDir, 'pre-commit'))) {
|
|
241
|
+
const content = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
242
|
+
assert.ok(!content.includes(DISPATCHER_MARKER), 'Dispatcher should not be installed in dry-run mode');
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
it('should handle missing source hooks gracefully', async () => {
|
|
246
|
+
// Remove one source hook
|
|
247
|
+
rmSync(join(hooksSourceDir, 'pre-push.sh'));
|
|
248
|
+
// Should not throw
|
|
249
|
+
await assert.doesNotReject(async () => installGitHooks(testDir, nodeModulesPath, { dryRun: false }), 'Should handle missing source hooks without throwing');
|
|
250
|
+
// The other hooks should still be installed
|
|
251
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-commit.d')), 'pre-commit.d/ should still be created for available hooks');
|
|
252
|
+
});
|
|
253
|
+
it('should handle non-git repos gracefully', async () => {
|
|
254
|
+
// Remove .git directory
|
|
255
|
+
rmSync(gitDir, { recursive: true, force: true });
|
|
256
|
+
// Should not throw
|
|
257
|
+
await assert.doesNotReject(async () => installGitHooks(testDir, nodeModulesPath, { dryRun: false }), 'Should handle non-git repos without throwing');
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
// ─── AC5: Backward compatibility ───────────────────────────────────
|
|
261
|
+
describe('AC5: Backward compatibility with existing hooks', () => {
|
|
262
|
+
it('should migrate existing single-file pennyfarthing hook into .d/', async () => {
|
|
263
|
+
// Pre-existing pennyfarthing hook at old location (single file)
|
|
264
|
+
const oldHookContent = '#!/bin/bash\n# pennyfarthing pre-commit hook\necho "old hook"\nexit 0\n';
|
|
265
|
+
writeFileSync(join(gitHooksDir, 'pre-commit'), oldHookContent, { mode: 0o755 });
|
|
266
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
267
|
+
// Old single-file hook should be replaced by dispatcher
|
|
268
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
269
|
+
assert.ok(dispatcherContent.includes(DISPATCHER_MARKER), 'Old pennyfarthing hook should be replaced by dispatcher');
|
|
270
|
+
// Pennyfarthing hook content should be in .d/ directory (updated from source)
|
|
271
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
272
|
+
assert.ok(existsSync(dDir), 'pre-commit.d/ should be created during migration');
|
|
273
|
+
const files = readdirSync(dDir);
|
|
274
|
+
const pfHook = files.find((f) => f.includes('pennyfarthing'));
|
|
275
|
+
assert.ok(pfHook, 'Pennyfarthing hook should be in .d/ directory');
|
|
276
|
+
});
|
|
277
|
+
it('should migrate existing non-pennyfarthing hook into .d/', async () => {
|
|
278
|
+
// Pre-existing user/third-party hook
|
|
279
|
+
const userHookContent = '#!/bin/bash\n# my custom linter\neslint .\nexit 0\n';
|
|
280
|
+
writeFileSync(join(gitHooksDir, 'pre-commit'), userHookContent, { mode: 0o755 });
|
|
281
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
282
|
+
// Dispatcher should be installed
|
|
283
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
284
|
+
assert.ok(dispatcherContent.includes(DISPATCHER_MARKER), 'Dispatcher should replace the user hook');
|
|
285
|
+
// User hook should be moved into .d/ directory
|
|
286
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
287
|
+
const files = readdirSync(dDir);
|
|
288
|
+
// Should have both: user's original hook + pennyfarthing hook
|
|
289
|
+
assert.ok(files.length >= 2, `Should have at least 2 hooks in .d/ (user + pennyfarthing), found: [${files.join(', ')}]`);
|
|
290
|
+
// Find the migrated user hook
|
|
291
|
+
const userHook = files.find((f) => !f.includes('pennyfarthing') && !f.startsWith('.'));
|
|
292
|
+
assert.ok(userHook, `User hook should be migrated to .d/, found: [${files.join(', ')}]`);
|
|
293
|
+
const migratedContent = readFileSync(join(dDir, userHook), 'utf8');
|
|
294
|
+
assert.strictEqual(migratedContent, userHookContent, 'Migrated user hook content should be preserved');
|
|
295
|
+
});
|
|
296
|
+
it('should not migrate an existing dispatcher (idempotent upgrade)', async () => {
|
|
297
|
+
// First install — creates dispatcher
|
|
298
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
299
|
+
const firstDispatcher = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
300
|
+
// Second install — should recognize dispatcher and not re-migrate
|
|
301
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
302
|
+
const secondDispatcher = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
303
|
+
assert.strictEqual(firstDispatcher, secondDispatcher, 'Dispatcher should be stable across re-installs');
|
|
304
|
+
// No duplicates in .d/
|
|
305
|
+
const files = readdirSync(join(gitHooksDir, 'pre-commit.d'));
|
|
306
|
+
const pfHooks = files.filter((f) => f.includes('pennyfarthing'));
|
|
307
|
+
assert.strictEqual(pfHooks.length, 1, 'Should not duplicate pennyfarthing hook on upgrade');
|
|
308
|
+
});
|
|
309
|
+
it('should handle existing .backup files gracefully', async () => {
|
|
310
|
+
// Simulate a previous installation that left .backup files
|
|
311
|
+
writeFileSync(join(gitHooksDir, 'pre-commit.backup'), '#!/bin/bash\necho "old backup"\n');
|
|
312
|
+
// Current non-pennyfarthing hook
|
|
313
|
+
writeFileSync(join(gitHooksDir, 'pre-commit'), '#!/bin/bash\necho "current user hook"\nexit 0\n', { mode: 0o755 });
|
|
314
|
+
// Should not throw and should handle gracefully
|
|
315
|
+
await assert.doesNotReject(async () => installGitHooks(testDir, nodeModulesPath, { dryRun: false }), 'Should handle existing .backup files gracefully');
|
|
316
|
+
// Dispatcher should be installed
|
|
317
|
+
assert.ok(existsSync(join(gitHooksDir, 'pre-commit')), 'Dispatcher should be installed');
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
// ─── Dispatcher execution behavior ─────────────────────────────────
|
|
321
|
+
describe('Dispatcher execution behavior', () => {
|
|
322
|
+
it('dispatcher should propagate failure exit codes', async () => {
|
|
323
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
324
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
325
|
+
// Dispatcher should check exit codes and fail fast
|
|
326
|
+
assert.ok(dispatcherContent.includes('exit') &&
|
|
327
|
+
(dispatcherContent.includes('$?') || dispatcherContent.includes('||')), 'Dispatcher should propagate non-zero exit codes from hook scripts');
|
|
328
|
+
});
|
|
329
|
+
it('dispatcher should skip non-executable files in .d/', async () => {
|
|
330
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
331
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
332
|
+
// Dispatcher should check for executable permission
|
|
333
|
+
assert.ok(dispatcherContent.includes('-x') || dispatcherContent.includes('executable'), 'Dispatcher should only run executable files in .d/ directory');
|
|
334
|
+
});
|
|
335
|
+
it('dispatcher should run hooks in sorted order', async () => {
|
|
336
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
337
|
+
const dispatcherContent = readFileSync(join(gitHooksDir, 'pre-commit'), 'utf8');
|
|
338
|
+
// Dispatcher should sort scripts (ls or sort)
|
|
339
|
+
assert.ok(dispatcherContent.includes('sort') || dispatcherContent.includes('ls'), 'Dispatcher should run hooks in sorted order for deterministic execution');
|
|
340
|
+
});
|
|
341
|
+
it('dispatcher should handle empty .d/ directory gracefully', async () => {
|
|
342
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
343
|
+
// Remove all hooks from .d/ to simulate empty directory
|
|
344
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
345
|
+
for (const f of readdirSync(dDir)) {
|
|
346
|
+
rmSync(join(dDir, f));
|
|
347
|
+
}
|
|
348
|
+
// Running the dispatcher should not fail
|
|
349
|
+
const dispatcherPath = join(gitHooksDir, 'pre-commit');
|
|
350
|
+
try {
|
|
351
|
+
execSync(`bash "${dispatcherPath}"`, {
|
|
352
|
+
cwd: testDir,
|
|
353
|
+
timeout: 5000,
|
|
354
|
+
encoding: 'utf8',
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
const execErr = err;
|
|
359
|
+
assert.fail(`Dispatcher should succeed with empty .d/ directory, but got exit code ${execErr.status}: ${execErr.stderr}`);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
// ─── Pennyfarthing hook naming convention ──────────────────────────
|
|
364
|
+
describe('Hook naming conventions in .d/', () => {
|
|
365
|
+
it('pennyfarthing hook should use numeric prefix for ordering', async () => {
|
|
366
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
367
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
368
|
+
const files = readdirSync(dDir);
|
|
369
|
+
const pfHook = files.find((f) => f.includes('pennyfarthing'));
|
|
370
|
+
assert.ok(pfHook, 'Pennyfarthing hook should exist');
|
|
371
|
+
// Should have numeric prefix like "10-pennyfarthing-pre-commit.sh"
|
|
372
|
+
assert.match(pfHook, /^\d+-/, `Pennyfarthing hook should have numeric prefix for ordering, got: ${pfHook}`);
|
|
373
|
+
});
|
|
374
|
+
it('migrated user hooks should have numeric prefix', async () => {
|
|
375
|
+
// Pre-existing user hook
|
|
376
|
+
writeFileSync(join(gitHooksDir, 'pre-commit'), '#!/bin/bash\necho "user hook"\nexit 0\n', { mode: 0o755 });
|
|
377
|
+
await installGitHooks(testDir, nodeModulesPath, { dryRun: false });
|
|
378
|
+
const dDir = join(gitHooksDir, 'pre-commit.d');
|
|
379
|
+
const files = readdirSync(dDir);
|
|
380
|
+
const userHook = files.find((f) => !f.includes('pennyfarthing') && !f.startsWith('.'));
|
|
381
|
+
assert.ok(userHook, 'Migrated user hook should exist');
|
|
382
|
+
assert.match(userHook, /^\d+-/, `Migrated user hook should have numeric prefix, got: ${userHook}`);
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
//# sourceMappingURL=hook-chaining.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-chaining.test.js","sourceRoot":"","sources":["../../../src/cli/commands/hook-chaining.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,12 @@ interface InitOptions {
|
|
|
5
5
|
}
|
|
6
6
|
export declare function initCommand(projectName: string | undefined, options: InitOptions): Promise<void>;
|
|
7
7
|
/**
|
|
8
|
-
* Install git hooks
|
|
8
|
+
* Install git hooks using .d/ dispatcher pattern.
|
|
9
|
+
* Creates a dispatcher script at .git/hooks/{hook} that runs all
|
|
10
|
+
* executable scripts in .git/hooks/{hook}.d/ in sorted order.
|
|
11
|
+
* Pennyfarthing hooks are placed in the .d/ directory with numeric prefixes.
|
|
12
|
+
* Existing hooks are migrated into .d/ to preserve user customizations.
|
|
13
|
+
*
|
|
9
14
|
* Installs: pre-commit, pre-push, post-merge
|
|
10
15
|
*/
|
|
11
16
|
export declare function installGitHooks(projectRoot: string, nodeModulesPath: string, options: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAgCA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Nf;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAgCA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Nf;AAUD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyGf"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
2
|
import { join, relative, basename } from 'path';
|
|
3
3
|
import fsExtra from 'fs-extra';
|
|
4
4
|
const { ensureDirSync, removeSync } = fsExtra;
|
|
@@ -7,7 +7,7 @@ import { prompts } from '../utils/prompts.js';
|
|
|
7
7
|
import { manifestExists, readManifest, writeManifest, createManifest } from '../utils/manifest.js';
|
|
8
8
|
import { pathExists, isDirectory, ensureDir } from '../utils/files.js';
|
|
9
9
|
import { getPackageVersion, getAssetsPath } from '../utils/version.js';
|
|
10
|
-
import { createDirectorySymlink,
|
|
10
|
+
import { createDirectorySymlink, createCommandsDirectory, createSkillsDirectory, removeSymlinkOrDirectory } from '../utils/symlinks.js';
|
|
11
11
|
import { findNodeModulesPath } from '../utils/node-modules.js';
|
|
12
12
|
import { CORE_AGENTS, DIRECTORY_SYMLINKS } from '../utils/constants.js';
|
|
13
13
|
import { mergeSettingsLocalJson, ensureSettingsSymlink } from '../utils/settings.js';
|
|
@@ -125,14 +125,14 @@ export async function initCommand(projectName, options) {
|
|
|
125
125
|
logger.warning(`Could not symlink ${name} to ${link}`);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
//
|
|
128
|
+
// Link commands directory (allows user commands alongside built-in)
|
|
129
129
|
const builtInCommandsPath = join(nodeModulesPath, 'commands');
|
|
130
130
|
const projectCommandsPath = join(projectRoot, '.pennyfarthing/project/commands');
|
|
131
|
-
|
|
132
|
-
//
|
|
131
|
+
createCommandsDirectory(projectRoot, builtInCommandsPath, projectCommandsPath, dryRun || false);
|
|
132
|
+
// Link skills directory (allows user skills alongside built-in)
|
|
133
133
|
const builtInSkillsPath = join(nodeModulesPath, 'skills');
|
|
134
134
|
const projectSkillsPath = join(projectRoot, '.pennyfarthing/project/skills');
|
|
135
|
-
|
|
135
|
+
createSkillsDirectory(projectRoot, builtInSkillsPath, projectSkillsPath, dryRun || false);
|
|
136
136
|
// 8. Create agent sidecars if not exist
|
|
137
137
|
logger.newline();
|
|
138
138
|
logger.info('Creating agent sidecars...');
|
|
@@ -202,7 +202,19 @@ export async function initCommand(projectName, options) {
|
|
|
202
202
|
logger.info(' - Run `pennyfarthing doctor` to verify installation');
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
205
|
-
*
|
|
205
|
+
* Generate a dispatcher script for a given hook name by substituting
|
|
206
|
+
* __HOOK_NAME__ in the shared template.
|
|
207
|
+
*/
|
|
208
|
+
function generateDispatcher(hookName, template) {
|
|
209
|
+
return template.replace(/__HOOK_NAME__/g, hookName);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Install git hooks using .d/ dispatcher pattern.
|
|
213
|
+
* Creates a dispatcher script at .git/hooks/{hook} that runs all
|
|
214
|
+
* executable scripts in .git/hooks/{hook}.d/ in sorted order.
|
|
215
|
+
* Pennyfarthing hooks are placed in the .d/ directory with numeric prefixes.
|
|
216
|
+
* Existing hooks are migrated into .d/ to preserve user customizations.
|
|
217
|
+
*
|
|
206
218
|
* Installs: pre-commit, pre-push, post-merge
|
|
207
219
|
*/
|
|
208
220
|
export async function installGitHooks(projectRoot, nodeModulesPath, options) {
|
|
@@ -218,48 +230,89 @@ export async function installGitHooks(projectRoot, nodeModulesPath, options) {
|
|
|
218
230
|
if (!pathExists(gitHooksDir) && !options.dryRun) {
|
|
219
231
|
ensureDir(gitHooksDir, { dryRun: options.dryRun });
|
|
220
232
|
}
|
|
233
|
+
const DISPATCHER_MARKER = 'pennyfarthing-dispatcher';
|
|
234
|
+
const PF_MARKER = 'pennyfarthing';
|
|
235
|
+
const PF_PREFIX = '10';
|
|
236
|
+
const MIGRATED_PREFIX = '50';
|
|
237
|
+
// Load shared dispatcher template
|
|
238
|
+
const dispatcherTemplatePath = join(nodeModulesPath, 'scripts/hooks/dispatcher-template.sh');
|
|
239
|
+
const dispatcherTemplate = readFileSync(dispatcherTemplatePath, 'utf8');
|
|
221
240
|
// Define hooks to install
|
|
222
241
|
const hooks = [
|
|
223
|
-
{ source: 'pre-commit.sh', dest: 'pre-commit'
|
|
224
|
-
{ source: 'pre-push.sh', dest: 'pre-push'
|
|
225
|
-
{ source: 'post-merge.sh', dest: 'post-merge'
|
|
242
|
+
{ source: 'pre-commit.sh', dest: 'pre-commit' },
|
|
243
|
+
{ source: 'pre-push.sh', dest: 'pre-push' },
|
|
244
|
+
{ source: 'post-merge.sh', dest: 'post-merge' },
|
|
226
245
|
];
|
|
227
246
|
for (const hook of hooks) {
|
|
228
247
|
const sourcePath = join(nodeModulesPath, 'scripts/hooks', hook.source);
|
|
229
248
|
const destPath = join(gitHooksDir, hook.dest);
|
|
249
|
+
const dDir = join(gitHooksDir, `${hook.dest}.d`);
|
|
250
|
+
const pfHookName = `${PF_PREFIX}-pennyfarthing-${hook.dest}.sh`;
|
|
251
|
+
const pfHookPath = join(dDir, pfHookName);
|
|
230
252
|
if (!pathExists(sourcePath)) {
|
|
231
253
|
logger.warning(`${hook.source} not found, skipping`);
|
|
232
254
|
continue;
|
|
233
255
|
}
|
|
234
256
|
const sourceContent = readFileSync(sourcePath, 'utf8');
|
|
235
|
-
|
|
257
|
+
if (options.dryRun) {
|
|
258
|
+
logger.info(`Would install .git/hooks/${hook.dest} dispatcher + .d/`);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
// Create .d/ directory
|
|
262
|
+
if (!pathExists(dDir)) {
|
|
263
|
+
mkdirSync(dDir, { recursive: true });
|
|
264
|
+
}
|
|
265
|
+
// Migrate existing hook if present
|
|
236
266
|
if (pathExists(destPath)) {
|
|
237
267
|
const existingContent = readFileSync(destPath, 'utf8');
|
|
238
|
-
if (existingContent.includes(
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
268
|
+
if (existingContent.includes(DISPATCHER_MARKER)) {
|
|
269
|
+
// Already a dispatcher — update it if content changed
|
|
270
|
+
const newDispatcher = generateDispatcher(hook.dest, dispatcherTemplate);
|
|
271
|
+
if (existingContent !== newDispatcher) {
|
|
272
|
+
writeFileSync(destPath, newDispatcher, { mode: 0o755 });
|
|
273
|
+
logger.updated(`.git/hooks/${hook.dest} dispatcher`);
|
|
243
274
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
writeFileSync(destPath, sourceContent, { mode: 0o755 });
|
|
275
|
+
else {
|
|
276
|
+
logger.skipped(`.git/hooks/${hook.dest} dispatcher`, 'already installed');
|
|
247
277
|
}
|
|
248
|
-
logger.updated(`.git/hooks/${hook.dest}`);
|
|
249
|
-
continue;
|
|
250
278
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
logger.info(`Backed up existing hook to ${backupPath}`);
|
|
279
|
+
else if (existingContent.includes(PF_MARKER)) {
|
|
280
|
+
// Old-style single-file pennyfarthing hook — replace with dispatcher
|
|
281
|
+
writeFileSync(destPath, generateDispatcher(hook.dest, dispatcherTemplate), { mode: 0o755 });
|
|
282
|
+
logger.updated(`.git/hooks/${hook.dest} → dispatcher`);
|
|
256
283
|
}
|
|
284
|
+
else {
|
|
285
|
+
// Non-pennyfarthing hook — migrate into .d/ then install dispatcher
|
|
286
|
+
const migratedName = `${MIGRATED_PREFIX}-migrated-${hook.dest}.sh`;
|
|
287
|
+
const migratedPath = join(dDir, migratedName);
|
|
288
|
+
if (!pathExists(migratedPath)) {
|
|
289
|
+
writeFileSync(migratedPath, existingContent, { mode: 0o755 });
|
|
290
|
+
logger.info(`Migrated existing ${hook.dest} hook to ${hook.dest}.d/${migratedName}`);
|
|
291
|
+
}
|
|
292
|
+
writeFileSync(destPath, generateDispatcher(hook.dest, dispatcherTemplate), { mode: 0o755 });
|
|
293
|
+
logger.created(`.git/hooks/${hook.dest} dispatcher`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
// No existing hook — install fresh dispatcher
|
|
298
|
+
writeFileSync(destPath, generateDispatcher(hook.dest, dispatcherTemplate), { mode: 0o755 });
|
|
299
|
+
logger.created(`.git/hooks/${hook.dest} dispatcher`);
|
|
257
300
|
}
|
|
258
|
-
//
|
|
259
|
-
if (
|
|
260
|
-
|
|
301
|
+
// Install/update pennyfarthing hook in .d/
|
|
302
|
+
if (pathExists(pfHookPath)) {
|
|
303
|
+
const existingPf = readFileSync(pfHookPath, 'utf8');
|
|
304
|
+
if (existingPf === sourceContent) {
|
|
305
|
+
logger.skipped(`.git/hooks/${hook.dest}.d/${pfHookName}`, 'already installed');
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
writeFileSync(pfHookPath, sourceContent, { mode: 0o755 });
|
|
309
|
+
logger.updated(`.git/hooks/${hook.dest}.d/${pfHookName}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
writeFileSync(pfHookPath, sourceContent, { mode: 0o755 });
|
|
314
|
+
logger.created(`.git/hooks/${hook.dest}.d/${pfHookName}`);
|
|
261
315
|
}
|
|
262
|
-
logger.created(`.git/hooks/${hook.dest}`);
|
|
263
316
|
}
|
|
264
317
|
}
|
|
265
318
|
/**
|