@therocketcode/gsd-core 1.4.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/.claude-plugin/plugin.json +23 -0
- package/GEMINI.md +53 -0
- package/LICENSE +21 -0
- package/README.ja-JP.md +125 -0
- package/README.ko-KR.md +125 -0
- package/README.md +144 -0
- package/README.pt-BR.md +125 -0
- package/README.zh-CN.md +125 -0
- package/agents/gsd-advisor-researcher.md +108 -0
- package/agents/gsd-ai-researcher.md +114 -0
- package/agents/gsd-assumptions-analyzer.md +105 -0
- package/agents/gsd-code-fixer.md +668 -0
- package/agents/gsd-code-reviewer.md +387 -0
- package/agents/gsd-codebase-mapper.md +853 -0
- package/agents/gsd-debug-session-manager.md +314 -0
- package/agents/gsd-debugger.md +1452 -0
- package/agents/gsd-doc-classifier.md +168 -0
- package/agents/gsd-doc-synthesizer.md +204 -0
- package/agents/gsd-doc-verifier.md +217 -0
- package/agents/gsd-doc-writer.md +616 -0
- package/agents/gsd-domain-researcher.md +147 -0
- package/agents/gsd-eval-auditor.md +191 -0
- package/agents/gsd-eval-planner.md +154 -0
- package/agents/gsd-executor.md +785 -0
- package/agents/gsd-framework-selector.md +160 -0
- package/agents/gsd-integration-checker.md +470 -0
- package/agents/gsd-intel-updater.md +342 -0
- package/agents/gsd-nyquist-auditor.md +203 -0
- package/agents/gsd-pattern-mapper.md +335 -0
- package/agents/gsd-phase-researcher.md +867 -0
- package/agents/gsd-plan-checker.md +978 -0
- package/agents/gsd-planner.md +1204 -0
- package/agents/gsd-project-researcher.md +611 -0
- package/agents/gsd-research-synthesizer.md +259 -0
- package/agents/gsd-roadmapper.md +688 -0
- package/agents/gsd-security-auditor.md +155 -0
- package/agents/gsd-ui-auditor.md +495 -0
- package/agents/gsd-ui-checker.md +309 -0
- package/agents/gsd-ui-researcher.md +374 -0
- package/agents/gsd-user-profiler.md +171 -0
- package/agents/gsd-verifier.md +923 -0
- 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 +12726 -0
- package/bin/lib/ui-safety-gate.cjs +107 -0
- package/commands/gsd/add-tests.md +42 -0
- package/commands/gsd/ai-integration-phase.md +37 -0
- package/commands/gsd/audit-fix.md +34 -0
- package/commands/gsd/audit-milestone.md +37 -0
- package/commands/gsd/audit-uat.md +24 -0
- package/commands/gsd/autonomous.md +48 -0
- package/commands/gsd/capture.md +62 -0
- package/commands/gsd/cleanup.md +24 -0
- package/commands/gsd/code-review.md +59 -0
- package/commands/gsd/complete-milestone.md +143 -0
- package/commands/gsd/config.md +56 -0
- package/commands/gsd/debug.md +52 -0
- package/commands/gsd/discover-product.md +65 -0
- package/commands/gsd/discuss-phase.md +77 -0
- package/commands/gsd/docs-update.md +49 -0
- package/commands/gsd/eval-review.md +33 -0
- package/commands/gsd/execute-phase.md +66 -0
- package/commands/gsd/explore.md +27 -0
- package/commands/gsd/extract-learnings.md +23 -0
- package/commands/gsd/fast.md +31 -0
- package/commands/gsd/forensics.md +57 -0
- package/commands/gsd/graphify.md +204 -0
- package/commands/gsd/health.md +31 -0
- package/commands/gsd/help.md +28 -0
- package/commands/gsd/import.md +45 -0
- package/commands/gsd/inbox.md +39 -0
- package/commands/gsd/ingest-docs.md +42 -0
- package/commands/gsd/manager.md +45 -0
- package/commands/gsd/map-codebase.md +83 -0
- package/commands/gsd/milestone-summary.md +51 -0
- package/commands/gsd/model-domain.md +65 -0
- package/commands/gsd/mvp-phase.md +45 -0
- package/commands/gsd/new-milestone.md +45 -0
- package/commands/gsd/new-project.md +47 -0
- package/commands/gsd/ns-context.md +23 -0
- package/commands/gsd/ns-ideate.md +24 -0
- package/commands/gsd/ns-manage.md +29 -0
- package/commands/gsd/ns-project.md +22 -0
- package/commands/gsd/ns-review.md +26 -0
- package/commands/gsd/ns-workflow.md +28 -0
- package/commands/gsd/pause-work.md +43 -0
- package/commands/gsd/phase.md +56 -0
- package/commands/gsd/plan-phase.md +64 -0
- package/commands/gsd/plan-review-convergence.md +59 -0
- package/commands/gsd/pr-branch.md +26 -0
- package/commands/gsd/profile-user.md +46 -0
- package/commands/gsd/progress.md +48 -0
- package/commands/gsd/quick.md +174 -0
- package/commands/gsd/recommend-architecture.md +64 -0
- package/commands/gsd/resume-work.md +30 -0
- package/commands/gsd/review-backlog.md +63 -0
- package/commands/gsd/review.md +42 -0
- package/commands/gsd/secure-phase.md +36 -0
- package/commands/gsd/settings.md +29 -0
- package/commands/gsd/ship.md +24 -0
- package/commands/gsd/sketch.md +60 -0
- package/commands/gsd/spec-phase.md +63 -0
- package/commands/gsd/spike.md +57 -0
- package/commands/gsd/stats.md +20 -0
- package/commands/gsd/surface.md +155 -0
- package/commands/gsd/testing-strategy.md +65 -0
- package/commands/gsd/thread.md +24 -0
- package/commands/gsd/ui-phase.md +35 -0
- package/commands/gsd/ui-review.md +33 -0
- package/commands/gsd/ultraplan-phase.md +34 -0
- package/commands/gsd/undo.md +35 -0
- package/commands/gsd/update.md +49 -0
- package/commands/gsd/validate-phase.md +36 -0
- package/commands/gsd/verify-work.md +39 -0
- package/commands/gsd/workspace.md +52 -0
- package/commands/gsd/workstreams.md +70 -0
- package/gemini-extension.json +6 -0
- package/gsd-core/bin/check-latest-version.cjs +161 -0
- package/gsd-core/bin/gsd-tools.cjs +1928 -0
- 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 +343 -0
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
- package/gsd-core/bin/lib/cli-exit.cjs +42 -0
- package/gsd-core/bin/lib/clock.cjs +95 -0
- package/gsd-core/bin/lib/clusters.cjs +132 -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 +1203 -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 +738 -0
- package/gsd-core/bin/lib/configuration.cjs +239 -0
- package/gsd-core/bin/lib/context-utilization.cjs +48 -0
- package/gsd-core/bin/lib/core.cjs +2051 -0
- package/gsd-core/bin/lib/decisions.cjs +118 -0
- 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 +1815 -0
- package/gsd-core/bin/lib/install-profiles.cjs +584 -0
- package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
- package/gsd-core/bin/lib/installer-migration-report.cjs +350 -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 +823 -0
- package/gsd-core/bin/lib/intel.cjs +590 -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/gsd-core/bin/lib/observability/redaction.cjs +48 -0
- package/gsd-core/bin/lib/package-identity.cjs +35 -0
- package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
- 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/gsd-core/bin/lib/plan-scan.cjs +91 -0
- 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/research-provider.cjs +137 -0
- package/gsd-core/bin/lib/research-store.cjs +167 -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 +476 -0
- package/gsd-core/bin/lib/roadmap.cjs +600 -0
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +312 -0
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +56 -0
- package/gsd-core/bin/lib/runtime-homes.cjs +190 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
- package/gsd-core/bin/lib/schema-detect.cjs +159 -0
- package/gsd-core/bin/lib/secrets.cjs +34 -0
- package/gsd-core/bin/lib/security.cjs +480 -0
- package/gsd-core/bin/lib/semver-compare.cjs +42 -0
- package/gsd-core/bin/lib/shell-command-projection.cjs +533 -0
- package/gsd-core/bin/lib/state-command-router.cjs +160 -0
- package/gsd-core/bin/lib/state-document.cjs +259 -0
- package/gsd-core/bin/lib/state.cjs +2010 -0
- package/gsd-core/bin/lib/surface.cjs +449 -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/verification-command-router.cjs +31 -0
- package/gsd-core/bin/lib/verification.cjs +193 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
- package/gsd-core/bin/lib/verify.cjs +1451 -0
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +81 -0
- package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
- package/gsd-core/bin/lib/workstream-name-policy.cjs +91 -0
- package/gsd-core/bin/lib/workstream.cjs +380 -0
- package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
- package/gsd-core/bin/lib/worktree-safety.cjs +943 -0
- package/gsd-core/bin/shared/config-defaults.manifest.json +98 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +192 -0
- package/gsd-core/bin/shared/model-catalog.json +149 -0
- package/gsd-core/bin/shared/runtime-aliases.manifest.json +75 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +349 -0
- package/gsd-core/contexts/dev.md +21 -0
- package/gsd-core/contexts/research.md +22 -0
- package/gsd-core/contexts/review.md +23 -0
- package/gsd-core/references/agent-contracts.md +79 -0
- package/gsd-core/references/ai-evals.md +156 -0
- package/gsd-core/references/ai-frameworks.md +186 -0
- package/gsd-core/references/architecture-decision.md +74 -0
- package/gsd-core/references/artifact-types.md +131 -0
- package/gsd-core/references/auth-in-tests.md +91 -0
- package/gsd-core/references/autonomous-smart-discuss.md +277 -0
- package/gsd-core/references/checkpoints.md +814 -0
- package/gsd-core/references/common-bug-patterns.md +114 -0
- package/gsd-core/references/context-budget.md +85 -0
- package/gsd-core/references/continuation-format.md +253 -0
- package/gsd-core/references/db-test-isolation.md +54 -0
- package/gsd-core/references/debugger-philosophy.md +76 -0
- package/gsd-core/references/decimal-phase-calculation.md +64 -0
- package/gsd-core/references/doc-conflict-engine.md +91 -0
- package/gsd-core/references/domain-modeling.md +80 -0
- package/gsd-core/references/domain-probes.md +125 -0
- package/gsd-core/references/e2e-tiering.md +35 -0
- package/gsd-core/references/execute-mvp-tdd.md +81 -0
- package/gsd-core/references/executor-examples.md +110 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +73 -0
- package/gsd-core/references/few-shot-examples/verifier.md +109 -0
- package/gsd-core/references/flaky-test-checklist.md +22 -0
- package/gsd-core/references/gate-prompts.md +100 -0
- package/gsd-core/references/gates.md +70 -0
- package/gsd-core/references/git-integration.md +298 -0
- package/gsd-core/references/git-planning-commit.md +40 -0
- package/gsd-core/references/ios-scaffold.md +123 -0
- package/gsd-core/references/mandatory-initial-read.md +2 -0
- package/gsd-core/references/model-profile-resolution.md +38 -0
- package/gsd-core/references/model-profiles.md +245 -0
- package/gsd-core/references/mvp-concepts.md +49 -0
- package/gsd-core/references/phase-argument-parsing.md +61 -0
- package/gsd-core/references/planner-antipatterns.md +89 -0
- package/gsd-core/references/planner-chunked.md +49 -0
- package/gsd-core/references/planner-gap-closure.md +62 -0
- package/gsd-core/references/planner-graphify-auto-update.md +67 -0
- package/gsd-core/references/planner-human-verify-mode.md +57 -0
- package/gsd-core/references/planner-interface-context.md +62 -0
- package/gsd-core/references/planner-load-graph-context.md +36 -0
- package/gsd-core/references/planner-mvp-mode.md +53 -0
- package/gsd-core/references/planner-reviews.md +39 -0
- package/gsd-core/references/planner-revision.md +87 -0
- package/gsd-core/references/planner-source-audit.md +73 -0
- package/gsd-core/references/planning-config.md +473 -0
- package/gsd-core/references/product-discovery.md +49 -0
- package/gsd-core/references/project-skills-discovery.md +19 -0
- package/gsd-core/references/questioning.md +162 -0
- package/gsd-core/references/realistic-test-data.md +44 -0
- package/gsd-core/references/research-documentation-lookup.md +29 -0
- package/gsd-core/references/research-philosophy.md +29 -0
- package/gsd-core/references/research-verification-protocol.md +27 -0
- package/gsd-core/references/revision-loop.md +97 -0
- package/gsd-core/references/scout-codebase.md +51 -0
- package/gsd-core/references/skeleton-template.md +48 -0
- package/gsd-core/references/sketch-interactivity.md +41 -0
- package/gsd-core/references/sketch-theme-system.md +94 -0
- package/gsd-core/references/sketch-tooling.md +45 -0
- package/gsd-core/references/sketch-variant-patterns.md +81 -0
- package/gsd-core/references/spidr-splitting.md +69 -0
- package/gsd-core/references/tdd.md +330 -0
- package/gsd-core/references/test-containers.md +55 -0
- package/gsd-core/references/test-strategy.md +75 -0
- package/gsd-core/references/thinking-models-debug.md +44 -0
- package/gsd-core/references/thinking-models-execution.md +50 -0
- package/gsd-core/references/thinking-models-planning.md +62 -0
- package/gsd-core/references/thinking-models-research.md +50 -0
- package/gsd-core/references/thinking-models-verification.md +55 -0
- package/gsd-core/references/thinking-partner.md +96 -0
- package/gsd-core/references/ui-brand.md +162 -0
- package/gsd-core/references/universal-anti-patterns.md +63 -0
- package/gsd-core/references/user-profiling.md +681 -0
- package/gsd-core/references/user-story-template.md +58 -0
- package/gsd-core/references/verification-overrides.md +227 -0
- package/gsd-core/references/verification-patterns.md +612 -0
- package/gsd-core/references/verify-mvp-mode.md +85 -0
- package/gsd-core/references/workstream-flag.md +111 -0
- package/gsd-core/references/worktree-branch-check.md +38 -0
- package/gsd-core/references/worktree-path-safety.md +67 -0
- package/gsd-core/templates/AI-SPEC.md +246 -0
- package/gsd-core/templates/DEBUG.md +169 -0
- package/gsd-core/templates/README.md +77 -0
- package/gsd-core/templates/SECURITY.md +61 -0
- package/gsd-core/templates/UAT.md +265 -0
- package/gsd-core/templates/UI-SPEC.md +100 -0
- package/gsd-core/templates/VALIDATION.md +76 -0
- package/gsd-core/templates/adr.md +58 -0
- package/gsd-core/templates/claude-md.md +145 -0
- package/gsd-core/templates/codebase/architecture.md +255 -0
- package/gsd-core/templates/codebase/concerns.md +310 -0
- package/gsd-core/templates/codebase/conventions.md +307 -0
- package/gsd-core/templates/codebase/integrations.md +280 -0
- package/gsd-core/templates/codebase/stack.md +186 -0
- package/gsd-core/templates/codebase/structure.md +285 -0
- package/gsd-core/templates/codebase/testing.md +480 -0
- package/gsd-core/templates/config.json +62 -0
- package/gsd-core/templates/context.md +352 -0
- package/gsd-core/templates/continue-here.md +78 -0
- package/gsd-core/templates/copilot-instructions.md +7 -0
- package/gsd-core/templates/debug-subagent-prompt.md +91 -0
- package/gsd-core/templates/dev-preferences.md +21 -0
- package/gsd-core/templates/discovery.md +146 -0
- package/gsd-core/templates/discussion-log.md +63 -0
- package/gsd-core/templates/domain-model.md +54 -0
- package/gsd-core/templates/milestone-archive.md +123 -0
- package/gsd-core/templates/milestone.md +115 -0
- package/gsd-core/templates/phase-prompt.md +610 -0
- package/gsd-core/templates/planner-subagent-prompt.md +117 -0
- package/gsd-core/templates/product-brief.md +55 -0
- package/gsd-core/templates/project.md +186 -0
- package/gsd-core/templates/requirements.md +231 -0
- package/gsd-core/templates/research-project/ARCHITECTURE.md +204 -0
- package/gsd-core/templates/research-project/FEATURES.md +147 -0
- package/gsd-core/templates/research-project/PITFALLS.md +200 -0
- package/gsd-core/templates/research-project/STACK.md +120 -0
- package/gsd-core/templates/research-project/SUMMARY.md +170 -0
- package/gsd-core/templates/research.md +592 -0
- package/gsd-core/templates/retrospective.md +54 -0
- package/gsd-core/templates/roadmap.md +202 -0
- package/gsd-core/templates/spec.md +307 -0
- package/gsd-core/templates/state.md +195 -0
- package/gsd-core/templates/summary-complex.md +59 -0
- package/gsd-core/templates/summary-minimal.md +41 -0
- package/gsd-core/templates/summary-standard.md +48 -0
- package/gsd-core/templates/summary.md +248 -0
- package/gsd-core/templates/test-strategy.md +50 -0
- package/gsd-core/templates/user-profile.md +146 -0
- package/gsd-core/templates/user-setup.md +311 -0
- package/gsd-core/templates/verification-report.md +322 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
- package/gsd-core/workflows/add-backlog.md +91 -0
- package/gsd-core/workflows/add-phase.md +113 -0
- package/gsd-core/workflows/add-tests.md +355 -0
- package/gsd-core/workflows/add-todo.md +161 -0
- package/gsd-core/workflows/ai-integration-phase.md +295 -0
- package/gsd-core/workflows/analyze-dependencies.md +96 -0
- package/gsd-core/workflows/audit-fix.md +178 -0
- package/gsd-core/workflows/audit-milestone.md +360 -0
- package/gsd-core/workflows/audit-uat.md +110 -0
- package/gsd-core/workflows/autonomous.md +797 -0
- package/gsd-core/workflows/check-todos.md +180 -0
- package/gsd-core/workflows/cleanup.md +195 -0
- package/gsd-core/workflows/code-review-fix.md +502 -0
- package/gsd-core/workflows/code-review.md +658 -0
- package/gsd-core/workflows/complete-milestone.md +855 -0
- package/gsd-core/workflows/debug.md +237 -0
- package/gsd-core/workflows/diagnose-issues.md +245 -0
- package/gsd-core/workflows/discover-product.md +112 -0
- package/gsd-core/workflows/discovery-phase.md +291 -0
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +176 -0
- package/gsd-core/workflows/discuss-phase/modes/all.md +28 -0
- package/gsd-core/workflows/discuss-phase/modes/analyze.md +44 -0
- package/gsd-core/workflows/discuss-phase/modes/auto.md +57 -0
- package/gsd-core/workflows/discuss-phase/modes/batch.md +52 -0
- package/gsd-core/workflows/discuss-phase/modes/chain.md +98 -0
- package/gsd-core/workflows/discuss-phase/modes/default.md +141 -0
- package/gsd-core/workflows/discuss-phase/modes/power.md +44 -0
- package/gsd-core/workflows/discuss-phase/modes/text.md +55 -0
- package/gsd-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
- package/gsd-core/workflows/discuss-phase/templates/context.md +136 -0
- package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
- package/gsd-core/workflows/discuss-phase-assumptions.md +675 -0
- package/gsd-core/workflows/discuss-phase-power.md +291 -0
- package/gsd-core/workflows/discuss-phase.md +499 -0
- package/gsd-core/workflows/do.md +111 -0
- package/gsd-core/workflows/docs-update.md +1176 -0
- package/gsd-core/workflows/edit-phase.md +295 -0
- package/gsd-core/workflows/eval-review.md +156 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
- package/gsd-core/workflows/execute-phase.md +1752 -0
- package/gsd-core/workflows/execute-plan.md +526 -0
- package/gsd-core/workflows/explore.md +146 -0
- package/gsd-core/workflows/extract-learnings.md +243 -0
- package/gsd-core/workflows/fast.md +124 -0
- package/gsd-core/workflows/forensics.md +279 -0
- package/gsd-core/workflows/graduation.md +196 -0
- package/gsd-core/workflows/health.md +224 -0
- package/gsd-core/workflows/help/modes/brief.md +22 -0
- package/gsd-core/workflows/help/modes/default.md +50 -0
- package/gsd-core/workflows/help/modes/full.md +789 -0
- package/gsd-core/workflows/help/modes/topic.md +74 -0
- package/gsd-core/workflows/help.md +24 -0
- package/gsd-core/workflows/import.md +256 -0
- package/gsd-core/workflows/inbox.md +387 -0
- package/gsd-core/workflows/ingest-docs.md +340 -0
- package/gsd-core/workflows/insert-phase.md +152 -0
- package/gsd-core/workflows/list-phase-assumptions.md +178 -0
- package/gsd-core/workflows/list-workspaces.md +57 -0
- package/gsd-core/workflows/manager.md +393 -0
- package/gsd-core/workflows/map-codebase.md +446 -0
- package/gsd-core/workflows/milestone-summary.md +224 -0
- package/gsd-core/workflows/model-domain.md +162 -0
- package/gsd-core/workflows/mvp-phase.md +222 -0
- package/gsd-core/workflows/new-milestone.md +635 -0
- package/gsd-core/workflows/new-project.md +1555 -0
- package/gsd-core/workflows/new-workspace.md +240 -0
- package/gsd-core/workflows/next.md +299 -0
- package/gsd-core/workflows/node-repair.md +92 -0
- package/gsd-core/workflows/note.md +158 -0
- package/gsd-core/workflows/pause-work.md +244 -0
- package/gsd-core/workflows/plan-milestone-gaps.md +281 -0
- package/gsd-core/workflows/plan-phase.md +1814 -0
- package/gsd-core/workflows/plan-review-convergence.md +346 -0
- package/gsd-core/workflows/plant-seed.md +230 -0
- package/gsd-core/workflows/pr-branch.md +157 -0
- package/gsd-core/workflows/profile-user.md +453 -0
- package/gsd-core/workflows/progress.md +699 -0
- package/gsd-core/workflows/quick.md +1017 -0
- package/gsd-core/workflows/reapply-patches.md +426 -0
- package/gsd-core/workflows/recommend-architecture.md +135 -0
- package/gsd-core/workflows/remove-phase.md +156 -0
- package/gsd-core/workflows/remove-workspace.md +108 -0
- package/gsd-core/workflows/resume-project.md +332 -0
- package/gsd-core/workflows/review.md +748 -0
- package/gsd-core/workflows/scan.md +107 -0
- package/gsd-core/workflows/secure-phase.md +182 -0
- package/gsd-core/workflows/session-report.md +146 -0
- package/gsd-core/workflows/settings-advanced.md +810 -0
- package/gsd-core/workflows/settings-integrations.md +312 -0
- package/gsd-core/workflows/settings.md +566 -0
- package/gsd-core/workflows/ship.md +405 -0
- package/gsd-core/workflows/sketch-wrap-up.md +286 -0
- package/gsd-core/workflows/sketch.md +361 -0
- package/gsd-core/workflows/spec-phase.md +263 -0
- package/gsd-core/workflows/spike-wrap-up.md +307 -0
- package/gsd-core/workflows/spike.md +453 -0
- package/gsd-core/workflows/stats.md +80 -0
- package/gsd-core/workflows/sync-skills.md +182 -0
- package/gsd-core/workflows/testing-strategy.md +122 -0
- package/gsd-core/workflows/thread.md +222 -0
- package/gsd-core/workflows/transition.md +694 -0
- package/gsd-core/workflows/ui-phase.md +328 -0
- package/gsd-core/workflows/ui-review.md +193 -0
- package/gsd-core/workflows/ultraplan-phase.md +199 -0
- package/gsd-core/workflows/undo.md +314 -0
- package/gsd-core/workflows/update.md +496 -0
- package/gsd-core/workflows/validate-phase.md +181 -0
- package/gsd-core/workflows/verify-phase.md +544 -0
- package/gsd-core/workflows/verify-work.md +781 -0
- package/hooks/dist/gsd-check-update-worker.js +108 -0
- package/hooks/dist/gsd-check-update.js +66 -0
- package/hooks/dist/gsd-config-reload.js +133 -0
- package/hooks/dist/gsd-context-monitor.js +195 -0
- package/hooks/dist/gsd-cursor-post-tool.js +75 -0
- package/hooks/dist/gsd-cursor-session-start.js +52 -0
- package/hooks/dist/gsd-graphify-update.sh +158 -0
- package/hooks/dist/gsd-phase-boundary.sh +47 -0
- package/hooks/dist/gsd-prompt-guard.js +97 -0
- package/hooks/dist/gsd-read-guard.js +101 -0
- package/hooks/dist/gsd-read-injection-scanner.js +203 -0
- package/hooks/dist/gsd-session-state.sh +59 -0
- package/hooks/dist/gsd-statusline.js +566 -0
- package/hooks/dist/gsd-update-banner.js +138 -0
- package/hooks/dist/gsd-validate-commit.sh +57 -0
- package/hooks/dist/gsd-workflow-guard.js +167 -0
- package/hooks/dist/gsd-worktree-path-guard.js +169 -0
- package/hooks/dist/lib/git-cmd.js +150 -0
- package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
- package/hooks/dist/managed-hooks-registry.cjs +38 -0
- package/hooks/gsd-check-update-worker.js +108 -0
- package/hooks/gsd-check-update.js +66 -0
- package/hooks/gsd-config-reload.js +133 -0
- package/hooks/gsd-context-monitor.js +195 -0
- package/hooks/gsd-cursor-post-tool.js +75 -0
- package/hooks/gsd-cursor-session-start.js +52 -0
- package/hooks/gsd-graphify-update.sh +158 -0
- package/hooks/gsd-phase-boundary.sh +47 -0
- package/hooks/gsd-prompt-guard.js +97 -0
- package/hooks/gsd-read-guard.js +101 -0
- package/hooks/gsd-read-injection-scanner.js +203 -0
- package/hooks/gsd-session-state.sh +59 -0
- package/hooks/gsd-statusline.js +566 -0
- package/hooks/gsd-update-banner.js +138 -0
- package/hooks/gsd-validate-commit.sh +57 -0
- package/hooks/gsd-workflow-guard.js +167 -0
- package/hooks/gsd-worktree-path-guard.js +169 -0
- package/hooks/hooks.json +69 -0
- package/hooks/lib/git-cmd.js +150 -0
- package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
- package/hooks/managed-hooks-registry.cjs +38 -0
- package/package.json +115 -0
- package/scripts/affected-tests-lib.cjs +542 -0
- package/scripts/audit-workflow-script-paths.cjs +73 -0
- package/scripts/base64-scan.sh +351 -0
- package/scripts/build-hooks.js +247 -0
- package/scripts/changeset/README.md +129 -0
- package/scripts/changeset/cli.cjs +590 -0
- package/scripts/changeset/github-release-notes.cjs +199 -0
- package/scripts/changeset/lint.cjs +111 -0
- package/scripts/changeset/new.cjs +137 -0
- package/scripts/changeset/parse.cjs +114 -0
- package/scripts/changeset/render.cjs +34 -0
- package/scripts/changeset/serialize.cjs +130 -0
- package/scripts/check-alias-drift.cjs +114 -0
- package/scripts/check-env.cjs +312 -0
- package/scripts/check-npm-integrity.cjs +215 -0
- package/scripts/ci-guard-runner.cjs +22 -0
- package/scripts/ci-prepare-test-scope.cjs +51 -0
- package/scripts/ci-rebase-check.cjs +86 -0
- package/scripts/ci-test-scope.cjs +431 -0
- package/scripts/command-contract-helpers.cjs +64 -0
- package/scripts/diff-touches-shipped-paths.cjs +155 -0
- package/scripts/fix-slash-commands.cjs +147 -0
- package/scripts/gen-inventory-manifest.cjs +115 -0
- package/scripts/gen-research-agents.cjs +276 -0
- package/scripts/generate-package-identity.cjs +125 -0
- package/scripts/issue-dedupe.cjs +278 -0
- package/scripts/lib/allowlist-ratchet.cjs +136 -0
- package/scripts/lib/cli-exit.cjs +56 -0
- package/scripts/lint-command-contract.cjs +114 -0
- package/scripts/lint-descriptions.cjs +87 -0
- package/scripts/lint-docs-required.cjs +222 -0
- package/scripts/lint-legacy-dir-name.cjs +160 -0
- package/scripts/lint-package-identity-drift.cjs +141 -0
- package/scripts/lint-pr-check-project-dir.cjs +99 -0
- package/scripts/lint-shell-command-projection-drift.cjs +62 -0
- package/scripts/lint-skill-deps.cjs +185 -0
- package/scripts/lint-test-file-count.allowlist.json +135 -0
- package/scripts/lint-test-file-count.cjs +246 -0
- package/scripts/mutation-matrix.cjs +222 -0
- package/scripts/pr-template-policy.cjs +268 -0
- package/scripts/prompt-injection-scan.sh +207 -0
- package/scripts/release-notes/discord-release-summary.cjs +373 -0
- package/scripts/release-notes/format-github-release-notes.cjs +261 -0
- package/scripts/release-tarball-smoke.cjs +629 -0
- package/scripts/research-profiles.cjs +149 -0
- package/scripts/run-affected-tests.cjs +7 -0
- package/scripts/run-cross-platform-tests.cjs +67 -0
- package/scripts/run-tests.cjs +315 -0
- package/scripts/secret-scan-lint.sh +231 -0
- package/scripts/secret-scan.sh +358 -0
- package/scripts/setup-branch-protection.sh +236 -0
- package/scripts/strip-prose-atrefs.cjs +106 -0
- package/scripts/sync-manifest-versions.cjs +119 -0
- package/scripts/sync-rulesets.sh +34 -0
- package/scripts/sync-runtime-launcher.cjs +399 -0
- package/scripts/test-failure-reasons.cjs +34 -0
- package/scripts/verify-npm-publish.cjs +240 -0
- package/scripts/workflow-policy.cjs +450 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Learnings — Global knowledge store with CRUD operations
|
|
4
|
+
*
|
|
5
|
+
* Provides a cross-project learnings store at ~/.gsd/knowledge/.
|
|
6
|
+
* Each learning is stored as an individual JSON file with content-hash
|
|
7
|
+
* deduplication. Supports write, read, list, query, delete, copy-from-project,
|
|
8
|
+
* and prune operations.
|
|
9
|
+
*
|
|
10
|
+
* Storage format: { id, source_project, date, context, learning, tags, content_hash }
|
|
11
|
+
* File naming: {id}.json
|
|
12
|
+
* Deduplication: SHA-256 of learning text + source_project
|
|
13
|
+
*
|
|
14
|
+
* ADR-457 build-at-publish: the hand-written bin/lib/learnings.cjs collapsed
|
|
15
|
+
* to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
|
|
16
|
+
* from the prior hand-written .cjs; only strict types are added.
|
|
17
|
+
*/
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
22
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
23
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
24
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
26
|
+
const core = require("./core.cjs");
|
|
27
|
+
const { output, error: coreError } = core;
|
|
28
|
+
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
29
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
30
|
+
const DEFAULT_STORE_DIR = node_path_1.default.join(node_os_1.default.homedir(), '.gsd', 'knowledge');
|
|
31
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
32
|
+
function getStoreDir(opts) {
|
|
33
|
+
return (opts && opts.storeDir) || DEFAULT_STORE_DIR;
|
|
34
|
+
}
|
|
35
|
+
function ensureStoreDir(dir) {
|
|
36
|
+
if (!node_fs_1.default.existsSync(dir)) {
|
|
37
|
+
node_fs_1.default.mkdirSync(dir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function contentHash(learning, sourceProject) {
|
|
41
|
+
return node_crypto_1.default.createHash('sha256')
|
|
42
|
+
.update(learning + '\n' + sourceProject)
|
|
43
|
+
.digest('hex');
|
|
44
|
+
}
|
|
45
|
+
function generateId() {
|
|
46
|
+
const ts = Date.now().toString(36);
|
|
47
|
+
const rand = node_crypto_1.default.randomBytes(4).toString('hex');
|
|
48
|
+
return `${ts}-${rand}`;
|
|
49
|
+
}
|
|
50
|
+
function readLearningFile(filePath) {
|
|
51
|
+
try {
|
|
52
|
+
const content = node_fs_1.default.readFileSync(filePath, 'utf-8');
|
|
53
|
+
return JSON.parse(content);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
process.stderr.write(`Warning: skipping malformed file ${filePath}: ${err.message}\n`);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ─── CRUD Operations ─────────────────────────────────────────────────────────
|
|
61
|
+
function learningsWrite(entry, opts) {
|
|
62
|
+
const dir = getStoreDir(opts);
|
|
63
|
+
ensureStoreDir(dir);
|
|
64
|
+
const hash = contentHash(entry.learning, entry.source_project);
|
|
65
|
+
// #306: In bulk-import paths, callers may supply a pre-built dedupeIndex
|
|
66
|
+
// (Map<content_hash, id>) to avoid the per-write O(N) store scan.
|
|
67
|
+
if (opts && opts.dedupeIndex) {
|
|
68
|
+
const dedupeIndex = opts.dedupeIndex;
|
|
69
|
+
if (dedupeIndex.has(hash)) {
|
|
70
|
+
return { id: dedupeIndex.get(hash), created: false, content_hash: hash };
|
|
71
|
+
}
|
|
72
|
+
const id = generateId();
|
|
73
|
+
const record = {
|
|
74
|
+
id,
|
|
75
|
+
source_project: entry.source_project,
|
|
76
|
+
date: new Date().toISOString(),
|
|
77
|
+
context: entry.context || '',
|
|
78
|
+
learning: entry.learning,
|
|
79
|
+
tags: entry.tags || [],
|
|
80
|
+
content_hash: hash,
|
|
81
|
+
};
|
|
82
|
+
(0, shell_command_projection_cjs_1.platformWriteSync)(node_path_1.default.join(dir, `${id}.json`), JSON.stringify(record, null, 2));
|
|
83
|
+
dedupeIndex.set(hash, id);
|
|
84
|
+
return { id, created: true, content_hash: hash };
|
|
85
|
+
}
|
|
86
|
+
// Check for duplicate by scanning existing files (single-write path, unchanged)
|
|
87
|
+
const files = node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
88
|
+
for (const file of files) {
|
|
89
|
+
const existing = readLearningFile(node_path_1.default.join(dir, file));
|
|
90
|
+
if (existing && existing.content_hash === hash) {
|
|
91
|
+
return { id: existing.id, created: false, content_hash: hash };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const id = generateId();
|
|
95
|
+
const record = {
|
|
96
|
+
id,
|
|
97
|
+
source_project: entry.source_project,
|
|
98
|
+
date: new Date().toISOString(),
|
|
99
|
+
context: entry.context || '',
|
|
100
|
+
learning: entry.learning,
|
|
101
|
+
tags: entry.tags || [],
|
|
102
|
+
content_hash: hash,
|
|
103
|
+
};
|
|
104
|
+
(0, shell_command_projection_cjs_1.platformWriteSync)(node_path_1.default.join(dir, `${id}.json`), JSON.stringify(record, null, 2));
|
|
105
|
+
return { id, created: true, content_hash: hash };
|
|
106
|
+
}
|
|
107
|
+
function learningsRead(id, opts) {
|
|
108
|
+
if (!/^[a-z0-9]+-[a-f0-9]+$/.test(id))
|
|
109
|
+
return null;
|
|
110
|
+
const dir = getStoreDir(opts);
|
|
111
|
+
const filePath = node_path_1.default.join(dir, `${id}.json`);
|
|
112
|
+
if (!node_fs_1.default.existsSync(filePath))
|
|
113
|
+
return null;
|
|
114
|
+
return readLearningFile(filePath);
|
|
115
|
+
}
|
|
116
|
+
function learningsList(opts) {
|
|
117
|
+
const dir = getStoreDir(opts);
|
|
118
|
+
if (!node_fs_1.default.existsSync(dir))
|
|
119
|
+
return [];
|
|
120
|
+
const files = node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
121
|
+
const results = [];
|
|
122
|
+
for (const file of files) {
|
|
123
|
+
const record = readLearningFile(node_path_1.default.join(dir, file));
|
|
124
|
+
if (record)
|
|
125
|
+
results.push(record);
|
|
126
|
+
}
|
|
127
|
+
// Sort by date descending (newest first)
|
|
128
|
+
results.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
function learningsQuery(query, opts) {
|
|
132
|
+
const all = learningsList(opts);
|
|
133
|
+
if (query && query.tag) {
|
|
134
|
+
return all.filter(r => r.tags && r.tags.includes(query.tag));
|
|
135
|
+
}
|
|
136
|
+
return all;
|
|
137
|
+
}
|
|
138
|
+
function learningsDelete(id, opts) {
|
|
139
|
+
if (!/^[a-z0-9]+-[a-f0-9]+$/.test(id))
|
|
140
|
+
return false;
|
|
141
|
+
const dir = getStoreDir(opts);
|
|
142
|
+
const filePath = node_path_1.default.join(dir, `${id}.json`);
|
|
143
|
+
if (!node_fs_1.default.existsSync(filePath))
|
|
144
|
+
return false;
|
|
145
|
+
node_fs_1.default.unlinkSync(filePath);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
function learningsCopyFromProject(planningDir, opts) {
|
|
149
|
+
const learningsPath = node_path_1.default.join(planningDir, 'LEARNINGS.md');
|
|
150
|
+
if (!node_fs_1.default.existsSync(learningsPath)) {
|
|
151
|
+
return { total: 0, created: 0, skipped: 0 };
|
|
152
|
+
}
|
|
153
|
+
const content = node_fs_1.default.readFileSync(learningsPath, 'utf-8');
|
|
154
|
+
const sourceProject = (opts && opts.sourceProject) || node_path_1.default.basename(node_path_1.default.resolve(planningDir, '..'));
|
|
155
|
+
// #306: Build the content_hash -> id dedupe index once before the loop so
|
|
156
|
+
// that learningsWrite does not re-scan the entire store on every call —
|
|
157
|
+
// O(K*N) -> O(N+K).
|
|
158
|
+
const dir = getStoreDir(opts);
|
|
159
|
+
ensureStoreDir(dir);
|
|
160
|
+
const dedupeIndex = new Map();
|
|
161
|
+
for (const file of node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'))) {
|
|
162
|
+
const existing = readLearningFile(node_path_1.default.join(dir, file));
|
|
163
|
+
// First-seen-wins, matching the legacy scan path's first-match return so the
|
|
164
|
+
// dedupe-hit `id` is identical on both paths even if the store already holds
|
|
165
|
+
// duplicate content_hashes. (#306)
|
|
166
|
+
if (existing && existing.content_hash && !dedupeIndex.has(existing.content_hash)) {
|
|
167
|
+
dedupeIndex.set(existing.content_hash, existing.id);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Parse markdown: split on ## headings
|
|
171
|
+
const sections = content.split(/^## /m).slice(1); // skip preamble before first ##
|
|
172
|
+
let created = 0;
|
|
173
|
+
let skipped = 0;
|
|
174
|
+
for (const section of sections) {
|
|
175
|
+
const lines = section.trim().split('\n');
|
|
176
|
+
const title = lines[0].trim();
|
|
177
|
+
const body = lines.slice(1).join('\n').trim();
|
|
178
|
+
if (!body)
|
|
179
|
+
continue;
|
|
180
|
+
// Extract tags from title (simple: use words as tags)
|
|
181
|
+
const tags = title.toLowerCase().split(/\s+/).filter(w => w.length > 2);
|
|
182
|
+
const result = learningsWrite({
|
|
183
|
+
source_project: sourceProject,
|
|
184
|
+
learning: body,
|
|
185
|
+
context: title,
|
|
186
|
+
tags,
|
|
187
|
+
}, { ...opts, dedupeIndex });
|
|
188
|
+
if (result.created) {
|
|
189
|
+
created++;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
skipped++;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return { total: created + skipped, created, skipped };
|
|
196
|
+
}
|
|
197
|
+
function learningsPrune(olderThan, opts) {
|
|
198
|
+
const match = /^(\d+)d$/.exec(olderThan);
|
|
199
|
+
if (!match) {
|
|
200
|
+
throw new Error(`Invalid duration format: "${olderThan}" — expected format like "90d"`);
|
|
201
|
+
}
|
|
202
|
+
const days = parseInt(match[1], 10);
|
|
203
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
204
|
+
const dir = getStoreDir(opts);
|
|
205
|
+
if (!node_fs_1.default.existsSync(dir))
|
|
206
|
+
return { removed: 0, kept: 0 };
|
|
207
|
+
const files = node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
208
|
+
let removed = 0;
|
|
209
|
+
let kept = 0;
|
|
210
|
+
for (const file of files) {
|
|
211
|
+
const filePath = node_path_1.default.join(dir, file);
|
|
212
|
+
const record = readLearningFile(filePath);
|
|
213
|
+
if (!record)
|
|
214
|
+
continue;
|
|
215
|
+
const recordDate = new Date(record.date);
|
|
216
|
+
if (recordDate < cutoff) {
|
|
217
|
+
node_fs_1.default.unlinkSync(filePath);
|
|
218
|
+
removed++;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
kept++;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return { removed, kept };
|
|
225
|
+
}
|
|
226
|
+
// ─── CLI Command Handlers ────────────────────────────────────────────────────
|
|
227
|
+
function cmdLearningsList(raw) {
|
|
228
|
+
const results = learningsList();
|
|
229
|
+
output({ learnings: results, count: results.length }, raw, undefined);
|
|
230
|
+
}
|
|
231
|
+
function cmdLearningsQuery(tag, raw) {
|
|
232
|
+
const results = learningsQuery({ tag });
|
|
233
|
+
output({ learnings: results, count: results.length, tag }, raw, undefined);
|
|
234
|
+
}
|
|
235
|
+
function cmdLearningsCopy(cwd, raw) {
|
|
236
|
+
const planDir = node_path_1.default.join(cwd, '.planning');
|
|
237
|
+
const result = learningsCopyFromProject(planDir);
|
|
238
|
+
output(result, raw, undefined);
|
|
239
|
+
}
|
|
240
|
+
function cmdLearningsPrune(olderThan, raw) {
|
|
241
|
+
try {
|
|
242
|
+
const result = learningsPrune(olderThan);
|
|
243
|
+
output(result, raw, undefined);
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
coreError(err.message);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function cmdLearningsDelete(id, raw) {
|
|
250
|
+
if (!/^[a-z0-9]+-[a-f0-9]+$/.test(id)) {
|
|
251
|
+
coreError(`Invalid learning ID: "${id}"`);
|
|
252
|
+
}
|
|
253
|
+
const deleted = learningsDelete(id);
|
|
254
|
+
output({ id, deleted }, raw, undefined);
|
|
255
|
+
}
|
|
256
|
+
module.exports = {
|
|
257
|
+
learningsWrite,
|
|
258
|
+
learningsRead,
|
|
259
|
+
learningsList,
|
|
260
|
+
learningsQuery,
|
|
261
|
+
learningsDelete,
|
|
262
|
+
learningsCopyFromProject,
|
|
263
|
+
learningsPrune,
|
|
264
|
+
cmdLearningsList,
|
|
265
|
+
cmdLearningsQuery,
|
|
266
|
+
cmdLearningsCopy,
|
|
267
|
+
cmdLearningsPrune,
|
|
268
|
+
cmdLearningsDelete,
|
|
269
|
+
DEFAULT_STORE_DIR,
|
|
270
|
+
};
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* legacy-cleanup.cjs — detect and remove leftover artifacts from the old package.
|
|
5
|
+
*
|
|
6
|
+
* Provides a pure-ish scan phase (planLegacyCleanup) and a thin IO applier
|
|
7
|
+
* (applyLegacyCleanup) that together root out stale files from the old
|
|
8
|
+
* package across every GSD-managed runtime config directory.
|
|
9
|
+
*
|
|
10
|
+
* Issue: #607
|
|
11
|
+
*
|
|
12
|
+
* House style: CommonJS, 'use strict', pure functions + thin IO appliers.
|
|
13
|
+
* Seams (opts.fs, opts.logger) allow full unit-test coverage without touching
|
|
14
|
+
* the real filesystem except in the apply phase.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const os = require('os');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
|
|
21
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Substring that identifies a file as belonging to the old package.
|
|
25
|
+
* Assembled from parts so this source file itself never contains the literal
|
|
26
|
+
* as a plain substring (avoids self-flagging if the content scan were ever
|
|
27
|
+
* widened back to include this subtree).
|
|
28
|
+
*/
|
|
29
|
+
const OLD_PACKAGE_SIGNAL = 'gsd-core' + '-cc';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Subtrees within a configDir that GSD actively scans for old-package content.
|
|
33
|
+
* Deliberately excludes 'gsd-core' — the current package's own infra and
|
|
34
|
+
* docs live there (CHANGELOG.md, this file, etc.) and are overwritten by
|
|
35
|
+
* install anyway. Poisoning hooks from the old package live in 'hooks/', which
|
|
36
|
+
* IS scanned.
|
|
37
|
+
*/
|
|
38
|
+
const GSD_MANAGED_SUBTREES = ['hooks', 'commands'];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Extensions eligible for the content-reference scan.
|
|
42
|
+
*
|
|
43
|
+
* WHY: The current @therocketcode/gsd-core package ships ZERO references to the old
|
|
44
|
+
* package name in any code file (.js/.cjs/.mjs/.sh). Therefore a code file
|
|
45
|
+
* that still contains that string is genuinely a leftover from the old package
|
|
46
|
+
* and is safe to flag.
|
|
47
|
+
*
|
|
48
|
+
* Markdown, JSON, TOML, YAML, and other doc/config files, however,
|
|
49
|
+
* legitimately cite the old name in historical or reference context
|
|
50
|
+
* (e.g. CHANGELOG.md, workflow .md files). Scanning them caused the
|
|
51
|
+
* installer to delete the freshly-installed gsd-core/CHANGELOG.md,
|
|
52
|
+
* breaking installs. Fix: restrict the content scan to code extensions only.
|
|
53
|
+
*/
|
|
54
|
+
const CODE_EXTENSIONS = new Set(['.js', '.cjs', '.mjs', '.sh']);
|
|
55
|
+
|
|
56
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Return true if any segment of the absolute file path is `dev-preferences`
|
|
60
|
+
* or the file is named `dev-preferences.md`. These are always user artifacts.
|
|
61
|
+
*
|
|
62
|
+
* @param {string} absPath
|
|
63
|
+
* @returns {boolean}
|
|
64
|
+
*/
|
|
65
|
+
function isDevPreferencesPath(absPath) {
|
|
66
|
+
const parts = absPath.split(path.sep);
|
|
67
|
+
return parts.some(
|
|
68
|
+
(seg) => seg === 'dev-preferences' || seg === 'dev-preferences.md'
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Recursively collect all file paths under `dir` (bounded; skips
|
|
74
|
+
* unreadable entries silently).
|
|
75
|
+
*
|
|
76
|
+
* @param {string} dir
|
|
77
|
+
* @param {object} fsMod - injectable fs module
|
|
78
|
+
* @returns {string[]} absolute file paths
|
|
79
|
+
*/
|
|
80
|
+
function collectFilesUnder(dir, fsMod) {
|
|
81
|
+
const results = [];
|
|
82
|
+
let entries;
|
|
83
|
+
try {
|
|
84
|
+
entries = fsMod.readdirSync(dir, { withFileTypes: true });
|
|
85
|
+
} catch {
|
|
86
|
+
return results;
|
|
87
|
+
}
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
const full = path.join(dir, entry.name);
|
|
90
|
+
if (entry.isDirectory()) {
|
|
91
|
+
results.push(...collectFilesUnder(full, fsMod));
|
|
92
|
+
} else if (entry.isFile()) {
|
|
93
|
+
results.push(full);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Return true if the file at `absPath` contains the old-package substring.
|
|
101
|
+
* Skips unreadable files (returns false on any error).
|
|
102
|
+
*
|
|
103
|
+
* @param {string} absPath
|
|
104
|
+
* @param {object} fsMod
|
|
105
|
+
* @returns {boolean}
|
|
106
|
+
*/
|
|
107
|
+
function fileContainsOldPackageSignal(absPath, fsMod) {
|
|
108
|
+
try {
|
|
109
|
+
const content = fsMod.readFileSync(absPath, 'utf8');
|
|
110
|
+
return content.includes(OLD_PACKAGE_SIGNAL);
|
|
111
|
+
} catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ─── Public API ──────────────────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Scan `configDirs` for leftover old-package artifacts and the legacy
|
|
120
|
+
* shared cache, returning an ordered array of removal candidates.
|
|
121
|
+
*
|
|
122
|
+
* Possible reasons in returned entries:
|
|
123
|
+
* - 'content-references-old-package': a code file whose content contains
|
|
124
|
+
* the old package name signal (hooks/ and commands/ subtrees only).
|
|
125
|
+
* - 'legacy-shared-cache': the old package's shared update-check cache file.
|
|
126
|
+
*
|
|
127
|
+
* @param {string[]} configDirs - absolute paths to runtime config dirs to scan
|
|
128
|
+
* @param {object} [opts]
|
|
129
|
+
* @param {string} [opts.homeDir] - home directory (default: os.homedir())
|
|
130
|
+
* @param {object} [opts.fs] - injectable fs module (default: require('node:fs'))
|
|
131
|
+
* @returns {{ path: string, reason: string }[]}
|
|
132
|
+
*/
|
|
133
|
+
function planLegacyCleanup(configDirs, opts = {}) {
|
|
134
|
+
const homeDir = opts.homeDir || os.homedir();
|
|
135
|
+
const fsMod = opts.fs || fs;
|
|
136
|
+
|
|
137
|
+
/** @type {Map<string, string>} path → reason (de-dup by path) */
|
|
138
|
+
const candidates = new Map();
|
|
139
|
+
|
|
140
|
+
const addCandidate = (absPath, reason) => {
|
|
141
|
+
if (!candidates.has(absPath)) {
|
|
142
|
+
candidates.set(absPath, reason);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
for (const configDir of configDirs) {
|
|
147
|
+
for (const subtree of GSD_MANAGED_SUBTREES) {
|
|
148
|
+
const subtreeDir = path.join(configDir, subtree);
|
|
149
|
+
|
|
150
|
+
// Collect all files under this subtree (skip if absent)
|
|
151
|
+
const files = collectFilesUnder(subtreeDir, fsMod);
|
|
152
|
+
|
|
153
|
+
for (const absPath of files) {
|
|
154
|
+
// Never flag user-authored dev-preferences artifacts
|
|
155
|
+
if (isDevPreferencesPath(absPath)) continue;
|
|
156
|
+
|
|
157
|
+
// Content signal: code files referencing the old package name.
|
|
158
|
+
// Only scan files with code extensions — docs/config files (.md, .json,
|
|
159
|
+
// .yml, etc.) legitimately cite the old name in historical context and
|
|
160
|
+
// must never be deleted (see CODE_EXTENSIONS declaration above).
|
|
161
|
+
const ext = path.extname(absPath).toLowerCase();
|
|
162
|
+
if (CODE_EXTENSIONS.has(ext) && fileContainsOldPackageSignal(absPath, fsMod)) {
|
|
163
|
+
addCandidate(absPath, 'content-references-old-package');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Legacy shared cache (fixed name from the old package)
|
|
170
|
+
const legacyCachePath = path.join(homeDir, '.cache', 'gsd', 'gsd-update-check.json');
|
|
171
|
+
try {
|
|
172
|
+
const stat = fsMod.statSync(legacyCachePath);
|
|
173
|
+
if (stat.isFile()) {
|
|
174
|
+
addCandidate(legacyCachePath, 'legacy-shared-cache');
|
|
175
|
+
}
|
|
176
|
+
} catch {
|
|
177
|
+
// absent — skip
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Sort deterministically by path
|
|
181
|
+
const sorted = [...candidates.entries()]
|
|
182
|
+
.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)
|
|
183
|
+
.map(([p, reason]) => ({ path: p, reason }));
|
|
184
|
+
|
|
185
|
+
return sorted;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Execute the plan returned by `planLegacyCleanup`.
|
|
190
|
+
*
|
|
191
|
+
* @param {{ path: string, reason: string }[]} plan
|
|
192
|
+
* @param {object} [opts]
|
|
193
|
+
* @param {boolean} [opts.dryRun=false] - when true, log but do not remove
|
|
194
|
+
* @param {object} [opts.fs] - injectable fs module
|
|
195
|
+
* @param {object} [opts.logger] - injectable logger (default: console)
|
|
196
|
+
* @returns {{ removed: string[], skipped: string[], errors: Array<{path:string,error:string}>, dryRun: boolean }}
|
|
197
|
+
*/
|
|
198
|
+
function applyLegacyCleanup(plan, opts = {}) {
|
|
199
|
+
const dryRun = opts.dryRun === true;
|
|
200
|
+
const fsMod = opts.fs || fs;
|
|
201
|
+
const logger = opts.logger || console;
|
|
202
|
+
|
|
203
|
+
if (dryRun) {
|
|
204
|
+
for (const item of plan) {
|
|
205
|
+
logger.log('[dry-run] would remove: ' + item.path + ' (' + item.reason + ')');
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
removed: [],
|
|
209
|
+
skipped: plan.map((item) => item.path),
|
|
210
|
+
errors: [],
|
|
211
|
+
dryRun: true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const removed = [];
|
|
216
|
+
const errors = [];
|
|
217
|
+
|
|
218
|
+
for (const item of plan) {
|
|
219
|
+
let lastErr;
|
|
220
|
+
const maxAttempts = process.platform === 'win32' ? 3 : 1;
|
|
221
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
222
|
+
try {
|
|
223
|
+
if (attempt > 0) {
|
|
224
|
+
// Synchronous 100ms delay before retry (win32 EBUSY/EPERM from Defender)
|
|
225
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 100);
|
|
226
|
+
}
|
|
227
|
+
fsMod.rmSync(item.path, { force: true });
|
|
228
|
+
lastErr = undefined;
|
|
229
|
+
break;
|
|
230
|
+
} catch (err) {
|
|
231
|
+
lastErr = err;
|
|
232
|
+
if (process.platform !== 'win32' ||
|
|
233
|
+
(err.code !== 'EBUSY' && err.code !== 'EPERM')) {
|
|
234
|
+
break; // non-retryable error; stop immediately
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (lastErr) {
|
|
239
|
+
errors.push({ path: item.path, error: lastErr.message });
|
|
240
|
+
} else {
|
|
241
|
+
removed.push(item.path);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return { removed, skipped: [], errors, dryRun: false };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ─── Exports ─────────────────────────────────────────────────────────────────
|
|
249
|
+
|
|
250
|
+
module.exports = {
|
|
251
|
+
planLegacyCleanup,
|
|
252
|
+
applyLegacyCleanup,
|
|
253
|
+
};
|