@pareto4/pp-core 1.5.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 +22 -0
- package/README.md +100 -0
- package/agents/pp-advisor-researcher.md +108 -0
- package/agents/pp-ai-researcher.md +114 -0
- package/agents/pp-assumptions-analyzer.md +105 -0
- package/agents/pp-code-fixer.md +669 -0
- package/agents/pp-code-reviewer.md +387 -0
- package/agents/pp-codebase-mapper.md +853 -0
- package/agents/pp-debug-session-manager.md +315 -0
- package/agents/pp-debugger.md +1453 -0
- package/agents/pp-doc-classifier.md +168 -0
- package/agents/pp-doc-synthesizer.md +204 -0
- package/agents/pp-doc-verifier.md +217 -0
- package/agents/pp-doc-writer.md +616 -0
- package/agents/pp-domain-researcher.md +147 -0
- package/agents/pp-eval-auditor.md +191 -0
- package/agents/pp-eval-planner.md +154 -0
- package/agents/pp-executor.md +808 -0
- package/agents/pp-framework-selector.md +160 -0
- package/agents/pp-integration-checker.md +470 -0
- package/agents/pp-intel-updater.md +339 -0
- package/agents/pp-mempalace-curator.md +47 -0
- package/agents/pp-nyquist-auditor.md +204 -0
- package/agents/pp-pattern-mapper.md +335 -0
- package/agents/pp-phase-researcher.md +867 -0
- package/agents/pp-plan-checker.md +988 -0
- package/agents/pp-planner.md +1052 -0
- package/agents/pp-project-researcher.md +612 -0
- package/agents/pp-research-synthesizer.md +260 -0
- package/agents/pp-roadmapper.md +741 -0
- package/agents/pp-security-auditor.md +156 -0
- package/agents/pp-ui-auditor.md +495 -0
- package/agents/pp-ui-checker.md +309 -0
- package/agents/pp-ui-researcher.md +375 -0
- package/agents/pp-user-profiler.md +171 -0
- package/agents/pp-verifier.md +967 -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 +12370 -0
- package/bin/lib/ui-safety-gate.cjs +107 -0
- package/commands/pp-add-tests.md +42 -0
- package/commands/pp-ai-integration-phase.md +37 -0
- package/commands/pp-audit-fix.md +34 -0
- package/commands/pp-audit-milestone.md +37 -0
- package/commands/pp-audit-uat.md +24 -0
- package/commands/pp-autonomous.md +51 -0
- package/commands/pp-capture.md +62 -0
- package/commands/pp-cleanup.md +24 -0
- package/commands/pp-code-review.md +59 -0
- package/commands/pp-complete-milestone.md +143 -0
- package/commands/pp-config.md +56 -0
- package/commands/pp-debug.md +52 -0
- package/commands/pp-discovery.md +34 -0
- package/commands/pp-discuss-phase.md +77 -0
- package/commands/pp-docs-update.md +49 -0
- package/commands/pp-eval-review.md +33 -0
- package/commands/pp-execute-phase.md +65 -0
- package/commands/pp-explore.md +27 -0
- package/commands/pp-extract-learnings.md +23 -0
- package/commands/pp-fast.md +31 -0
- package/commands/pp-forensics.md +57 -0
- package/commands/pp-graphify.md +204 -0
- package/commands/pp-health.md +31 -0
- package/commands/pp-help.md +28 -0
- package/commands/pp-import.md +45 -0
- package/commands/pp-inbox.md +39 -0
- package/commands/pp-ingest-docs.md +42 -0
- package/commands/pp-manager.md +45 -0
- package/commands/pp-map-codebase.md +83 -0
- package/commands/pp-mempalace-capture.md +71 -0
- package/commands/pp-mempalace-recall.md +102 -0
- package/commands/pp-milestone-summary.md +51 -0
- package/commands/pp-mvp-phase.md +45 -0
- package/commands/pp-new-milestone.md +45 -0
- package/commands/pp-new-project.md +47 -0
- package/commands/pp-ns-context.md +25 -0
- package/commands/pp-ns-ideate.md +24 -0
- package/commands/pp-ns-manage.md +36 -0
- package/commands/pp-ns-project.md +27 -0
- package/commands/pp-ns-review.md +29 -0
- package/commands/pp-ns-workflow.md +35 -0
- package/commands/pp-pause-work.md +43 -0
- package/commands/pp-phase.md +56 -0
- package/commands/pp-plan-phase.md +63 -0
- package/commands/pp-plan-review-convergence.md +60 -0
- package/commands/pp-pr-branch.md +26 -0
- package/commands/pp-profile-user.md +46 -0
- package/commands/pp-progress.md +49 -0
- package/commands/pp-quick.md +174 -0
- package/commands/pp-resume-work.md +30 -0
- package/commands/pp-review-backlog.md +63 -0
- package/commands/pp-review.md +42 -0
- package/commands/pp-secure-phase.md +36 -0
- package/commands/pp-settings.md +29 -0
- package/commands/pp-ship.md +24 -0
- package/commands/pp-sketch.md +60 -0
- package/commands/pp-spec-phase.md +63 -0
- package/commands/pp-spike.md +57 -0
- package/commands/pp-stats.md +20 -0
- package/commands/pp-surface.md +162 -0
- package/commands/pp-thread.md +24 -0
- package/commands/pp-ui-phase.md +35 -0
- package/commands/pp-ui-review.md +33 -0
- package/commands/pp-ultraplan-phase.md +34 -0
- package/commands/pp-undo.md +35 -0
- package/commands/pp-update.md +49 -0
- package/commands/pp-validate-phase.md +36 -0
- package/commands/pp-verify-work.md +39 -0
- package/commands/pp-workspace.md +52 -0
- package/commands/pp-workstreams.md +70 -0
- package/gemini-extension.json +6 -0
- package/hooks/dist/lib/git-cmd.js +150 -0
- package/hooks/dist/lib/pp-graphify-rebuild.sh +65 -0
- package/hooks/dist/managed-hooks-registry.cjs +39 -0
- package/hooks/dist/pp-check-update-worker.js +108 -0
- package/hooks/dist/pp-check-update.js +66 -0
- package/hooks/dist/pp-config-reload.js +133 -0
- package/hooks/dist/pp-context-monitor.js +196 -0
- package/hooks/dist/pp-cursor-post-tool.js +75 -0
- package/hooks/dist/pp-cursor-session-start.js +52 -0
- package/hooks/dist/pp-ensure-canonical-path.js +305 -0
- package/hooks/dist/pp-graphify-update.sh +158 -0
- package/hooks/dist/pp-phase-boundary.sh +47 -0
- package/hooks/dist/pp-prompt-guard.js +97 -0
- package/hooks/dist/pp-read-guard.js +101 -0
- package/hooks/dist/pp-read-injection-scanner.js +203 -0
- package/hooks/dist/pp-session-state.sh +59 -0
- package/hooks/dist/pp-statusline.js +566 -0
- package/hooks/dist/pp-update-banner.js +138 -0
- package/hooks/dist/pp-validate-commit.sh +57 -0
- package/hooks/dist/pp-workflow-guard.js +167 -0
- package/hooks/dist/pp-worktree-path-guard.js +185 -0
- package/hooks/hooks.json +70 -0
- package/hooks/lib/git-cmd.js +150 -0
- package/hooks/lib/pp-graphify-rebuild.sh +65 -0
- package/hooks/managed-hooks-registry.cjs +39 -0
- package/hooks/pp-check-update-worker.js +108 -0
- package/hooks/pp-check-update.js +66 -0
- package/hooks/pp-config-reload.js +133 -0
- package/hooks/pp-context-monitor.js +196 -0
- package/hooks/pp-cursor-post-tool.js +75 -0
- package/hooks/pp-cursor-session-start.js +52 -0
- package/hooks/pp-ensure-canonical-path.js +305 -0
- package/hooks/pp-graphify-update.sh +158 -0
- package/hooks/pp-phase-boundary.sh +47 -0
- package/hooks/pp-prompt-guard.js +97 -0
- package/hooks/pp-read-guard.js +101 -0
- package/hooks/pp-read-injection-scanner.js +203 -0
- package/hooks/pp-session-state.sh +59 -0
- package/hooks/pp-statusline.js +566 -0
- package/hooks/pp-update-banner.js +138 -0
- package/hooks/pp-validate-commit.sh +57 -0
- package/hooks/pp-workflow-guard.js +167 -0
- package/hooks/pp-worktree-path-guard.js +185 -0
- package/package.json +125 -0
- package/pp-core/bin/check-latest-version.cjs +161 -0
- package/pp-core/bin/lib/active-workstream-store.cjs +297 -0
- package/pp-core/bin/lib/adr-parser.cjs +399 -0
- package/pp-core/bin/lib/agent-command-router.cjs +68 -0
- package/pp-core/bin/lib/agent-install-check.cjs +143 -0
- package/pp-core/bin/lib/artifacts.cjs +51 -0
- package/pp-core/bin/lib/audit-command-router.cjs +61 -0
- package/pp-core/bin/lib/audit.cjs +743 -0
- package/pp-core/bin/lib/capability-activation.cjs +113 -0
- package/pp-core/bin/lib/capability-registry.cjs +3727 -0
- package/pp-core/bin/lib/capability-state.cjs +497 -0
- package/pp-core/bin/lib/capability-writer.cjs +355 -0
- package/pp-core/bin/lib/check-command-router.cjs +800 -0
- package/pp-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
- package/pp-core/bin/lib/cli-exit.cjs +61 -0
- package/pp-core/bin/lib/clock.cjs +95 -0
- package/pp-core/bin/lib/clusters.cjs +131 -0
- package/pp-core/bin/lib/code-review-flags.cjs +59 -0
- package/pp-core/bin/lib/command-aliases.cjs +809 -0
- package/pp-core/bin/lib/command-arg-projection.cjs +55 -0
- package/pp-core/bin/lib/command-roster.cjs +19 -0
- package/pp-core/bin/lib/command-routing-hub.cjs +300 -0
- package/pp-core/bin/lib/commands.cjs +1244 -0
- package/pp-core/bin/lib/config-loader.cjs +714 -0
- package/pp-core/bin/lib/config-schema.cjs +58 -0
- package/pp-core/bin/lib/config-types.cjs +20 -0
- package/pp-core/bin/lib/config.cjs +796 -0
- package/pp-core/bin/lib/configuration.cjs +209 -0
- package/pp-core/bin/lib/context-utilization.cjs +48 -0
- package/pp-core/bin/lib/core-utils.cjs +198 -0
- package/pp-core/bin/lib/decisions.cjs +136 -0
- package/pp-core/bin/lib/docs.cjs +264 -0
- package/pp-core/bin/lib/drift.cjs +364 -0
- package/pp-core/bin/lib/edge-probe.cjs +196 -0
- package/pp-core/bin/lib/fallow-runner.cjs +153 -0
- package/pp-core/bin/lib/federated-config.cjs +182 -0
- package/pp-core/bin/lib/frontmatter.cjs +494 -0
- package/pp-core/bin/lib/gap-checker.cjs +260 -0
- package/pp-core/bin/lib/git-base-branch.cjs +220 -0
- package/pp-core/bin/lib/graphify-command-router.cjs +72 -0
- package/pp-core/bin/lib/graphify.cjs +472 -0
- package/pp-core/bin/lib/gsd2-import.cjs +456 -0
- package/pp-core/bin/lib/init-command-router.cjs +62 -0
- package/pp-core/bin/lib/init.cjs +1912 -0
- package/pp-core/bin/lib/install-profiles.cjs +814 -0
- package/pp-core/bin/lib/installer-migration-authoring.cjs +122 -0
- package/pp-core/bin/lib/installer-migration-report.cjs +351 -0
- package/pp-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +225 -0
- package/pp-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
- package/pp-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
- package/pp-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
- package/pp-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs +123 -0
- package/pp-core/bin/lib/installer-migrations/005-rename-gsd-core-to-pp-core.cjs +109 -0
- package/pp-core/bin/lib/installer-migrations/006-rename-gsd-command-namespace.cjs +135 -0
- package/pp-core/bin/lib/installer-migrations.cjs +823 -0
- package/pp-core/bin/lib/intel-command-router.cjs +119 -0
- package/pp-core/bin/lib/intel.cjs +584 -0
- package/pp-core/bin/lib/io.cjs +220 -0
- package/pp-core/bin/lib/learnings.cjs +270 -0
- package/pp-core/bin/lib/legacy-cleanup.cjs +253 -0
- package/pp-core/bin/lib/loop-host-contract.cjs +105 -0
- package/pp-core/bin/lib/loop-resolver.cjs +479 -0
- package/pp-core/bin/lib/milestone.cjs +381 -0
- package/pp-core/bin/lib/model-catalog.cjs +154 -0
- package/pp-core/bin/lib/model-profiles.cjs +24 -0
- package/pp-core/bin/lib/model-resolver.cjs +467 -0
- package/pp-core/bin/lib/observability/event.cjs +51 -0
- package/pp-core/bin/lib/observability/logger.cjs +146 -0
- package/pp-core/bin/lib/observability/redaction.cjs +48 -0
- package/pp-core/bin/lib/package-identity.cjs +35 -0
- package/pp-core/bin/lib/package-legitimacy.cjs +368 -0
- package/pp-core/bin/lib/phase-command-router.cjs +209 -0
- package/pp-core/bin/lib/phase-id.cjs +213 -0
- package/pp-core/bin/lib/phase-lifecycle.cjs +74 -0
- package/pp-core/bin/lib/phase-locator.cjs +145 -0
- package/pp-core/bin/lib/phase.cjs +1446 -0
- package/pp-core/bin/lib/phases-command-router.cjs +43 -0
- package/pp-core/bin/lib/plan-drift-guard.cjs +117 -0
- package/pp-core/bin/lib/plan-scan.cjs +91 -0
- package/pp-core/bin/lib/planning-workspace.cjs +245 -0
- package/pp-core/bin/lib/probe-core.cjs +402 -0
- package/pp-core/bin/lib/profile-output.cjs +1164 -0
- package/pp-core/bin/lib/profile-pipeline-command-router.cjs +138 -0
- package/pp-core/bin/lib/profile-pipeline.cjs +519 -0
- package/pp-core/bin/lib/prohibition-enforcement.cjs +660 -0
- package/pp-core/bin/lib/project-root.cjs +119 -0
- package/pp-core/bin/lib/prompt-budget.cjs +305 -0
- package/pp-core/bin/lib/research-provider.cjs +137 -0
- package/pp-core/bin/lib/research-store.cjs +167 -0
- package/pp-core/bin/lib/review-reviewer-selection.cjs +121 -0
- package/pp-core/bin/lib/roadmap-command-router.cjs +166 -0
- package/pp-core/bin/lib/roadmap-parser.cjs +456 -0
- package/pp-core/bin/lib/roadmap-upgrade.cjs +476 -0
- package/pp-core/bin/lib/roadmap.cjs +738 -0
- package/pp-core/bin/lib/runtime-artifact-conversion.cjs +1966 -0
- package/pp-core/bin/lib/runtime-artifact-layout.cjs +342 -0
- package/pp-core/bin/lib/runtime-config-adapter-registry.cjs +103 -0
- package/pp-core/bin/lib/runtime-homes.cjs +272 -0
- package/pp-core/bin/lib/runtime-hooks-surface.cjs +1460 -0
- package/pp-core/bin/lib/runtime-name-policy.cjs +97 -0
- package/pp-core/bin/lib/runtime-slash.cjs +137 -0
- package/pp-core/bin/lib/schema-detect.cjs +159 -0
- package/pp-core/bin/lib/secrets.cjs +34 -0
- package/pp-core/bin/lib/security.cjs +480 -0
- package/pp-core/bin/lib/semver-compare.cjs +42 -0
- package/pp-core/bin/lib/shell-command-projection.cjs +550 -0
- package/pp-core/bin/lib/state-command-router.cjs +172 -0
- package/pp-core/bin/lib/state-document.cjs +312 -0
- package/pp-core/bin/lib/state.cjs +2587 -0
- package/pp-core/bin/lib/surface.cjs +505 -0
- package/pp-core/bin/lib/task-command-router.cjs +85 -0
- package/pp-core/bin/lib/teams-status.cjs +74 -0
- package/pp-core/bin/lib/template.cjs +246 -0
- package/pp-core/bin/lib/uat-predicate.cjs +329 -0
- package/pp-core/bin/lib/uat.cjs +359 -0
- package/pp-core/bin/lib/ui-safety-gate.cjs +98 -0
- package/pp-core/bin/lib/update-context.cjs +221 -0
- package/pp-core/bin/lib/validate-command-router.cjs +91 -0
- package/pp-core/bin/lib/validate.cjs +122 -0
- package/pp-core/bin/lib/verification-command-router.cjs +31 -0
- package/pp-core/bin/lib/verification.cjs +196 -0
- package/pp-core/bin/lib/verify-command-router.cjs +44 -0
- package/pp-core/bin/lib/verify.cjs +1932 -0
- package/pp-core/bin/lib/workstream-inventory-builder.cjs +81 -0
- package/pp-core/bin/lib/workstream-inventory.cjs +147 -0
- package/pp-core/bin/lib/workstream-name-policy.cjs +91 -0
- package/pp-core/bin/lib/workstream.cjs +386 -0
- package/pp-core/bin/lib/worktree-base-ref.cjs +350 -0
- package/pp-core/bin/lib/worktree-safety.cjs +985 -0
- package/pp-core/bin/pp-tools.cjs +2239 -0
- package/pp-core/bin/pp_run +20 -0
- package/pp-core/bin/shared/config-defaults.manifest.json +97 -0
- package/pp-core/bin/shared/config-schema.manifest.json +176 -0
- package/pp-core/bin/shared/model-catalog.json +160 -0
- package/pp-core/bin/shared/runtime-aliases.manifest.json +79 -0
- package/pp-core/bin/verify-reapply-patches.cjs +400 -0
- package/pp-core/contexts/dev.md +21 -0
- package/pp-core/contexts/research.md +22 -0
- package/pp-core/contexts/review.md +23 -0
- package/pp-core/references/agent-contracts.md +79 -0
- package/pp-core/references/ai-evals.md +156 -0
- package/pp-core/references/ai-frameworks.md +186 -0
- package/pp-core/references/artifact-types.md +131 -0
- package/pp-core/references/autonomous-smart-discuss.md +277 -0
- package/pp-core/references/checkpoints.md +814 -0
- package/pp-core/references/common-bug-patterns.md +114 -0
- package/pp-core/references/context-budget.md +85 -0
- package/pp-core/references/continuation-format.md +253 -0
- package/pp-core/references/debugger-philosophy.md +76 -0
- package/pp-core/references/decimal-phase-calculation.md +64 -0
- package/pp-core/references/doc-conflict-engine.md +91 -0
- package/pp-core/references/domain-probes.md +125 -0
- package/pp-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/01-round-half-even/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/02-merge-intervals/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/04-money-rounding/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/05-list-dedupe/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/resolutions.json +4 -0
- package/pp-core/references/edge-probe.md +272 -0
- package/pp-core/references/execute-mvp-tdd.md +81 -0
- package/pp-core/references/executor-examples.md +110 -0
- package/pp-core/references/few-shot-examples/plan-checker.md +73 -0
- package/pp-core/references/few-shot-examples/verifier.md +109 -0
- package/pp-core/references/gate-prompts.md +100 -0
- package/pp-core/references/gates.md +70 -0
- package/pp-core/references/git-integration.md +298 -0
- package/pp-core/references/git-planning-commit.md +40 -0
- package/pp-core/references/ios-scaffold.md +123 -0
- package/pp-core/references/loop-hook-dispatch.md +61 -0
- package/pp-core/references/mandatory-initial-read.md +2 -0
- package/pp-core/references/model-profile-resolution.md +38 -0
- package/pp-core/references/model-profiles.md +245 -0
- package/pp-core/references/mvp-concepts.md +49 -0
- package/pp-core/references/phase-argument-parsing.md +61 -0
- package/pp-core/references/planner-antipatterns.md +176 -0
- package/pp-core/references/planner-chunked.md +49 -0
- package/pp-core/references/planner-gap-closure.md +62 -0
- package/pp-core/references/planner-graphify-auto-update.md +67 -0
- package/pp-core/references/planner-guidance.md +186 -0
- package/pp-core/references/planner-human-verify-mode.md +57 -0
- package/pp-core/references/planner-interface-context.md +62 -0
- package/pp-core/references/planner-load-graph-context.md +36 -0
- package/pp-core/references/planner-mvp-mode.md +53 -0
- package/pp-core/references/planner-reviews.md +42 -0
- package/pp-core/references/planner-revision.md +87 -0
- package/pp-core/references/planner-source-audit.md +73 -0
- package/pp-core/references/planning-config.md +477 -0
- package/pp-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json +14 -0
- package/pp-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json +4 -0
- package/pp-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json +32 -0
- package/pp-core/references/prohibition-probe.md +326 -0
- package/pp-core/references/project-skills-discovery.md +19 -0
- package/pp-core/references/questioning.md +162 -0
- package/pp-core/references/research-documentation-lookup.md +29 -0
- package/pp-core/references/research-philosophy.md +29 -0
- package/pp-core/references/research-verification-protocol.md +27 -0
- package/pp-core/references/revision-loop.md +97 -0
- package/pp-core/references/scout-codebase.md +51 -0
- package/pp-core/references/skeleton-template.md +48 -0
- package/pp-core/references/sketch-interactivity.md +41 -0
- package/pp-core/references/sketch-theme-system.md +94 -0
- package/pp-core/references/sketch-tooling.md +45 -0
- package/pp-core/references/sketch-variant-patterns.md +81 -0
- package/pp-core/references/spidr-splitting.md +69 -0
- package/pp-core/references/tdd.md +330 -0
- package/pp-core/references/thinking-models-debug.md +44 -0
- package/pp-core/references/thinking-models-execution.md +50 -0
- package/pp-core/references/thinking-models-planning.md +62 -0
- package/pp-core/references/thinking-models-research.md +50 -0
- package/pp-core/references/thinking-models-verification.md +55 -0
- package/pp-core/references/thinking-partner.md +96 -0
- package/pp-core/references/ui-brand.md +162 -0
- package/pp-core/references/universal-anti-patterns.md +63 -0
- package/pp-core/references/user-profiling.md +681 -0
- package/pp-core/references/user-story-template.md +58 -0
- package/pp-core/references/verification-overrides.md +227 -0
- package/pp-core/references/verification-patterns.md +612 -0
- package/pp-core/references/verify-mvp-mode.md +85 -0
- package/pp-core/references/workstream-flag.md +111 -0
- package/pp-core/references/worktree-branch-check.md +44 -0
- package/pp-core/references/worktree-path-safety.md +67 -0
- package/pp-core/templates/AI-SPEC.md +246 -0
- package/pp-core/templates/DEBUG.md +169 -0
- package/pp-core/templates/README.md +77 -0
- package/pp-core/templates/SECURITY.md +61 -0
- package/pp-core/templates/UAT.md +265 -0
- package/pp-core/templates/UI-SPEC.md +100 -0
- package/pp-core/templates/VALIDATION.md +76 -0
- package/pp-core/templates/claude-md.md +145 -0
- package/pp-core/templates/codebase/architecture.md +255 -0
- package/pp-core/templates/codebase/concerns.md +310 -0
- package/pp-core/templates/codebase/conventions.md +307 -0
- package/pp-core/templates/codebase/integrations.md +280 -0
- package/pp-core/templates/codebase/stack.md +186 -0
- package/pp-core/templates/codebase/structure.md +285 -0
- package/pp-core/templates/codebase/testing.md +480 -0
- package/pp-core/templates/config.json +62 -0
- package/pp-core/templates/context.md +352 -0
- package/pp-core/templates/continue-here.md +78 -0
- package/pp-core/templates/copilot-instructions.md +7 -0
- package/pp-core/templates/debug-subagent-prompt.md +91 -0
- package/pp-core/templates/dev-preferences.md +21 -0
- package/pp-core/templates/discovery.md +146 -0
- package/pp-core/templates/discussion-log.md +63 -0
- package/pp-core/templates/milestone-archive.md +123 -0
- package/pp-core/templates/milestone.md +115 -0
- package/pp-core/templates/phase-prompt.md +610 -0
- package/pp-core/templates/planner-subagent-prompt.md +117 -0
- package/pp-core/templates/project.md +203 -0
- package/pp-core/templates/requirements.md +231 -0
- package/pp-core/templates/research-project/ARCHITECTURE.md +204 -0
- package/pp-core/templates/research-project/FEATURES.md +147 -0
- package/pp-core/templates/research-project/PITFALLS.md +200 -0
- package/pp-core/templates/research-project/STACK.md +120 -0
- package/pp-core/templates/research-project/SUMMARY.md +170 -0
- package/pp-core/templates/research.md +592 -0
- package/pp-core/templates/retrospective.md +54 -0
- package/pp-core/templates/roadmap.md +202 -0
- package/pp-core/templates/spec.md +333 -0
- package/pp-core/templates/state.md +195 -0
- package/pp-core/templates/summary-complex.md +60 -0
- package/pp-core/templates/summary-minimal.md +42 -0
- package/pp-core/templates/summary-standard.md +49 -0
- package/pp-core/templates/summary.md +249 -0
- package/pp-core/templates/user-profile.md +146 -0
- package/pp-core/templates/user-setup.md +311 -0
- package/pp-core/templates/verification-report.md +335 -0
- package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -0
- package/pp-core/workflows/add-backlog.md +91 -0
- package/pp-core/workflows/add-phase.md +113 -0
- package/pp-core/workflows/add-tests.md +355 -0
- package/pp-core/workflows/add-todo.md +161 -0
- package/pp-core/workflows/ai-integration-phase.md +295 -0
- package/pp-core/workflows/analyze-dependencies.md +96 -0
- package/pp-core/workflows/audit-fix.md +178 -0
- package/pp-core/workflows/audit-milestone.md +362 -0
- package/pp-core/workflows/audit-uat.md +110 -0
- package/pp-core/workflows/autonomous.md +886 -0
- package/pp-core/workflows/check-todos.md +180 -0
- package/pp-core/workflows/cleanup.md +195 -0
- package/pp-core/workflows/code-review-fix.md +506 -0
- package/pp-core/workflows/code-review.md +696 -0
- package/pp-core/workflows/complete-milestone.md +857 -0
- package/pp-core/workflows/debug.md +237 -0
- package/pp-core/workflows/diagnose-issues.md +245 -0
- package/pp-core/workflows/discovery-phase.md +291 -0
- package/pp-core/workflows/discovery-sprint.md +1546 -0
- package/pp-core/workflows/discuss-phase/modes/advisor.md +176 -0
- package/pp-core/workflows/discuss-phase/modes/all.md +28 -0
- package/pp-core/workflows/discuss-phase/modes/analyze.md +44 -0
- package/pp-core/workflows/discuss-phase/modes/auto.md +57 -0
- package/pp-core/workflows/discuss-phase/modes/batch.md +52 -0
- package/pp-core/workflows/discuss-phase/modes/chain.md +98 -0
- package/pp-core/workflows/discuss-phase/modes/default.md +141 -0
- package/pp-core/workflows/discuss-phase/modes/power.md +44 -0
- package/pp-core/workflows/discuss-phase/modes/text.md +55 -0
- package/pp-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
- package/pp-core/workflows/discuss-phase/templates/context.md +136 -0
- package/pp-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
- package/pp-core/workflows/discuss-phase-assumptions.md +675 -0
- package/pp-core/workflows/discuss-phase-power.md +291 -0
- package/pp-core/workflows/discuss-phase.md +520 -0
- package/pp-core/workflows/do.md +111 -0
- package/pp-core/workflows/docs-update.md +1168 -0
- package/pp-core/workflows/edit-phase.md +295 -0
- package/pp-core/workflows/eval-review.md +159 -0
- package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
- package/pp-core/workflows/execute-phase/steps/worktree-recovery-policy.md +9 -0
- package/pp-core/workflows/execute-phase.md +1707 -0
- package/pp-core/workflows/execute-plan.md +541 -0
- package/pp-core/workflows/explore.md +146 -0
- package/pp-core/workflows/extract-learnings.md +243 -0
- package/pp-core/workflows/fast.md +124 -0
- package/pp-core/workflows/forensics.md +279 -0
- package/pp-core/workflows/graduation.md +196 -0
- package/pp-core/workflows/health.md +224 -0
- package/pp-core/workflows/help/modes/brief.md +22 -0
- package/pp-core/workflows/help/modes/default.md +50 -0
- package/pp-core/workflows/help/modes/full.md +791 -0
- package/pp-core/workflows/help/modes/topic.md +74 -0
- package/pp-core/workflows/help.md +24 -0
- package/pp-core/workflows/import.md +256 -0
- package/pp-core/workflows/inbox.md +387 -0
- package/pp-core/workflows/ingest-docs.md +340 -0
- package/pp-core/workflows/insert-phase.md +152 -0
- package/pp-core/workflows/list-phase-assumptions.md +178 -0
- package/pp-core/workflows/list-workspaces.md +57 -0
- package/pp-core/workflows/manager.md +435 -0
- package/pp-core/workflows/map-codebase.md +444 -0
- package/pp-core/workflows/milestone-summary.md +224 -0
- package/pp-core/workflows/mvp-phase.md +222 -0
- package/pp-core/workflows/new-milestone.md +643 -0
- package/pp-core/workflows/new-project.md +1563 -0
- package/pp-core/workflows/new-workspace.md +240 -0
- package/pp-core/workflows/next.md +347 -0
- package/pp-core/workflows/node-repair.md +92 -0
- package/pp-core/workflows/note.md +158 -0
- package/pp-core/workflows/pause-work.md +250 -0
- package/pp-core/workflows/plan-milestone-gaps.md +281 -0
- package/pp-core/workflows/plan-phase.md +1755 -0
- package/pp-core/workflows/plan-review-convergence.md +369 -0
- package/pp-core/workflows/plant-seed.md +230 -0
- package/pp-core/workflows/pr-branch.md +159 -0
- package/pp-core/workflows/profile-user.md +455 -0
- package/pp-core/workflows/progress.md +756 -0
- package/pp-core/workflows/quick.md +1045 -0
- package/pp-core/workflows/reapply-patches.md +443 -0
- package/pp-core/workflows/remove-phase.md +156 -0
- package/pp-core/workflows/remove-workspace.md +108 -0
- package/pp-core/workflows/resume-project.md +348 -0
- package/pp-core/workflows/review.md +765 -0
- package/pp-core/workflows/scan.md +107 -0
- package/pp-core/workflows/secure-phase.md +184 -0
- package/pp-core/workflows/session-report.md +146 -0
- package/pp-core/workflows/settings-advanced.md +816 -0
- package/pp-core/workflows/settings-integrations.md +312 -0
- package/pp-core/workflows/settings.md +592 -0
- package/pp-core/workflows/ship.md +465 -0
- package/pp-core/workflows/sketch-wrap-up.md +286 -0
- package/pp-core/workflows/sketch.md +361 -0
- package/pp-core/workflows/spec-phase.md +495 -0
- package/pp-core/workflows/spike-wrap-up.md +307 -0
- package/pp-core/workflows/spike.md +453 -0
- package/pp-core/workflows/stats.md +80 -0
- package/pp-core/workflows/sync-skills.md +182 -0
- package/pp-core/workflows/thread.md +222 -0
- package/pp-core/workflows/transition.md +694 -0
- package/pp-core/workflows/ui-phase.md +328 -0
- package/pp-core/workflows/ui-review.md +193 -0
- package/pp-core/workflows/ultraplan-phase.md +199 -0
- package/pp-core/workflows/undo.md +314 -0
- package/pp-core/workflows/update.md +501 -0
- package/pp-core/workflows/validate-phase.md +183 -0
- package/pp-core/workflows/verify-phase.md +569 -0
- package/pp-core/workflows/verify-work.md +804 -0
- package/scripts/affected-tests-lib.cjs +554 -0
- package/scripts/audit-workflow-script-paths.cjs +73 -0
- package/scripts/base64-scan.sh +351 -0
- package/scripts/build-hooks.js +254 -0
- package/scripts/changeset/README.md +129 -0
- package/scripts/changeset/cli.cjs +597 -0
- package/scripts/changeset/github-release-notes.cjs +199 -0
- package/scripts/changeset/lint.cjs +147 -0
- package/scripts/changeset/new.cjs +151 -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 +93 -0
- package/scripts/ci-rebase-check.cjs +86 -0
- package/scripts/ci-test-scope.cjs +441 -0
- package/scripts/command-contract-helpers.cjs +64 -0
- package/scripts/diff-touches-shipped-paths.cjs +149 -0
- package/scripts/fix-slash-commands.cjs +161 -0
- package/scripts/gen-capability-registry.cjs +2646 -0
- package/scripts/gen-commands-reference.cjs +139 -0
- package/scripts/gen-inventory-manifest.cjs +114 -0
- package/scripts/gen-loop-host-contract.cjs +526 -0
- package/scripts/gen-research-agents.cjs +276 -0
- package/scripts/generate-package-identity.cjs +134 -0
- package/scripts/issue-dedupe.cjs +278 -0
- package/scripts/issue-version-gate.cjs +140 -0
- package/scripts/lib/allowlist-ratchet.cjs +236 -0
- package/scripts/lib/cli-exit.cjs +56 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +328 -0
- package/scripts/lint-allow-test-rule-refs.cjs +162 -0
- package/scripts/lint-command-contract.cjs +118 -0
- package/scripts/lint-descriptions.cjs +87 -0
- package/scripts/lint-docs-required.cjs +222 -0
- package/scripts/lint-legacy-dir-name.cjs +166 -0
- package/scripts/lint-package-identity-drift.cjs +141 -0
- package/scripts/lint-pr-check-project-dir.cjs +99 -0
- package/scripts/lint-regression-test-names.allowlist.json +269 -0
- package/scripts/lint-regression-test-names.cjs +117 -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 +181 -0
- package/scripts/lint-test-file-count.cjs +246 -0
- package/scripts/lint-windows-test-portability.cjs +178 -0
- package/scripts/mutation-matrix.cjs +323 -0
- package/scripts/pr-target-policy.cjs +63 -0
- package/scripts/pr-template-policy.cjs +268 -0
- package/scripts/prompt-injection-scan.sh +207 -0
- package/scripts/registry-smoke.cjs +337 -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 +763 -0
- package/scripts/research-profiles.cjs +149 -0
- package/scripts/run-affected-tests.cjs +7 -0
- package/scripts/run-tests.cjs +589 -0
- package/scripts/secret-scan-lint.sh +231 -0
- package/scripts/secret-scan.sh +358 -0
- package/scripts/setup-branch-protection.sh +234 -0
- package/scripts/strip-prose-atrefs.cjs +106 -0
- package/scripts/sync-manifest-versions.cjs +119 -0
- package/scripts/sync-next-version.cjs +133 -0
- package/scripts/sync-rulesets.sh +34 -0
- package/scripts/sync-runtime-launcher.cjs +425 -0
- package/scripts/test-failure-reasons.cjs +34 -0
- package/scripts/update-size-baseline.cjs +68 -0
- package/scripts/verify-npm-publish.cjs +240 -0
- package/scripts/verify-opengsd-sweep.cjs +288 -0
- package/scripts/verify-phase-02-rename.sh +258 -0
- package/scripts/verify-phase-03-rename.sh +376 -0
- package/scripts/workflow-policy.cjs +483 -0
- package/scripts/workflow-size.cjs +90 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI I/O primitives — output(), error(), ERROR_REASON, JSON-error mode,
|
|
4
|
+
* and the temp-file helpers that output() depends on.
|
|
5
|
+
*
|
|
6
|
+
* Extracted from core.cts (ADR-857 rollout phase 1 / issue #859).
|
|
7
|
+
* The hand-written bodies are preserved byte-for-behaviour; only the module
|
|
8
|
+
* boundary moved. The core.cjs re-export spine was retired in epic #1267;
|
|
9
|
+
* callers import I/O primitives from io.cjs directly.
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
15
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
16
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
+
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
18
|
+
// ─── Temp-file helpers (needed by output()) ──────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Dedicated GSD temp directory: path.join(os.tmpdir(), 'gsd').
|
|
21
|
+
* Created on first use. Keeps GSD temp files isolated from the system
|
|
22
|
+
* temp directory so reap scans only GSD files (#1975).
|
|
23
|
+
*/
|
|
24
|
+
const GSD_TEMP_DIR = node_path_1.default.join(node_os_1.default.tmpdir(), 'gsd');
|
|
25
|
+
function ensureGsdTempDir() {
|
|
26
|
+
(0, shell_command_projection_cjs_1.platformEnsureDir)(GSD_TEMP_DIR);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Remove stale gsd-* temp files/dirs older than maxAgeMs (default: 5 minutes).
|
|
30
|
+
* Runs opportunistically before each new temp file write to prevent unbounded accumulation.
|
|
31
|
+
* @param prefix - filename prefix to match (e.g., 'gsd-')
|
|
32
|
+
* @param opts
|
|
33
|
+
* @param opts.maxAgeMs - max age in ms before removal (default: 5 min)
|
|
34
|
+
* @param opts.dirsOnly - if true, only remove directories (default: false)
|
|
35
|
+
*/
|
|
36
|
+
function reapStaleTempFiles(prefix = 'gsd-', { maxAgeMs = 5 * 60 * 1000, dirsOnly = false } = {}) {
|
|
37
|
+
try {
|
|
38
|
+
ensureGsdTempDir();
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
const entries = node_fs_1.default.readdirSync(GSD_TEMP_DIR);
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
if (!entry.startsWith(prefix))
|
|
43
|
+
continue;
|
|
44
|
+
const fullPath = node_path_1.default.join(GSD_TEMP_DIR, entry);
|
|
45
|
+
try {
|
|
46
|
+
const stat = node_fs_1.default.statSync(fullPath);
|
|
47
|
+
if (now - stat.mtimeMs > maxAgeMs) {
|
|
48
|
+
if (stat.isDirectory()) {
|
|
49
|
+
node_fs_1.default.rmSync(fullPath, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
else if (!dirsOnly) {
|
|
52
|
+
node_fs_1.default.unlinkSync(fullPath);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// File may have been removed between readdir and stat — ignore
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Non-critical — don't let cleanup failures break output
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ─── Output helpers ───────────────────────────────────────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Transient write errnos. When stdout/stderr is a NON-BLOCKING pipe — as it is
|
|
68
|
+
* under the parallel `node --test` runner on Linux CI — a full pipe buffer makes
|
|
69
|
+
* `fs.writeSync` throw EAGAIN, and a signal can interrupt it with EINTR. Both
|
|
70
|
+
* clear on retry once the reader drains. This is the same transient class the
|
|
71
|
+
* STATE.md lock path already retries (ACQUIRE_LOCK_RETRY_ERRNOS, #3776); #1008.
|
|
72
|
+
*/
|
|
73
|
+
const WRITE_RETRY_ERRNOS = new Set(['EAGAIN', 'EINTR']);
|
|
74
|
+
// Bounded so a pathological never-draining fd cannot spin forever. Each retry
|
|
75
|
+
// yields the thread for ~1ms via Atomics.wait (the project's sync-sleep idiom —
|
|
76
|
+
// see clock.cts realClock.sleep), so the cap is ~1s of total back-pressure wait.
|
|
77
|
+
const WRITE_MAX_RETRIES = 1000;
|
|
78
|
+
const WRITE_RETRY_BACKOFF_MS = 1;
|
|
79
|
+
// Sleep buffer is lazily allocated on the FIRST back-pressure retry (rare — only
|
|
80
|
+
// when a non-blocking pipe is full) and then reused. Keeping it out of module
|
|
81
|
+
// load costs nothing on the overwhelmingly common no-retry path and avoids
|
|
82
|
+
// perturbing SharedArrayBuffer-allocation accounting in other modules (perf-316).
|
|
83
|
+
let _writeSleepBuf = null;
|
|
84
|
+
function backoffOnce() {
|
|
85
|
+
if (_writeSleepBuf === null)
|
|
86
|
+
_writeSleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
87
|
+
Atomics.wait(_writeSleepBuf, 0, 0, WRITE_RETRY_BACKOFF_MS);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Write the entire payload to `fd`, tolerating non-blocking-pipe back-pressure.
|
|
91
|
+
*
|
|
92
|
+
* `fs.writeSync` does NOT block on a non-blocking pipe: a full buffer throws
|
|
93
|
+
* EAGAIN, and a partially-drained buffer returns a SHORT count (fewer bytes than
|
|
94
|
+
* requested). The previous bare `fs.writeSync(fd, string)` call assumed it always
|
|
95
|
+
* blocked until the kernel accepted every byte — false under load, which both
|
|
96
|
+
* threw spurious errors and risked silently truncating output (#1008).
|
|
97
|
+
*
|
|
98
|
+
* This loops on short counts (advancing the offset) and retries EAGAIN/EINTR with
|
|
99
|
+
* a brief Atomics.wait backoff that yields the thread so the reader can drain.
|
|
100
|
+
* Non-transient errors (e.g. EPIPE) propagate unchanged.
|
|
101
|
+
*/
|
|
102
|
+
function writeAllSync(fd, data) {
|
|
103
|
+
const buf = Buffer.from(data, 'utf8');
|
|
104
|
+
let offset = 0;
|
|
105
|
+
let retries = 0;
|
|
106
|
+
while (offset < buf.length) {
|
|
107
|
+
try {
|
|
108
|
+
offset += node_fs_1.default.writeSync(fd, buf, offset, buf.length - offset);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const code = err.code ?? '';
|
|
112
|
+
if (WRITE_RETRY_ERRNOS.has(code) && retries < WRITE_MAX_RETRIES) {
|
|
113
|
+
retries += 1;
|
|
114
|
+
backoffOnce();
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function output(result, raw, rawValue) {
|
|
122
|
+
let data;
|
|
123
|
+
if (raw && rawValue !== undefined) {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
125
|
+
data = String(rawValue);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const json = JSON.stringify(result, null, 2);
|
|
129
|
+
// Large payloads exceed Claude Code's Bash tool buffer (~50KB).
|
|
130
|
+
// Write to tmpfile and output the path prefixed with @file: so callers can detect it.
|
|
131
|
+
if (json.length > 50000) {
|
|
132
|
+
reapStaleTempFiles();
|
|
133
|
+
ensureGsdTempDir();
|
|
134
|
+
const tmpPath = node_path_1.default.join(GSD_TEMP_DIR, `gsd-${Date.now()}.json`);
|
|
135
|
+
(0, shell_command_projection_cjs_1.platformWriteSync)(tmpPath, json);
|
|
136
|
+
data = '@file:' + tmpPath;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
data = json;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// process.stdout.write() is async when stdout is a pipe — process.exit()
|
|
143
|
+
// can tear down the process before the reader consumes the buffer. writeAllSync
|
|
144
|
+
// pushes every byte synchronously (looping short counts, retrying EAGAIN/EINTR),
|
|
145
|
+
// and skipping process.exit() lets the event loop drain naturally.
|
|
146
|
+
writeAllSync(1, data);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Frozen enum of typed reason codes used by error() for structured errors.
|
|
150
|
+
* Each subcommand contributes its own codes; the enum exists so tests can
|
|
151
|
+
* assert against typed values instead of grepping stderr (#2974).
|
|
152
|
+
*
|
|
153
|
+
* Adding a new code:
|
|
154
|
+
* - Pick a snake_case lowercase value (the JSON wire form)
|
|
155
|
+
* - Group by subsystem prefix (CONFIG_*, SDK_*, etc)
|
|
156
|
+
* - Pass it to error(msg, ERROR_REASON.NEW_CODE) at the call site
|
|
157
|
+
*/
|
|
158
|
+
const ERROR_REASON = Object.freeze({
|
|
159
|
+
// config-get / config-set
|
|
160
|
+
CONFIG_KEY_NOT_FOUND: 'config_key_not_found',
|
|
161
|
+
CONFIG_NO_FILE: 'config_no_file',
|
|
162
|
+
CONFIG_PARSE_FAILED: 'config_parse_failed',
|
|
163
|
+
CONFIG_INVALID_KEY: 'config_invalid_key',
|
|
164
|
+
// SDK / gsd-tools dispatch
|
|
165
|
+
SDK_FAIL_FAST: 'sdk_fail_fast',
|
|
166
|
+
SDK_UNKNOWN_COMMAND: 'sdk_unknown_command',
|
|
167
|
+
SDK_MISSING_ARG: 'sdk_missing_arg',
|
|
168
|
+
// workflow / phase
|
|
169
|
+
PHASE_NOT_FOUND: 'phase_not_found',
|
|
170
|
+
SUMMARY_NO_PLANNING: 'summary_no_planning',
|
|
171
|
+
// graphify
|
|
172
|
+
GRAPHIFY_NO_GRAPH: 'graphify_no_graph',
|
|
173
|
+
GRAPHIFY_INVALID_QUERY: 'graphify_invalid_query',
|
|
174
|
+
// hooks
|
|
175
|
+
HOOKS_OPT_OUT: 'hooks_opt_out',
|
|
176
|
+
// security-scan
|
|
177
|
+
SECURITY_SCAN_FAILED: 'security_scan_failed',
|
|
178
|
+
// generic
|
|
179
|
+
USAGE: 'usage',
|
|
180
|
+
UNKNOWN: 'unknown',
|
|
181
|
+
});
|
|
182
|
+
/**
|
|
183
|
+
* Process-level flag: when true, error() emits structured JSON to stderr
|
|
184
|
+
* instead of plain "Error: <message>" text. Set by gsd-tools.cjs when the
|
|
185
|
+
* CLI is invoked with `--json-errors`. Tests opt in to typed-IR error
|
|
186
|
+
* assertions by passing that flag and parsing the JSON.
|
|
187
|
+
*
|
|
188
|
+
* Default off so existing callers and human operators keep their plain-text
|
|
189
|
+
* diagnostics. The structured form is opt-in for tooling and tests (#2974).
|
|
190
|
+
*/
|
|
191
|
+
let _jsonErrorMode = false;
|
|
192
|
+
function setJsonErrorMode(v) { _jsonErrorMode = !!v; }
|
|
193
|
+
function getJsonErrorMode() { return _jsonErrorMode; }
|
|
194
|
+
/**
|
|
195
|
+
* Emit an error and exit. When the second argument is provided it must be
|
|
196
|
+
* a value from ERROR_REASON; tests can assert on `result.reason`. When the
|
|
197
|
+
* process is in JSON-error mode, stderr receives `{ ok: false, reason,
|
|
198
|
+
* message }` so callers can parse it; otherwise stderr keeps the plain
|
|
199
|
+
* text form for human operators.
|
|
200
|
+
*/
|
|
201
|
+
function error(message, reason = ERROR_REASON.UNKNOWN) {
|
|
202
|
+
if (_jsonErrorMode) {
|
|
203
|
+
const payload = JSON.stringify({ ok: false, reason, message }) + '\n';
|
|
204
|
+
writeAllSync(2, payload);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
writeAllSync(2, 'Error: ' + message + '\n');
|
|
208
|
+
}
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
module.exports = {
|
|
212
|
+
GSD_TEMP_DIR,
|
|
213
|
+
ensureGsdTempDir,
|
|
214
|
+
reapStaleTempFiles,
|
|
215
|
+
output,
|
|
216
|
+
ERROR_REASON,
|
|
217
|
+
setJsonErrorMode,
|
|
218
|
+
getJsonErrorMode,
|
|
219
|
+
error,
|
|
220
|
+
};
|
|
@@ -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 ioMod = require("./io.cjs");
|
|
27
|
+
const { output, error: coreError } = ioMod;
|
|
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
|
+
};
|