@opengsd/gsd-core 1.2.0 → 1.3.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.ja-JP.md +46 -791
- package/README.ko-KR.md +44 -780
- package/README.md +42 -218
- package/README.pt-BR.md +47 -414
- package/README.zh-CN.md +46 -763
- package/agents/gsd-ai-researcher.md +2 -2
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +8 -8
- package/agents/gsd-doc-writer.md +7 -6
- package/agents/gsd-domain-researcher.md +15 -2
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-eval-planner.md +2 -2
- package/agents/gsd-executor.md +21 -8
- package/agents/gsd-framework-selector.md +1 -1
- package/agents/gsd-intel-updater.md +4 -4
- package/agents/gsd-phase-researcher.md +19 -6
- package/agents/gsd-plan-checker.md +3 -3
- package/agents/gsd-planner.md +36 -23
- package/agents/gsd-project-researcher.md +13 -0
- package/agents/gsd-research-synthesizer.md +6 -2
- package/agents/gsd-roadmapper.md +6 -6
- package/agents/gsd-ui-researcher.md +16 -3
- package/agents/gsd-user-profiler.md +2 -2
- package/agents/gsd-verifier.md +8 -8
- package/assets/gsd-logo-2000-transparent.png +0 -0
- package/assets/gsd-logo-2000-transparent.svg +17 -0
- package/assets/gsd-logo-2000.png +0 -0
- package/assets/gsd-logo-2000.svg +21 -0
- package/assets/terminal.svg +68 -0
- package/bin/install.js +255 -103
- package/commands/gsd/add-tests.md +1 -1
- package/commands/gsd/ai-integration-phase.md +3 -3
- package/commands/gsd/audit-fix.md +1 -1
- package/commands/gsd/audit-milestone.md +1 -1
- package/commands/gsd/audit-uat.md +1 -1
- package/commands/gsd/autonomous.md +2 -2
- package/commands/gsd/capture.md +6 -6
- package/commands/gsd/cleanup.md +1 -1
- package/commands/gsd/code-review.md +1 -1
- package/commands/gsd/complete-milestone.md +2 -2
- package/commands/gsd/config.md +3 -3
- package/commands/gsd/debug.md +1 -1
- package/commands/gsd/discuss-phase.md +5 -4
- package/commands/gsd/docs-update.md +1 -1
- package/commands/gsd/eval-review.md +2 -2
- package/commands/gsd/execute-phase.md +2 -2
- package/commands/gsd/explore.md +1 -1
- package/commands/gsd/extract-learnings.md +2 -2
- package/commands/gsd/fast.md +1 -1
- package/commands/gsd/forensics.md +1 -1
- package/commands/gsd/graphify.md +9 -9
- package/commands/gsd/health.md +1 -1
- package/commands/gsd/help.md +2 -2
- package/commands/gsd/import.md +5 -5
- package/commands/gsd/inbox.md +1 -1
- package/commands/gsd/ingest-docs.md +4 -4
- package/commands/gsd/manager.md +3 -3
- package/commands/gsd/map-codebase.md +1 -1
- package/commands/gsd/milestone-summary.md +1 -1
- package/commands/gsd/mvp-phase.md +4 -4
- package/commands/gsd/new-milestone.md +5 -5
- package/commands/gsd/new-project.md +5 -5
- package/commands/gsd/pause-work.md +2 -2
- package/commands/gsd/phase.md +4 -4
- package/commands/gsd/plan-phase.md +2 -2
- package/commands/gsd/plan-review-convergence.md +4 -4
- package/commands/gsd/pr-branch.md +1 -1
- package/commands/gsd/profile-user.md +2 -2
- package/commands/gsd/progress.md +4 -4
- package/commands/gsd/quick.md +1 -1
- package/commands/gsd/resume-work.md +1 -1
- package/commands/gsd/review.md +3 -2
- package/commands/gsd/secure-phase.md +1 -1
- package/commands/gsd/settings.md +1 -1
- package/commands/gsd/ship.md +2 -2
- package/commands/gsd/sketch.md +7 -7
- package/commands/gsd/spec-phase.md +2 -2
- package/commands/gsd/spike.md +3 -3
- package/commands/gsd/stats.md +1 -1
- package/commands/gsd/surface.md +4 -4
- package/commands/gsd/thread.md +1 -1
- package/commands/gsd/ui-phase.md +2 -2
- package/commands/gsd/ui-review.md +2 -2
- package/commands/gsd/ultraplan-phase.md +2 -2
- package/commands/gsd/undo.md +3 -3
- package/commands/gsd/update.md +3 -3
- package/commands/gsd/validate-phase.md +1 -1
- package/commands/gsd/verify-work.md +2 -2
- package/commands/gsd/workspace.md +4 -4
- package/{get-shit-done → gsd-core}/bin/check-latest-version.cjs +1 -1
- package/{get-shit-done → gsd-core}/bin/gsd-tools.cjs +50 -4
- package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
- package/gsd-core/bin/lib/adr-parser.cjs +399 -0
- package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
- package/gsd-core/bin/lib/artifacts.cjs +51 -0
- package/gsd-core/bin/lib/audit.cjs +743 -0
- package/gsd-core/bin/lib/check-command-router.cjs +342 -0
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
- package/gsd-core/bin/lib/clock.cjs +95 -0
- package/gsd-core/bin/lib/clusters.cjs +128 -0
- package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
- package/gsd-core/bin/lib/command-aliases.cjs +809 -0
- package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
- package/gsd-core/bin/lib/commands.cjs +1202 -0
- package/gsd-core/bin/lib/config-schema.cjs +29 -0
- package/gsd-core/bin/lib/config-types.cjs +19 -0
- package/gsd-core/bin/lib/config.cjs +714 -0
- package/{get-shit-done → gsd-core}/bin/lib/configuration.cjs +76 -85
- package/gsd-core/bin/lib/context-utilization.cjs +48 -0
- package/gsd-core/bin/lib/core.cjs +2007 -0
- package/{get-shit-done → gsd-core}/bin/lib/decisions.cjs +9 -7
- package/gsd-core/bin/lib/docs.cjs +252 -0
- package/gsd-core/bin/lib/drift.cjs +364 -0
- package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
- package/gsd-core/bin/lib/frontmatter.cjs +442 -0
- package/gsd-core/bin/lib/gap-checker.cjs +257 -0
- package/gsd-core/bin/lib/graphify.cjs +496 -0
- package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
- package/gsd-core/bin/lib/init-command-router.cjs +62 -0
- package/gsd-core/bin/lib/init.cjs +1799 -0
- package/gsd-core/bin/lib/install-profiles.cjs +526 -0
- package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
- package/gsd-core/bin/lib/installer-migration-report.cjs +347 -0
- package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
- package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
- package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
- package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +784 -0
- package/gsd-core/bin/lib/intel.cjs +607 -0
- package/gsd-core/bin/lib/learnings.cjs +270 -0
- package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
- package/gsd-core/bin/lib/milestone.cjs +373 -0
- package/gsd-core/bin/lib/model-catalog.cjs +154 -0
- package/gsd-core/bin/lib/model-profiles.cjs +24 -0
- package/gsd-core/bin/lib/observability/event.cjs +51 -0
- package/gsd-core/bin/lib/observability/logger.cjs +146 -0
- package/{get-shit-done → gsd-core}/bin/lib/observability/redaction.cjs +19 -21
- package/{get-shit-done → gsd-core}/bin/lib/package-identity.cjs +5 -1
- package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
- package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
- package/gsd-core/bin/lib/phase.cjs +1307 -0
- package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
- package/{get-shit-done → gsd-core}/bin/lib/plan-scan.cjs +18 -24
- package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
- package/gsd-core/bin/lib/profile-output.cjs +1120 -0
- package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
- package/gsd-core/bin/lib/project-root.cjs +119 -0
- package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
- package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +491 -0
- package/gsd-core/bin/lib/roadmap.cjs +600 -0
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +254 -0
- package/gsd-core/bin/lib/runtime-homes.cjs +169 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
- package/{get-shit-done → gsd-core}/bin/lib/schema-detect.cjs +20 -26
- package/gsd-core/bin/lib/secrets.cjs +34 -0
- package/gsd-core/bin/lib/security.cjs +407 -0
- package/gsd-core/bin/lib/semver-compare.cjs +42 -0
- package/gsd-core/bin/lib/shell-command-projection.cjs +524 -0
- package/gsd-core/bin/lib/state-command-router.cjs +160 -0
- package/{get-shit-done → gsd-core}/bin/lib/state-document.cjs +78 -82
- package/gsd-core/bin/lib/state.cjs +2010 -0
- package/gsd-core/bin/lib/surface.cjs +406 -0
- package/gsd-core/bin/lib/task-command-router.cjs +85 -0
- package/gsd-core/bin/lib/template.cjs +237 -0
- package/gsd-core/bin/lib/uat.cjs +297 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
- package/gsd-core/bin/lib/update-context.cjs +218 -0
- package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
- package/gsd-core/bin/lib/validate.cjs +112 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
- package/gsd-core/bin/lib/verify.cjs +1451 -0
- package/{get-shit-done → gsd-core}/bin/lib/workstream-inventory-builder.cjs +19 -12
- package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
- package/{get-shit-done → gsd-core}/bin/lib/workstream-name-policy.cjs +28 -31
- package/gsd-core/bin/lib/workstream.cjs +380 -0
- package/gsd-core/bin/lib/worktree-safety.cjs +912 -0
- package/{get-shit-done → gsd-core}/bin/shared/config-defaults.manifest.json +1 -0
- package/{get-shit-done → gsd-core}/bin/shared/config-schema.manifest.json +17 -1
- package/{get-shit-done → gsd-core}/bin/shared/model-catalog.json +27 -0
- package/{get-shit-done → gsd-core}/references/artifact-types.md +1 -1
- package/{get-shit-done → gsd-core}/references/checkpoints.md +1 -1
- package/{get-shit-done → gsd-core}/references/few-shot-examples/plan-checker.md +2 -2
- package/{get-shit-done → gsd-core}/references/few-shot-examples/verifier.md +12 -12
- package/{get-shit-done → gsd-core}/references/model-profile-resolution.md +1 -1
- package/{get-shit-done → gsd-core}/references/mvp-concepts.md +1 -1
- package/{get-shit-done → gsd-core}/references/planner-graphify-auto-update.md +2 -2
- package/{get-shit-done → gsd-core}/references/planner-human-verify-mode.md +1 -1
- package/{get-shit-done → gsd-core}/references/planner-mvp-mode.md +1 -1
- package/{get-shit-done → gsd-core}/references/ui-brand.md +4 -2
- package/{get-shit-done → gsd-core}/references/verification-patterns.md +1 -1
- package/gsd-core/references/worktree-branch-check.md +38 -0
- package/{get-shit-done → gsd-core}/references/worktree-path-safety.md +4 -26
- package/{get-shit-done → gsd-core}/templates/README.md +2 -2
- package/{get-shit-done → gsd-core}/templates/codebase/structure.md +10 -10
- package/{get-shit-done → gsd-core}/templates/copilot-instructions.md +1 -1
- package/{get-shit-done → gsd-core}/templates/phase-prompt.md +10 -10
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
- package/{get-shit-done → gsd-core}/workflows/add-backlog.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/add-phase.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/add-tests.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/add-todo.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/ai-integration-phase.md +4 -4
- package/{get-shit-done → gsd-core}/workflows/audit-fix.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/audit-milestone.md +3 -1
- package/{get-shit-done → gsd-core}/workflows/audit-uat.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/autonomous.md +10 -8
- package/{get-shit-done → gsd-core}/workflows/check-todos.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/cleanup.md +44 -4
- package/{get-shit-done → gsd-core}/workflows/code-review-fix.md +4 -4
- package/{get-shit-done → gsd-core}/workflows/code-review.md +6 -4
- package/{get-shit-done → gsd-core}/workflows/complete-milestone.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/debug.md +7 -2
- package/{get-shit-done → gsd-core}/workflows/diagnose-issues.md +6 -2
- package/{get-shit-done → gsd-core}/workflows/discovery-phase.md +5 -5
- package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/advisor.md +5 -5
- package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/auto.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/chain.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/power.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/discuss-phase-assumptions.md +4 -4
- package/{get-shit-done → gsd-core}/workflows/discuss-phase.md +6 -6
- package/{get-shit-done → gsd-core}/workflows/do.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/docs-update.md +19 -5
- package/{get-shit-done → gsd-core}/workflows/edit-phase.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/eval-review.md +3 -3
- package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/codebase-drift-gate.md +16 -3
- package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/post-merge-gate.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/execute-phase.md +89 -57
- package/{get-shit-done → gsd-core}/workflows/execute-plan.md +8 -8
- package/{get-shit-done → gsd-core}/workflows/explore.md +5 -3
- package/{get-shit-done → gsd-core}/workflows/extract-learnings.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/forensics.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/graduation.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/health.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/help/modes/default.md +3 -3
- package/{get-shit-done → gsd-core}/workflows/help/modes/full.md +6 -6
- package/{get-shit-done → gsd-core}/workflows/import.md +3 -1
- package/{get-shit-done → gsd-core}/workflows/ingest-docs.md +5 -5
- package/{get-shit-done → gsd-core}/workflows/insert-phase.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/list-workspaces.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/manager.md +3 -3
- package/{get-shit-done → gsd-core}/workflows/map-codebase.md +3 -1
- package/{get-shit-done → gsd-core}/workflows/milestone-summary.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/mvp-phase.md +7 -7
- package/{get-shit-done → gsd-core}/workflows/new-milestone.md +5 -5
- package/{get-shit-done → gsd-core}/workflows/new-project.md +8 -8
- package/{get-shit-done → gsd-core}/workflows/new-workspace.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/next.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/pause-work.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/plan-milestone-gaps.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/plan-phase.md +29 -28
- package/{get-shit-done → gsd-core}/workflows/plan-review-convergence.md +10 -10
- package/{get-shit-done → gsd-core}/workflows/plant-seed.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/profile-user.md +11 -11
- package/{get-shit-done → gsd-core}/workflows/progress.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/quick.md +7 -29
- package/{get-shit-done → gsd-core}/workflows/reapply-patches.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/remove-phase.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/remove-workspace.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/resume-project.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/review.md +110 -2
- package/{get-shit-done → gsd-core}/workflows/scan.md +3 -1
- package/{get-shit-done → gsd-core}/workflows/secure-phase.md +5 -3
- package/{get-shit-done → gsd-core}/workflows/settings-advanced.md +196 -6
- package/{get-shit-done → gsd-core}/workflows/settings-integrations.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/settings.md +16 -2
- package/{get-shit-done → gsd-core}/workflows/ship.md +56 -4
- package/{get-shit-done → gsd-core}/workflows/sketch-wrap-up.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/sketch.md +5 -5
- package/{get-shit-done → gsd-core}/workflows/spec-phase.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/spike-wrap-up.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/spike.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/stats.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/sync-skills.md +3 -3
- package/{get-shit-done → gsd-core}/workflows/thread.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/transition.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/ui-phase.md +5 -5
- package/{get-shit-done → gsd-core}/workflows/ui-review.md +3 -3
- package/{get-shit-done → gsd-core}/workflows/ultraplan-phase.md +1 -1
- package/{get-shit-done → gsd-core}/workflows/undo.md +2 -2
- package/{get-shit-done → gsd-core}/workflows/update.md +41 -16
- package/{get-shit-done → gsd-core}/workflows/validate-phase.md +5 -3
- package/{get-shit-done → gsd-core}/workflows/verify-phase.md +4 -4
- package/{get-shit-done → gsd-core}/workflows/verify-work.md +7 -7
- package/hooks/dist/gsd-check-update-worker.js +16 -3
- package/hooks/dist/gsd-check-update.js +7 -5
- package/hooks/dist/gsd-context-monitor.js +2 -2
- package/hooks/dist/gsd-statusline.js +39 -21
- package/hooks/dist/gsd-update-banner.js +6 -2
- package/hooks/dist/gsd-worktree-path-guard.js +169 -0
- package/hooks/dist/managed-hooks-registry.cjs +35 -0
- package/hooks/gsd-check-update-worker.js +16 -3
- package/hooks/gsd-check-update.js +7 -5
- package/hooks/gsd-context-monitor.js +2 -2
- package/hooks/gsd-statusline.js +39 -21
- package/hooks/gsd-update-banner.js +6 -2
- package/hooks/gsd-worktree-path-guard.js +169 -0
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +17 -11
- package/scripts/affected-tests-lib.cjs +1 -1
- package/scripts/base64-scan.sh +12 -0
- package/scripts/build-hooks.js +5 -1
- package/scripts/changeset/cli.cjs +2 -2
- package/scripts/changeset/github-release-notes.cjs +1 -1
- package/scripts/changeset/lint.cjs +1 -1
- package/scripts/check-alias-drift.cjs +8 -8
- package/scripts/check-env.cjs +5 -1
- package/scripts/ci-test-scope.cjs +34 -9
- package/scripts/command-contract-helpers.cjs +1 -1
- package/scripts/fix-slash-commands.cjs +5 -5
- package/scripts/gen-inventory-manifest.cjs +3 -3
- package/scripts/generate-package-identity.cjs +28 -7
- package/scripts/lib/allowlist-ratchet.cjs +136 -0
- package/scripts/lint-command-contract.cjs +1 -1
- package/scripts/lint-legacy-dir-name.cjs +156 -0
- package/scripts/lint-package-identity-drift.cjs +8 -8
- package/scripts/lint-pr-check-project-dir.cjs +0 -1
- package/scripts/lint-shell-command-projection-drift.cjs +1 -1
- package/scripts/lint-skill-deps.cjs +1 -1
- package/scripts/lint-test-file-count.allowlist.json +129 -32
- package/scripts/lint-test-file-count.cjs +85 -30
- package/scripts/mutation-matrix.cjs +219 -0
- package/scripts/prompt-injection-scan.sh +5 -1
- package/scripts/release-notes/format-github-release-notes.cjs +256 -0
- package/scripts/release-tarball-smoke.cjs +9 -9
- package/scripts/run-tests.cjs +34 -2
- package/scripts/strip-prose-atrefs.cjs +2 -2
- package/scripts/sync-runtime-launcher.cjs +2 -2
- package/scripts/verify-npm-publish.cjs +252 -0
- package/get-shit-done/bin/lib/active-workstream-store.cjs +0 -302
- package/get-shit-done/bin/lib/adr-parser.cjs +0 -394
- package/get-shit-done/bin/lib/agent-command-router.cjs +0 -65
- package/get-shit-done/bin/lib/artifacts.cjs +0 -53
- package/get-shit-done/bin/lib/audit.cjs +0 -755
- package/get-shit-done/bin/lib/check-command-router.cjs +0 -333
- package/get-shit-done/bin/lib/cjs-command-router-adapter.cjs +0 -118
- package/get-shit-done/bin/lib/clock.cjs +0 -96
- package/get-shit-done/bin/lib/clusters.cjs +0 -135
- package/get-shit-done/bin/lib/code-review-flags.cjs +0 -74
- package/get-shit-done/bin/lib/command-aliases.cjs +0 -815
- package/get-shit-done/bin/lib/command-arg-projection.cjs +0 -62
- package/get-shit-done/bin/lib/command-routing-hub.cjs +0 -388
- package/get-shit-done/bin/lib/commands.cjs +0 -1188
- package/get-shit-done/bin/lib/config-schema.cjs +0 -31
- package/get-shit-done/bin/lib/config.cjs +0 -728
- package/get-shit-done/bin/lib/context-utilization.cjs +0 -47
- package/get-shit-done/bin/lib/core.cjs +0 -2121
- package/get-shit-done/bin/lib/docs.cjs +0 -270
- package/get-shit-done/bin/lib/drift.cjs +0 -388
- package/get-shit-done/bin/lib/fallow-runner.cjs +0 -109
- package/get-shit-done/bin/lib/frontmatter.cjs +0 -389
- package/get-shit-done/bin/lib/gap-checker.cjs +0 -205
- package/get-shit-done/bin/lib/graphify.cjs +0 -592
- package/get-shit-done/bin/lib/gsd2-import.cjs +0 -514
- package/get-shit-done/bin/lib/init-command-router.cjs +0 -58
- package/get-shit-done/bin/lib/init.cjs +0 -2112
- package/get-shit-done/bin/lib/install-profiles.cjs +0 -603
- package/get-shit-done/bin/lib/installer-migration-authoring.cjs +0 -117
- package/get-shit-done/bin/lib/installer-migration-report.cjs +0 -354
- package/get-shit-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +0 -220
- package/get-shit-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +0 -41
- package/get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +0 -80
- package/get-shit-done/bin/lib/installer-migrations.cjs +0 -778
- package/get-shit-done/bin/lib/intel.cjs +0 -708
- package/get-shit-done/bin/lib/learnings.cjs +0 -421
- package/get-shit-done/bin/lib/milestone.cjs +0 -314
- package/get-shit-done/bin/lib/model-catalog.cjs +0 -212
- package/get-shit-done/bin/lib/model-profiles.cjs +0 -31
- package/get-shit-done/bin/lib/observability/event.cjs +0 -82
- package/get-shit-done/bin/lib/observability/logger.cjs +0 -174
- package/get-shit-done/bin/lib/phase-command-router.cjs +0 -191
- package/get-shit-done/bin/lib/phase-lifecycle.cjs +0 -80
- package/get-shit-done/bin/lib/phase.cjs +0 -1607
- package/get-shit-done/bin/lib/phases-command-router.cjs +0 -39
- package/get-shit-done/bin/lib/planning-workspace.cjs +0 -238
- package/get-shit-done/bin/lib/profile-output.cjs +0 -1141
- package/get-shit-done/bin/lib/profile-pipeline.cjs +0 -539
- package/get-shit-done/bin/lib/project-root.cjs +0 -112
- package/get-shit-done/bin/lib/prompt-budget.cjs +0 -399
- package/get-shit-done/bin/lib/review-reviewer-selection.cjs +0 -125
- package/get-shit-done/bin/lib/roadmap-command-router.cjs +0 -28
- package/get-shit-done/bin/lib/roadmap.cjs +0 -650
- package/get-shit-done/bin/lib/runtime-artifact-layout.cjs +0 -301
- package/get-shit-done/bin/lib/runtime-homes.cjs +0 -222
- package/get-shit-done/bin/lib/runtime-name-policy.cjs +0 -83
- package/get-shit-done/bin/lib/runtime-slash.cjs +0 -112
- package/get-shit-done/bin/lib/secrets.cjs +0 -32
- package/get-shit-done/bin/lib/security.cjs +0 -600
- package/get-shit-done/bin/lib/semver-compare.cjs +0 -35
- package/get-shit-done/bin/lib/shell-command-projection.cjs +0 -500
- package/get-shit-done/bin/lib/state-command-router.cjs +0 -252
- package/get-shit-done/bin/lib/state.cjs +0 -2038
- package/get-shit-done/bin/lib/surface.cjs +0 -470
- package/get-shit-done/bin/lib/task-command-router.cjs +0 -81
- package/get-shit-done/bin/lib/template.cjs +0 -228
- package/get-shit-done/bin/lib/uat.cjs +0 -289
- package/get-shit-done/bin/lib/update-context.cjs +0 -209
- package/get-shit-done/bin/lib/validate-command-router.cjs +0 -83
- package/get-shit-done/bin/lib/validate.cjs +0 -92
- package/get-shit-done/bin/lib/verify-command-router.cjs +0 -40
- package/get-shit-done/bin/lib/verify.cjs +0 -1511
- package/get-shit-done/bin/lib/workstream-inventory.cjs +0 -146
- package/get-shit-done/bin/lib/workstream.cjs +0 -389
- package/get-shit-done/bin/lib/worktree-safety.cjs +0 -985
- package/get-shit-done/workflows/_runtime-launcher.snippet.sh +0 -1
- package/scripts/lint-no-source-grep-extras.cjs +0 -81
- package/scripts/lint-no-source-grep.cjs +0 -174
- package/scripts/lint-shared-module-handsync.cjs +0 -388
- package/scripts/shared-module-handsync-allowlist.json +0 -183
- /package/{get-shit-done → gsd-core}/bin/shared/runtime-aliases.manifest.json +0 -0
- /package/{get-shit-done → gsd-core}/bin/verify-reapply-patches.cjs +0 -0
- /package/{get-shit-done → gsd-core}/contexts/dev.md +0 -0
- /package/{get-shit-done → gsd-core}/contexts/research.md +0 -0
- /package/{get-shit-done → gsd-core}/contexts/review.md +0 -0
- /package/{get-shit-done → gsd-core}/references/agent-contracts.md +0 -0
- /package/{get-shit-done → gsd-core}/references/ai-evals.md +0 -0
- /package/{get-shit-done → gsd-core}/references/ai-frameworks.md +0 -0
- /package/{get-shit-done → gsd-core}/references/autonomous-smart-discuss.md +0 -0
- /package/{get-shit-done → gsd-core}/references/common-bug-patterns.md +0 -0
- /package/{get-shit-done → gsd-core}/references/context-budget.md +0 -0
- /package/{get-shit-done → gsd-core}/references/continuation-format.md +0 -0
- /package/{get-shit-done → gsd-core}/references/debugger-philosophy.md +0 -0
- /package/{get-shit-done → gsd-core}/references/decimal-phase-calculation.md +0 -0
- /package/{get-shit-done → gsd-core}/references/doc-conflict-engine.md +0 -0
- /package/{get-shit-done → gsd-core}/references/domain-probes.md +0 -0
- /package/{get-shit-done → gsd-core}/references/execute-mvp-tdd.md +0 -0
- /package/{get-shit-done → gsd-core}/references/executor-examples.md +0 -0
- /package/{get-shit-done → gsd-core}/references/gate-prompts.md +0 -0
- /package/{get-shit-done → gsd-core}/references/gates.md +0 -0
- /package/{get-shit-done → gsd-core}/references/git-integration.md +0 -0
- /package/{get-shit-done → gsd-core}/references/git-planning-commit.md +0 -0
- /package/{get-shit-done → gsd-core}/references/ios-scaffold.md +0 -0
- /package/{get-shit-done → gsd-core}/references/mandatory-initial-read.md +0 -0
- /package/{get-shit-done → gsd-core}/references/model-profiles.md +0 -0
- /package/{get-shit-done → gsd-core}/references/phase-argument-parsing.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-antipatterns.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-chunked.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-gap-closure.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-interface-context.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-reviews.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-revision.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planner-source-audit.md +0 -0
- /package/{get-shit-done → gsd-core}/references/planning-config.md +0 -0
- /package/{get-shit-done → gsd-core}/references/project-skills-discovery.md +0 -0
- /package/{get-shit-done → gsd-core}/references/questioning.md +0 -0
- /package/{get-shit-done → gsd-core}/references/revision-loop.md +0 -0
- /package/{get-shit-done → gsd-core}/references/scout-codebase.md +0 -0
- /package/{get-shit-done → gsd-core}/references/skeleton-template.md +0 -0
- /package/{get-shit-done → gsd-core}/references/sketch-interactivity.md +0 -0
- /package/{get-shit-done → gsd-core}/references/sketch-theme-system.md +0 -0
- /package/{get-shit-done → gsd-core}/references/sketch-tooling.md +0 -0
- /package/{get-shit-done → gsd-core}/references/sketch-variant-patterns.md +0 -0
- /package/{get-shit-done → gsd-core}/references/spidr-splitting.md +0 -0
- /package/{get-shit-done → gsd-core}/references/tdd.md +0 -0
- /package/{get-shit-done → gsd-core}/references/thinking-models-debug.md +0 -0
- /package/{get-shit-done → gsd-core}/references/thinking-models-execution.md +0 -0
- /package/{get-shit-done → gsd-core}/references/thinking-models-planning.md +0 -0
- /package/{get-shit-done → gsd-core}/references/thinking-models-research.md +0 -0
- /package/{get-shit-done → gsd-core}/references/thinking-models-verification.md +0 -0
- /package/{get-shit-done → gsd-core}/references/thinking-partner.md +0 -0
- /package/{get-shit-done → gsd-core}/references/universal-anti-patterns.md +0 -0
- /package/{get-shit-done → gsd-core}/references/user-profiling.md +0 -0
- /package/{get-shit-done → gsd-core}/references/user-story-template.md +0 -0
- /package/{get-shit-done → gsd-core}/references/verification-overrides.md +0 -0
- /package/{get-shit-done → gsd-core}/references/verify-mvp-mode.md +0 -0
- /package/{get-shit-done → gsd-core}/references/workstream-flag.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/AI-SPEC.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/DEBUG.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/SECURITY.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/UAT.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/UI-SPEC.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/VALIDATION.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/claude-md.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/codebase/architecture.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/codebase/concerns.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/codebase/conventions.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/codebase/integrations.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/codebase/stack.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/codebase/testing.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/config.json +0 -0
- /package/{get-shit-done → gsd-core}/templates/context.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/continue-here.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/debug-subagent-prompt.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/dev-preferences.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/discovery.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/discussion-log.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/milestone-archive.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/milestone.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/planner-subagent-prompt.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/project.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/requirements.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/research-project/ARCHITECTURE.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/research-project/FEATURES.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/research-project/PITFALLS.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/research-project/STACK.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/research-project/SUMMARY.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/research.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/retrospective.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/roadmap.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/spec.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/state.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/summary-complex.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/summary-minimal.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/summary-standard.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/summary.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/user-profile.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/user-setup.md +0 -0
- /package/{get-shit-done → gsd-core}/templates/verification-report.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/analyze-dependencies.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/all.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/analyze.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/batch.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/default.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/text.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/checkpoint.json +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/context.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/discussion-log.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/discuss-phase-power.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/per-plan-worktree-gate.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/fast.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/help/modes/brief.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/help/modes/topic.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/help.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/inbox.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/list-phase-assumptions.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/node-repair.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/note.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/pr-branch.md +0 -0
- /package/{get-shit-done → gsd-core}/workflows/session-report.md +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// gsd-hook-version: {{GSD_VERSION}}
|
|
3
|
+
// GSD Worktree Path Guard — PreToolUse hook
|
|
4
|
+
// Blocks Edit/Write/MultiEdit tool calls that target absolute paths outside the worktree root.
|
|
5
|
+
//
|
|
6
|
+
// Problem: gsd-executor agents spawned with isolation="worktree" sometimes issue
|
|
7
|
+
// Edit/Write calls with absolute paths rooted at the MAIN repository instead of
|
|
8
|
+
// the worktree (issue #260). The prose guard in agents/gsd-executor.md step 0b
|
|
9
|
+
// is never enforced because the model under load skips it.
|
|
10
|
+
//
|
|
11
|
+
// This hook enforces the constraint at the tooling layer, making it HARD-BLOCKING.
|
|
12
|
+
//
|
|
13
|
+
// Triggers on: Edit, Write, and MultiEdit tool calls
|
|
14
|
+
// Action: BLOCK (exit 2) if file_path is absolute and outside the worktree root
|
|
15
|
+
// No-op: relative paths, non-worktree CWDs, hook errors (silent fail)
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const { spawnSync } = require('child_process');
|
|
20
|
+
|
|
21
|
+
const SPAWNOPT = { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 2000 };
|
|
22
|
+
|
|
23
|
+
function git(args, cwd) {
|
|
24
|
+
return spawnSync('git', args, { ...SPAWNOPT, cwd });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Walk up from `start` to find the nearest existing directory.
|
|
28
|
+
// Returns null if we reach the filesystem root without finding one.
|
|
29
|
+
function nearestExistingDir(start) {
|
|
30
|
+
let dir = start;
|
|
31
|
+
let prev;
|
|
32
|
+
do {
|
|
33
|
+
prev = dir;
|
|
34
|
+
try { fs.accessSync(dir, fs.constants.F_OK); return dir; } catch { /* keep walking */ }
|
|
35
|
+
dir = path.dirname(dir);
|
|
36
|
+
} while (dir !== prev);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let input = '';
|
|
41
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
42
|
+
process.stdin.setEncoding('utf8');
|
|
43
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
44
|
+
process.stdin.on('end', () => {
|
|
45
|
+
clearTimeout(stdinTimeout);
|
|
46
|
+
try {
|
|
47
|
+
const data = JSON.parse(input);
|
|
48
|
+
const toolName = data.tool_name;
|
|
49
|
+
|
|
50
|
+
// Only guard Edit, Write, and MultiEdit tool calls
|
|
51
|
+
if (toolName !== 'Edit' && toolName !== 'Write' && toolName !== 'MultiEdit') {
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const cwd = data.cwd || process.cwd();
|
|
56
|
+
|
|
57
|
+
// Detect whether CWD is inside a linked git worktree by inspecting
|
|
58
|
+
// the git-dir path. In a linked worktree, git rev-parse --git-dir
|
|
59
|
+
// returns a path containing .git/worktrees/ as a component.
|
|
60
|
+
// In the main repo or a submodule it returns .git (or a path without /worktrees/).
|
|
61
|
+
// This approach works even when cwd is a subdirectory of the worktree.
|
|
62
|
+
const gitDirResult = git(['rev-parse', '--git-dir'], cwd);
|
|
63
|
+
if (gitDirResult.status !== 0 || !gitDirResult.stdout) {
|
|
64
|
+
process.exit(0); // not a git repo — pass through
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const gitDir = gitDirResult.stdout.trim();
|
|
68
|
+
// A linked worktree's --git-dir contains .git/worktrees/ as a path component
|
|
69
|
+
const isLinkedWorktree = /[/\\]\.git[/\\]worktrees[/\\]/.test(gitDir);
|
|
70
|
+
if (!isLinkedWorktree) {
|
|
71
|
+
process.exit(0); // main repo, submodule, or separate-git-dir — no-op
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Get the raw --show-toplevel output for the worktree (cwd).
|
|
75
|
+
// We keep it raw (not path.resolve'd) to compare directly with the
|
|
76
|
+
// file's toplevel — same git binary, same format, no normalization needed.
|
|
77
|
+
const wtTopResult = git(['rev-parse', '--show-toplevel'], cwd);
|
|
78
|
+
if (wtTopResult.status !== 0 || !wtTopResult.stdout) {
|
|
79
|
+
process.exit(0); // can't determine root — fail open
|
|
80
|
+
}
|
|
81
|
+
const wtTopRaw = wtTopResult.stdout.trim();
|
|
82
|
+
|
|
83
|
+
const rawFilePath = data.tool_input?.file_path || '';
|
|
84
|
+
if (!rawFilePath) {
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Relative paths are always safe — they resolve relative to CWD inside the worktree
|
|
89
|
+
if (!path.isAbsolute(rawFilePath)) {
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Normalise .. traversal so /worktree/src/../../../main/file
|
|
94
|
+
// resolves to its true location before we check containment.
|
|
95
|
+
const filePath = path.resolve(rawFilePath);
|
|
96
|
+
|
|
97
|
+
// Find the nearest existing ancestor of filePath so we can ask git
|
|
98
|
+
// for its toplevel. The file itself may not exist yet (Write creates
|
|
99
|
+
// new files), but at least one ancestor directory must exist.
|
|
100
|
+
// We check the file itself first in case it already exists.
|
|
101
|
+
const checkDir = nearestExistingDir(
|
|
102
|
+
(() => {
|
|
103
|
+
try {
|
|
104
|
+
return fs.statSync(filePath).isDirectory() ? filePath : path.dirname(filePath);
|
|
105
|
+
} catch {
|
|
106
|
+
return path.dirname(filePath);
|
|
107
|
+
}
|
|
108
|
+
})()
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (!checkDir) {
|
|
112
|
+
// Walked to root without finding any directory — path is synthetic.
|
|
113
|
+
// Block conservatively.
|
|
114
|
+
const output = {
|
|
115
|
+
decision: 'block',
|
|
116
|
+
reason:
|
|
117
|
+
`Worktree path guard: '${filePath}' has no existing ancestor directory — ` +
|
|
118
|
+
`cannot verify it is inside the worktree '${wtTopRaw}'. Use a relative path instead.`,
|
|
119
|
+
};
|
|
120
|
+
process.stdout.write(JSON.stringify(output));
|
|
121
|
+
process.exit(2);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Ask git for the toplevel of the file's location.
|
|
125
|
+
// Comparing two raw git --show-toplevel outputs avoids every
|
|
126
|
+
// platform-specific path normalisation pitfall (Windows 8.3 short names,
|
|
127
|
+
// case differences between realpathSync and path.resolve, forward- vs
|
|
128
|
+
// back-slash inconsistencies) — both values come from the same git binary
|
|
129
|
+
// in the same format by definition.
|
|
130
|
+
const fileTopResult = git(['rev-parse', '--show-toplevel'], checkDir);
|
|
131
|
+
|
|
132
|
+
if (fileTopResult.status !== 0 || !fileTopResult.stdout) {
|
|
133
|
+
// checkDir is not inside any git repo → cannot be inside the worktree.
|
|
134
|
+
const output = {
|
|
135
|
+
decision: 'block',
|
|
136
|
+
reason:
|
|
137
|
+
`Worktree path guard: '${filePath}' is not inside any git repository — ` +
|
|
138
|
+
`it cannot be inside the worktree at '${wtTopRaw}'. Use a relative path instead.`,
|
|
139
|
+
};
|
|
140
|
+
process.stdout.write(JSON.stringify(output));
|
|
141
|
+
process.exit(2);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const fileTopRaw = fileTopResult.stdout.trim();
|
|
145
|
+
|
|
146
|
+
// Same git toplevel → file is inside the worktree → allow
|
|
147
|
+
if (fileTopRaw === wtTopRaw) {
|
|
148
|
+
process.exit(0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// BLOCK: file resolves to a different git root than the active worktree
|
|
152
|
+
const output = {
|
|
153
|
+
decision: 'block',
|
|
154
|
+
reason:
|
|
155
|
+
`Worktree path guard: '${filePath}' resolves to git root '${fileTopRaw}' which ` +
|
|
156
|
+
`differs from the active worktree root '${wtTopRaw}'. This likely means an ` +
|
|
157
|
+
`absolute path was derived from the orchestrator's main repository instead of ` +
|
|
158
|
+
`the active worktree. To fix: use a relative path, or re-derive the base ` +
|
|
159
|
+
`directory with \`git rev-parse --show-toplevel\` from within the worktree ` +
|
|
160
|
+
`(hook cwd: '${cwd}').`,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
process.stdout.write(JSON.stringify(output));
|
|
164
|
+
process.exit(2);
|
|
165
|
+
} catch {
|
|
166
|
+
// Silent fail — never block valid tool calls due to hook errors
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
});
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengsd/gsd-core",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"gsd-core": "bin/install.js",
|
|
7
|
-
"gsd-tools": "
|
|
7
|
+
"gsd-tools": "gsd-core/bin/gsd-tools.cjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin",
|
|
11
11
|
"commands",
|
|
12
|
-
"
|
|
12
|
+
"gsd-core",
|
|
13
|
+
"assets",
|
|
13
14
|
"agents",
|
|
14
15
|
"hooks",
|
|
15
16
|
"scripts"
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
"codex",
|
|
27
28
|
"codex-cli"
|
|
28
29
|
],
|
|
29
|
-
"author": "
|
|
30
|
+
"author": "OpenGSD",
|
|
30
31
|
"license": "MIT",
|
|
31
32
|
"repository": {
|
|
32
33
|
"type": "git",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@eslint/js": "^9.39.4",
|
|
52
53
|
"@stryker-mutator/core": "^9.6.1",
|
|
54
|
+
"@types/node": "^22.19.19",
|
|
53
55
|
"c8": "^11.0.0",
|
|
54
56
|
"eslint": "^9.39.4",
|
|
55
57
|
"eslint-plugin-n": "^17.24.0",
|
|
@@ -69,12 +71,15 @@
|
|
|
69
71
|
"check:alias-drift": "node scripts/check-alias-drift.cjs",
|
|
70
72
|
"check:identity-drift": "node scripts/lint-package-identity-drift.cjs",
|
|
71
73
|
"check:integrity": "node scripts/check-npm-integrity.cjs",
|
|
72
|
-
"build": "npm run generate:identity && npm run build:hooks",
|
|
74
|
+
"build": "npm run generate:identity && npm run build:lib && npm run build:hooks",
|
|
73
75
|
"build:hooks": "node scripts/build-hooks.js",
|
|
76
|
+
"build:lib": "tsc -p tsconfig.build.json",
|
|
74
77
|
"generate:identity": "node scripts/generate-package-identity.cjs",
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
+
"prepack": "npm run build:lib",
|
|
79
|
+
"prepare": "npm run build:lib",
|
|
80
|
+
"prepublishOnly": "npm run build:lib && npm run build:hooks",
|
|
81
|
+
"pretest": "npm run build:lib && npm run lint:skill-deps",
|
|
82
|
+
"pretest:coverage": "npm run build:lib && npm run lint:skill-deps",
|
|
78
83
|
"lint": "eslint . --cache --cache-location node_modules/.cache/eslint/",
|
|
79
84
|
"lint:fix": "eslint . --fix",
|
|
80
85
|
"lint:descriptions": "node scripts/lint-descriptions.cjs",
|
|
@@ -83,6 +88,7 @@
|
|
|
83
88
|
"lint:pr-checks": "node scripts/lint-pr-check-project-dir.cjs",
|
|
84
89
|
"lint:changeset": "node scripts/changeset/lint.cjs",
|
|
85
90
|
"lint:docs": "node scripts/lint-docs-required.cjs",
|
|
91
|
+
"lint:legacy-name": "node scripts/lint-legacy-dir-name.cjs",
|
|
86
92
|
"ci:test-scope": "node scripts/ci-test-scope.cjs",
|
|
87
93
|
"changeset": "node scripts/changeset/new.cjs",
|
|
88
94
|
"changelog:render": "node scripts/changeset/cli.cjs render",
|
|
@@ -93,8 +99,8 @@
|
|
|
93
99
|
"test:security": "node scripts/run-tests.cjs --suite security",
|
|
94
100
|
"test:slow": "node scripts/run-tests.cjs --suite slow",
|
|
95
101
|
"test:affected": "node scripts/run-affected-tests.cjs",
|
|
96
|
-
"test:coverage": "c8 --check-coverage --lines 70 --reporter text --include '
|
|
97
|
-
"test:coverage:unit": "c8 --check-coverage --lines 70 --reporter text --include '
|
|
102
|
+
"test:coverage": "c8 --check-coverage --lines 70 --reporter text --include 'gsd-core/bin/lib/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs",
|
|
103
|
+
"test:coverage:unit": "c8 --check-coverage --lines 70 --reporter text --include 'gsd-core/bin/lib/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs --suite unit",
|
|
98
104
|
"test:coverage:all": "npm run test:coverage",
|
|
99
105
|
"test:mutation": "stryker run",
|
|
100
106
|
"test:mutation:since": "stryker run --incremental --since origin/next"
|
|
@@ -25,7 +25,7 @@ const PR_FULL_SUITES = ['unit', 'integration', 'security'];
|
|
|
25
25
|
// Relative to repoRoot. We walk these to discover SUT-internal requires so that
|
|
26
26
|
// a change to a deep helper propagates through re-export chains to tests.
|
|
27
27
|
const SOURCE_TREES = [
|
|
28
|
-
'
|
|
28
|
+
'gsd-core/bin/lib',
|
|
29
29
|
'bin/lib',
|
|
30
30
|
'bin',
|
|
31
31
|
'scripts',
|
package/scripts/base64-scan.sh
CHANGED
|
@@ -217,6 +217,18 @@ extract_and_check_blobs() {
|
|
|
217
217
|
local found=0
|
|
218
218
|
local line_num=0
|
|
219
219
|
|
|
220
|
+
# Skip binary-by-content files (e.g. adversarial parser fixtures with embedded
|
|
221
|
+
# non-UTF8 / NUL bytes). They cannot meaningfully carry base64-obfuscated *text*,
|
|
222
|
+
# and feeding NUL bytes through the per-line scanner spawns thousands of bogus
|
|
223
|
+
# `base64 -d` subprocesses (the "ignored null byte" warnings) — slow enough to
|
|
224
|
+
# blow the job timeout on a large diff. `grep -Iq .` treats a binary file as
|
|
225
|
+
# non-matching, so this skips it with a coverage notice (collect_files already
|
|
226
|
+
# filters binary *extensions*; this catches binary *content* in text extensions).
|
|
227
|
+
if ! LC_ALL=C grep -Iq . "$file" 2>/dev/null; then
|
|
228
|
+
echo "SKIP: $file (binary content — base64 text scan not applicable)" >&2
|
|
229
|
+
return 0
|
|
230
|
+
fi
|
|
231
|
+
|
|
220
232
|
while IFS= read -r line; do
|
|
221
233
|
line_num=$((line_num + 1))
|
|
222
234
|
|
package/scripts/build-hooks.js
CHANGED
|
@@ -26,6 +26,9 @@ const STAGE_DIR = path.join(HOOKS_DIR, `.dist-staging-${process.pid}`);
|
|
|
26
26
|
const HOOKS_TO_COPY = [
|
|
27
27
|
'gsd-check-update-worker.js',
|
|
28
28
|
'gsd-check-update.js',
|
|
29
|
+
// Required by gsd-check-update-worker.js at runtime — must ship alongside it
|
|
30
|
+
// so require('./managed-hooks-registry.cjs') resolves in the installed hooks/ dir.
|
|
31
|
+
'managed-hooks-registry.cjs',
|
|
29
32
|
'gsd-context-monitor.js',
|
|
30
33
|
'gsd-prompt-guard.js',
|
|
31
34
|
'gsd-read-guard.js',
|
|
@@ -33,6 +36,7 @@ const HOOKS_TO_COPY = [
|
|
|
33
36
|
'gsd-statusline.js',
|
|
34
37
|
'gsd-update-banner.js',
|
|
35
38
|
'gsd-workflow-guard.js',
|
|
39
|
+
'gsd-worktree-path-guard.js',
|
|
36
40
|
// Community hooks (bash, opt-in via .planning/config.json hooks.community)
|
|
37
41
|
'gsd-session-state.sh',
|
|
38
42
|
'gsd-validate-commit.sh',
|
|
@@ -233,4 +237,4 @@ if (require.main === module) {
|
|
|
233
237
|
build();
|
|
234
238
|
}
|
|
235
239
|
|
|
236
|
-
module.exports = { HOOKS_TO_COPY };
|
|
240
|
+
module.exports = { HOOKS_TO_COPY, HOOKS_SUBDIRS_TO_COPY };
|
|
@@ -24,8 +24,8 @@ const { renderGithubReleaseNotes } = require('./github-release-notes.cjs');
|
|
|
24
24
|
const {
|
|
25
25
|
compareSemverCore,
|
|
26
26
|
isStableTripletSemver,
|
|
27
|
-
} = require('../../
|
|
28
|
-
const { packageName, repoSlug: defaultRepoSlug } = require('../../
|
|
27
|
+
} = require('../../gsd-core/bin/lib/semver-compare.cjs');
|
|
28
|
+
const { packageName, repoSlug: defaultRepoSlug } = require('../../gsd-core/bin/lib/package-identity.cjs');
|
|
29
29
|
|
|
30
30
|
function parseArgs(argv) {
|
|
31
31
|
const opts = {
|
|
@@ -4,7 +4,7 @@ const cp = require('node:child_process');
|
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
|
|
6
6
|
const { parseFragment } = require('./parse.cjs');
|
|
7
|
-
const { packageName, repoSlug: defaultRepoSlug } = require('../../
|
|
7
|
+
const { packageName, repoSlug: defaultRepoSlug } = require('../../gsd-core/bin/lib/package-identity.cjs');
|
|
8
8
|
|
|
9
9
|
const SECTION_ORDER = ['Fixed', 'Added', 'Changed', 'Deprecated', 'Removed', 'Security'];
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ const fs = require('node:fs');
|
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
|
|
6
6
|
const ROOT = path.resolve(__dirname, '..');
|
|
7
|
-
const aliasesPath = path.join(ROOT, '
|
|
7
|
+
const aliasesPath = path.join(ROOT, 'gsd-core', 'bin', 'lib', 'command-aliases.cjs');
|
|
8
8
|
|
|
9
9
|
function fail(message) {
|
|
10
10
|
process.stderr.write(`${message}\n`);
|
|
@@ -37,37 +37,37 @@ const families = [
|
|
|
37
37
|
{
|
|
38
38
|
commandAliases: 'STATE_COMMAND_ALIASES',
|
|
39
39
|
subcommands: 'STATE_SUBCOMMANDS',
|
|
40
|
-
routerPath: path.join(ROOT, '
|
|
40
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'state-command-router.cjs'),
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
commandAliases: 'VERIFY_COMMAND_ALIASES',
|
|
44
44
|
subcommands: 'VERIFY_SUBCOMMANDS',
|
|
45
|
-
routerPath: path.join(ROOT, '
|
|
45
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'verify-command-router.cjs'),
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
commandAliases: 'INIT_COMMAND_ALIASES',
|
|
49
49
|
subcommands: 'INIT_SUBCOMMANDS',
|
|
50
|
-
routerPath: path.join(ROOT, '
|
|
50
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'init-command-router.cjs'),
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
commandAliases: 'PHASE_COMMAND_ALIASES',
|
|
54
54
|
subcommands: 'PHASE_SUBCOMMANDS',
|
|
55
|
-
routerPath: path.join(ROOT, '
|
|
55
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'phase-command-router.cjs'),
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
commandAliases: 'PHASES_COMMAND_ALIASES',
|
|
59
59
|
subcommands: 'PHASES_SUBCOMMANDS',
|
|
60
|
-
routerPath: path.join(ROOT, '
|
|
60
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'phases-command-router.cjs'),
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
commandAliases: 'VALIDATE_COMMAND_ALIASES',
|
|
64
64
|
subcommands: 'VALIDATE_SUBCOMMANDS',
|
|
65
|
-
routerPath: path.join(ROOT, '
|
|
65
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'validate-command-router.cjs'),
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
68
|
commandAliases: 'ROADMAP_COMMAND_ALIASES',
|
|
69
69
|
subcommands: 'ROADMAP_SUBCOMMANDS',
|
|
70
|
-
routerPath: path.join(ROOT, '
|
|
70
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'roadmap-command-router.cjs'),
|
|
71
71
|
},
|
|
72
72
|
];
|
|
73
73
|
|
package/scripts/check-env.cjs
CHANGED
|
@@ -212,7 +212,11 @@ if (fs.existsSync(LOCKFILE)) {
|
|
|
212
212
|
// ---------------------------------------------------------------------------
|
|
213
213
|
if (fs.existsSync(LOCKFILE)) {
|
|
214
214
|
try {
|
|
215
|
-
|
|
215
|
+
// --ignore-scripts: this is a lockfile-vs-package.json sync check, not a
|
|
216
|
+
// build. Without it, npm would run the `prepare` lifecycle (build:lib via
|
|
217
|
+
// tsc) — which fails when check:env runs before deps are installed (tsc
|
|
218
|
+
// absent), misreporting an out-of-sync lockfile. ADR-457 build-at-publish.
|
|
219
|
+
const res = spawnSync(npmCmd, ['ci', '--dry-run', '--ignore-scripts'], {
|
|
216
220
|
cwd: PROJECT_ROOT,
|
|
217
221
|
encoding: 'utf8',
|
|
218
222
|
shell: process.platform === 'win32',
|
|
@@ -42,10 +42,20 @@ const RULES = [
|
|
|
42
42
|
'tests/bug-3588-npm-audit-clean.test.cjs',
|
|
43
43
|
],
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
name: 'TS runtime sources (ADR-457 build-at-publish)',
|
|
47
|
+
// src/*.cts compiles into gsd-core/bin/lib/*.cjs; a source-only edit must
|
|
48
|
+
// still trigger the migrated module's tests (otherwise CI silently skips them).
|
|
49
|
+
match: path => path.startsWith('src/') || path === 'tsconfig.build.json',
|
|
50
|
+
tests: [
|
|
51
|
+
'tests/semver-compare.test.cjs',
|
|
52
|
+
'tests/bug-10-semver-policy-consolidation.test.cjs',
|
|
53
|
+
],
|
|
54
|
+
},
|
|
45
55
|
{
|
|
46
56
|
name: 'installer and package layout',
|
|
47
57
|
match: path => path.startsWith('bin/') ||
|
|
48
|
-
path.startsWith('
|
|
58
|
+
path.startsWith('gsd-core/bin/') ||
|
|
49
59
|
path.includes('install') ||
|
|
50
60
|
path.includes('release-tarball-smoke'),
|
|
51
61
|
fullMatrix: true,
|
|
@@ -112,7 +122,7 @@ const RULES = [
|
|
|
112
122
|
},
|
|
113
123
|
{
|
|
114
124
|
name: 'workflow prompts',
|
|
115
|
-
match: path => path.startsWith('
|
|
125
|
+
match: path => path.startsWith('gsd-core/workflows/'),
|
|
116
126
|
tests: [
|
|
117
127
|
'tests/workflow-compat.test.cjs',
|
|
118
128
|
'tests/workflow-size-budget.test.cjs',
|
|
@@ -143,7 +153,7 @@ const RULES = [
|
|
|
143
153
|
},
|
|
144
154
|
{
|
|
145
155
|
name: 'configuration',
|
|
146
|
-
match: path =>
|
|
156
|
+
match: path => ['config', 'configuration', 'model-catalog', 'model-profile'].some(k => path.includes(k)),
|
|
147
157
|
tests: [
|
|
148
158
|
'tests/config.test.cjs',
|
|
149
159
|
'tests/config-get-default.test.cjs',
|
|
@@ -198,7 +208,19 @@ function parseArgs(argv) {
|
|
|
198
208
|
|
|
199
209
|
function splitFiles(value) {
|
|
200
210
|
if (!value) return [];
|
|
201
|
-
|
|
211
|
+
const SEPARATORS = new Set([',', ' ', '\t', '\n', '\r', '\f', '\v']);
|
|
212
|
+
const tokens = [];
|
|
213
|
+
let current = '';
|
|
214
|
+
for (const ch of value) {
|
|
215
|
+
if (SEPARATORS.has(ch)) {
|
|
216
|
+
if (current) tokens.push(current);
|
|
217
|
+
current = '';
|
|
218
|
+
} else {
|
|
219
|
+
current += ch;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (current) tokens.push(current);
|
|
223
|
+
return tokens.map(v => v.trim()).filter(Boolean);
|
|
202
224
|
}
|
|
203
225
|
|
|
204
226
|
function changedFiles(args) {
|
|
@@ -221,6 +243,9 @@ function addAll(set, values) {
|
|
|
221
243
|
for (const value of values) set.add(value);
|
|
222
244
|
}
|
|
223
245
|
|
|
246
|
+
const WINDOWS_HINTS = ['windows', 'path', 'shell', 'workflow', 'install', 'hook'];
|
|
247
|
+
const isWindowsHint = s => WINDOWS_HINTS.some(k => s.toLowerCase().includes(k));
|
|
248
|
+
|
|
224
249
|
function classify(files) {
|
|
225
250
|
const targeted = new Set();
|
|
226
251
|
const windows = new Set();
|
|
@@ -229,9 +254,9 @@ function classify(files) {
|
|
|
229
254
|
let fullMatrix = false;
|
|
230
255
|
|
|
231
256
|
for (const file of files) {
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
257
|
+
if (['bin/', 'gsd-core/', 'agents/', 'commands/', 'docs/', 'hooks/', 'tests/', 'scripts/'].some(p => file.startsWith(p)) ||
|
|
258
|
+
file === 'package.json' || file === 'package-lock.json' ||
|
|
259
|
+
(file.startsWith('tsconfig') && file.endsWith('.json')) ||
|
|
235
260
|
file.startsWith('.github/workflows/') ||
|
|
236
261
|
file.startsWith('.github/rulesets/')) {
|
|
237
262
|
codeChanged = true;
|
|
@@ -240,7 +265,7 @@ function classify(files) {
|
|
|
240
265
|
if (file.startsWith('tests/') && file.endsWith('.test.cjs')) {
|
|
241
266
|
targeted.add(file);
|
|
242
267
|
fullMatrix = true;
|
|
243
|
-
if (
|
|
268
|
+
if (isWindowsHint(file)) {
|
|
244
269
|
windows.add(file);
|
|
245
270
|
}
|
|
246
271
|
}
|
|
@@ -262,7 +287,7 @@ function classify(files) {
|
|
|
262
287
|
targetedTests.push('unit');
|
|
263
288
|
}
|
|
264
289
|
|
|
265
|
-
const windowsTests = existingTests([...new Set([...windows, ...targetedTests.filter(
|
|
290
|
+
const windowsTests = existingTests([...new Set([...windows, ...targetedTests.filter(isWindowsHint)])].sort());
|
|
266
291
|
|
|
267
292
|
return {
|
|
268
293
|
code_changed: codeChanged,
|
|
@@ -54,7 +54,7 @@ function executionContextRefs(content) {
|
|
|
54
54
|
const trailingProse = line.length > token.length;
|
|
55
55
|
const normalized = token
|
|
56
56
|
.replace(/^@(?:~|\$HOME)\//, '')
|
|
57
|
-
.replace(/^(?:\.claude\/)?(?:
|
|
57
|
+
.replace(/^(?:\.claude\/)?(?:gsd-core\/)?/, '');
|
|
58
58
|
refs.push({ token, normalized, trailingProse });
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -20,11 +20,11 @@ const path = require('node:path');
|
|
|
20
20
|
|
|
21
21
|
const COMMANDS_DIR = path.join(__dirname, '..', 'commands', 'gsd');
|
|
22
22
|
const SEARCH_DIRS = [
|
|
23
|
-
path.join(__dirname, '..', '
|
|
24
|
-
path.join(__dirname, '..', '
|
|
25
|
-
path.join(__dirname, '..', '
|
|
26
|
-
path.join(__dirname, '..', '
|
|
27
|
-
path.join(__dirname, '..', '
|
|
23
|
+
path.join(__dirname, '..', 'gsd-core', 'bin', 'lib'),
|
|
24
|
+
path.join(__dirname, '..', 'gsd-core', 'workflows'),
|
|
25
|
+
path.join(__dirname, '..', 'gsd-core', 'references'),
|
|
26
|
+
path.join(__dirname, '..', 'gsd-core', 'templates'),
|
|
27
|
+
path.join(__dirname, '..', 'gsd-core', 'contexts'),
|
|
28
28
|
path.join(__dirname, '..', 'commands', 'gsd'),
|
|
29
29
|
path.join(__dirname, '..', 'agents'),
|
|
30
30
|
path.join(__dirname, '..', 'hooks'),
|
|
@@ -34,19 +34,19 @@ const FAMILIES = [
|
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
name: 'workflows',
|
|
37
|
-
dir: path.join(ROOT, '
|
|
37
|
+
dir: path.join(ROOT, 'gsd-core', 'workflows'),
|
|
38
38
|
filter: (f) => f.endsWith('.md'),
|
|
39
39
|
toName: (f) => f,
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
name: 'references',
|
|
43
|
-
dir: path.join(ROOT, '
|
|
43
|
+
dir: path.join(ROOT, 'gsd-core', 'references'),
|
|
44
44
|
filter: (f) => f.endsWith('.md'),
|
|
45
45
|
toName: (f) => f,
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
name: 'cli_modules',
|
|
49
|
-
dir: path.join(ROOT, '
|
|
49
|
+
dir: path.join(ROOT, 'gsd-core', 'bin', 'lib'),
|
|
50
50
|
filter: (f) => f.endsWith('.cjs'),
|
|
51
51
|
toName: (f) => f,
|
|
52
52
|
},
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* `deriveIdentity(pkg)` is the pure core: it turns a parsed package.json into
|
|
8
8
|
* the coordinate record every consumer needs. The generated runtime module
|
|
9
|
-
* `
|
|
9
|
+
* `gsd-core/bin/lib/package-identity.cjs` bakes those values at build
|
|
10
10
|
* time, because the installed tree carries only a synthetic
|
|
11
11
|
* `{"type":"commonjs"}` package.json (no `.name`) — so a runtime
|
|
12
12
|
* `require('package.json').name` resolves to `undefined` (the #378 bug this
|
|
@@ -24,6 +24,21 @@ function parseRepoSlug(repository) {
|
|
|
24
24
|
return m ? m[1] : '';
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Pure: turn an npm package name into a filesystem-safe slug for cache filenames.
|
|
29
|
+
* Strips a leading `@`, replaces `/` with `-`, then collapses any run of
|
|
30
|
+
* characters that are NOT `[a-z0-9]` to a single `-`, and trims leading/trailing `-`.
|
|
31
|
+
*/
|
|
32
|
+
function slugifyPackageName(name) {
|
|
33
|
+
if (!name) return '';
|
|
34
|
+
return name
|
|
35
|
+
.replace(/^@/, '')
|
|
36
|
+
.replace(/\//g, '-')
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
39
|
+
.replace(/^-+|-+$/g, '');
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
/**
|
|
28
43
|
* Pure: package.json object -> the package identity coordinates.
|
|
29
44
|
*/
|
|
@@ -35,7 +50,9 @@ function deriveIdentity(pkg = {}) {
|
|
|
35
50
|
const changelogRawUrl = repoSlug
|
|
36
51
|
? `https://raw.githubusercontent.com/${repoSlug}/main/CHANGELOG.md`
|
|
37
52
|
: '';
|
|
38
|
-
|
|
53
|
+
const cacheSlug = slugifyPackageName(packageName);
|
|
54
|
+
const updateCacheFileName = cacheSlug ? `gsd-update-check-${cacheSlug}.json` : 'gsd-update-check.json';
|
|
55
|
+
return { packageName, binName, repoSlug, repoUrl, changelogRawUrl, cacheSlug, updateCacheFileName };
|
|
39
56
|
}
|
|
40
57
|
|
|
41
58
|
/**
|
|
@@ -62,7 +79,7 @@ const GENERATED_HEADER =
|
|
|
62
79
|
* runtime command builder is byte-identical to the tested source above.
|
|
63
80
|
*/
|
|
64
81
|
function render(identity) {
|
|
65
|
-
const { packageName, binName, repoSlug, repoUrl, changelogRawUrl } = identity;
|
|
82
|
+
const { packageName, binName, repoSlug, repoUrl, changelogRawUrl, cacheSlug, updateCacheFileName } = identity;
|
|
66
83
|
const j = (v) => JSON.stringify(v);
|
|
67
84
|
return (
|
|
68
85
|
GENERATED_HEADER +
|
|
@@ -71,7 +88,9 @@ function render(identity) {
|
|
|
71
88
|
`const binName = ${j(binName)};\n` +
|
|
72
89
|
`const repoSlug = ${j(repoSlug)};\n` +
|
|
73
90
|
`const repoUrl = ${j(repoUrl)};\n` +
|
|
74
|
-
`const changelogRawUrl = ${j(changelogRawUrl)};\n
|
|
91
|
+
`const changelogRawUrl = ${j(changelogRawUrl)};\n` +
|
|
92
|
+
`const cacheSlug = ${j(cacheSlug)};\n` +
|
|
93
|
+
`const updateCacheFileName = ${j(updateCacheFileName)};\n\n` +
|
|
75
94
|
`${formatManualInstall.toString()}\n\n` +
|
|
76
95
|
'function manualInstallCommand(opts = {}) {\n' +
|
|
77
96
|
' return formatManualInstall({ packageName, binName, scope: opts.scope, runtime: opts.runtime });\n' +
|
|
@@ -79,12 +98,14 @@ function render(identity) {
|
|
|
79
98
|
'module.exports = Object.freeze({\n' +
|
|
80
99
|
' packageName,\n' +
|
|
81
100
|
' // PACKAGE_NAME: back-compat alias for #516-era consumers. Baked here, so it\n' +
|
|
82
|
-
|
|
101
|
+
" // survives the installed tree's synthetic package.json (fixes the #378 undefined).\n" +
|
|
83
102
|
' PACKAGE_NAME: packageName,\n' +
|
|
84
103
|
' binName,\n' +
|
|
85
104
|
' repoSlug,\n' +
|
|
86
105
|
' repoUrl,\n' +
|
|
87
106
|
' changelogRawUrl,\n' +
|
|
107
|
+
' cacheSlug,\n' +
|
|
108
|
+
' updateCacheFileName,\n' +
|
|
88
109
|
' manualInstallCommand,\n' +
|
|
89
110
|
'});\n'
|
|
90
111
|
);
|
|
@@ -94,11 +115,11 @@ function main() {
|
|
|
94
115
|
const fs = require('node:fs');
|
|
95
116
|
const path = require('node:path');
|
|
96
117
|
const pkg = require(path.join(__dirname, '..', 'package.json'));
|
|
97
|
-
const out = path.join(__dirname, '..', '
|
|
118
|
+
const out = path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'package-identity.cjs');
|
|
98
119
|
fs.writeFileSync(out, render(deriveIdentity(pkg)));
|
|
99
120
|
process.stdout.write(`wrote ${path.relative(path.join(__dirname, '..'), out)}\n`);
|
|
100
121
|
}
|
|
101
122
|
|
|
102
123
|
if (require.main === module) main();
|
|
103
124
|
|
|
104
|
-
module.exports = { deriveIdentity, parseRepoSlug, formatManualInstall, render, main };
|
|
125
|
+
module.exports = { deriveIdentity, parseRepoSlug, slugifyPackageName, formatManualInstall, render, main };
|