@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,497 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Capability State Resolver — ADR-857 phase 4b
|
|
4
|
+
*
|
|
5
|
+
* Unified capability-state resolver that composes the three toggle systems
|
|
6
|
+
* (install profile, runtime surface, config activation) into one per-capability
|
|
7
|
+
* view. The loop resolver consumes this state so workflow dispatch and the
|
|
8
|
+
* `gsd-tools capability state` diagnostic share the same enablement answer.
|
|
9
|
+
*
|
|
10
|
+
* Exports (three things, mirroring loop-resolver):
|
|
11
|
+
* resolveCapabilityState({ registry, installedSkills, surfacedSkills, config, cwd })
|
|
12
|
+
* → { capabilities: CapabilityStateEntry[] }
|
|
13
|
+
* cmdCapabilityState(cwd, runtimeConfigDir, raw, options) — I/O entry point
|
|
14
|
+
*
|
|
15
|
+
* resolveCapabilityState is DETERMINISTIC given (registry, installedSkills,
|
|
16
|
+
* surfacedSkills, config) and — when `cwd` is provided — the project config
|
|
17
|
+
* files at `cwd` (.planning/config.json etc). Pass `cwd: undefined` for a
|
|
18
|
+
* pure, config-only resolution with no filesystem I/O.
|
|
19
|
+
* cmdCapabilityState is the I/O handler.
|
|
20
|
+
*
|
|
21
|
+
* Dependencies (leaf modules only — no circular risk):
|
|
22
|
+
* - node:path
|
|
23
|
+
* - ./io.cjs (output, error)
|
|
24
|
+
* - ./capability-activation.cjs (_resolveActivationValue)
|
|
25
|
+
* - ./install-profiles.cjs (readActiveProfile, loadSkillsManifest, resolveProfile)
|
|
26
|
+
* - ./surface.cjs (resolveSurface)
|
|
27
|
+
* - ./config-loader.cjs (loadConfig)
|
|
28
|
+
* - ./runtime-homes.cjs (getGlobalConfigDir — for runtimeConfigDir auto-detection)
|
|
29
|
+
* - ./runtime-slash.cjs (resolveRuntime — GSD_RUNTIME > config.runtime > 'claude' precedence)
|
|
30
|
+
* - capability-registry.cjs (loaded at call time)
|
|
31
|
+
*/
|
|
32
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
|
+
};
|
|
35
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
36
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const ioMod = require("./io.cjs");
|
|
39
|
+
const { output: coreOutput, error: coreError } = ioMod;
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
41
|
+
const activationMod = require("./capability-activation.cjs");
|
|
42
|
+
const { _resolveActivationValue } = activationMod;
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
44
|
+
const configLoaderMod = require("./config-loader.cjs");
|
|
45
|
+
const { loadConfig } = configLoaderMod;
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
47
|
+
const installProfilesMod = require("./install-profiles.cjs");
|
|
48
|
+
const { readActiveProfile, loadSkillsManifest, resolveProfile, parseRequires } = installProfilesMod;
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
50
|
+
const surfaceMod = require("./surface.cjs");
|
|
51
|
+
const { resolveSurface } = surfaceMod;
|
|
52
|
+
// ─── Prototype-pollution guard (inline literal, CodeQL barrier) ───────────────
|
|
53
|
+
function _isSafePropKey(key) {
|
|
54
|
+
// Inline literal guards — CodeQL barrier pattern
|
|
55
|
+
if (typeof key !== 'string')
|
|
56
|
+
return false;
|
|
57
|
+
if (key === '__proto__')
|
|
58
|
+
return false;
|
|
59
|
+
if (key === 'constructor')
|
|
60
|
+
return false;
|
|
61
|
+
if (key === 'prototype')
|
|
62
|
+
return false;
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// ─── Pure resolver ─────────────────────────────────────────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Deterministic resolver: for each capability in the registry, produce the
|
|
68
|
+
* three-dimension state view:
|
|
69
|
+
* 1. installed — does the install profile cover this capability?
|
|
70
|
+
* 2. surfaced — does the runtime surface enable this capability?
|
|
71
|
+
* 3. hooks — per-hook activation derived from config `when` keys.
|
|
72
|
+
*
|
|
73
|
+
* Determinism contract: given the same (registry, installedSkills,
|
|
74
|
+
* surfacedSkills, config) and — when `cwd` is set — the same project config
|
|
75
|
+
* files at `cwd`, the output is identical across calls. Pass `cwd: undefined`
|
|
76
|
+
* for a pure, config-only resolution with no filesystem I/O.
|
|
77
|
+
*
|
|
78
|
+
* Never throws for malformed registry/hook entries — skips/defaults defensively.
|
|
79
|
+
* An empty or missing capabilities object → { capabilities: [] }.
|
|
80
|
+
*
|
|
81
|
+
* @param input.registry The capability-registry.cjs module export.
|
|
82
|
+
* @param input.installedSkills Set<string> | '*' — from resolveProfile().skills.
|
|
83
|
+
* @param input.surfacedSkills Set<string> — from resolveSurface().skills.
|
|
84
|
+
* @param input.config Record from loadConfig(cwd).
|
|
85
|
+
* @param input.cwd Optional; when provided, enables raw .planning/config.json
|
|
86
|
+
* fallback reads (levels 2+3 of _resolveActivationValue
|
|
87
|
+
* precedence). Omit for a pure in-memory resolution.
|
|
88
|
+
*/
|
|
89
|
+
function resolveCapabilityState(input) {
|
|
90
|
+
const { registry, installedSkills, surfacedSkills, config, cwd } = input;
|
|
91
|
+
// Guard: registry missing capabilities
|
|
92
|
+
if (!registry || typeof registry !== 'object' || Array.isArray(registry)) {
|
|
93
|
+
return { capabilities: [] };
|
|
94
|
+
}
|
|
95
|
+
const capabilitiesRaw = registry['capabilities'];
|
|
96
|
+
if (!capabilitiesRaw || typeof capabilitiesRaw !== 'object' || Array.isArray(capabilitiesRaw)) {
|
|
97
|
+
return { capabilities: [] };
|
|
98
|
+
}
|
|
99
|
+
const capabilitiesMap = capabilitiesRaw;
|
|
100
|
+
const results = [];
|
|
101
|
+
for (const capId of Object.keys(capabilitiesMap)) {
|
|
102
|
+
// Prototype-pollution guard on capability id
|
|
103
|
+
if (!_isSafePropKey(capId))
|
|
104
|
+
continue;
|
|
105
|
+
const cap = capabilitiesMap[capId];
|
|
106
|
+
if (!cap || typeof cap !== 'object' || Array.isArray(cap))
|
|
107
|
+
continue;
|
|
108
|
+
const capObj = cap;
|
|
109
|
+
// Extract tier
|
|
110
|
+
const tier = typeof capObj['tier'] === 'string' ? capObj['tier'] : 'unknown';
|
|
111
|
+
// Extract skills array
|
|
112
|
+
const skillsRaw = capObj['skills'];
|
|
113
|
+
const skills = Array.isArray(skillsRaw)
|
|
114
|
+
? skillsRaw.filter((s) => typeof s === 'string')
|
|
115
|
+
: [];
|
|
116
|
+
// ── installed ──────────────────────────────────────────────────────────────
|
|
117
|
+
// Empty-skills cap → vacuously installed (no skills to be absent).
|
|
118
|
+
// installedSkills === '*' → installed = true for every cap.
|
|
119
|
+
let installed;
|
|
120
|
+
if (installedSkills === '*') {
|
|
121
|
+
installed = true;
|
|
122
|
+
}
|
|
123
|
+
else if (skills.length === 0) {
|
|
124
|
+
installed = true; // vacuous: no skills required
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
installed = skills.every((s) => installedSkills.has(s));
|
|
128
|
+
}
|
|
129
|
+
// ── surfaced ───────────────────────────────────────────────────────────────
|
|
130
|
+
// Empty-skills cap → vacuously surfaced.
|
|
131
|
+
let surfaced;
|
|
132
|
+
if (skills.length === 0) {
|
|
133
|
+
surfaced = true; // vacuous
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
surfaced = skills.every((s) => surfacedSkills.has(s));
|
|
137
|
+
}
|
|
138
|
+
const enabled = installed && surfaced;
|
|
139
|
+
// ── per-capability config activation ──────────────────────────────────────
|
|
140
|
+
// Resolve the capability's own activationKey (if present). This is the
|
|
141
|
+
// config-level toggle that gates the whole capability — separate from the
|
|
142
|
+
// per-hook `when` keys that gate individual hooks. When activationKey is
|
|
143
|
+
// absent, configActivation defaults to true (no config gate on the cap).
|
|
144
|
+
// active = enabled && configActivation (enabled unchanged: installed && surfaced)
|
|
145
|
+
const activationKey = typeof capObj['activationKey'] === 'string' && capObj['activationKey'].length > 0
|
|
146
|
+
? capObj['activationKey']
|
|
147
|
+
: undefined;
|
|
148
|
+
const configActivation = activationKey !== undefined
|
|
149
|
+
? _resolveActivationValue(activationKey, config, cwd, registry)
|
|
150
|
+
: true;
|
|
151
|
+
const active = enabled && configActivation;
|
|
152
|
+
// ── hooks ──────────────────────────────────────────────────────────────────
|
|
153
|
+
// Collect from steps, gates, contributions. Each may have a `when` key.
|
|
154
|
+
// Activation semantics (mirrors loop-resolver.isActive exactly):
|
|
155
|
+
// - No `when` field present (undefined/null) → unconditional, active=true
|
|
156
|
+
// - Non-empty string `when` → resolve via _resolveActivationValue
|
|
157
|
+
// - Present-but-empty-string or non-string `when` → malformed, active=false
|
|
158
|
+
// The original `when` value is carried through to the output for visibility.
|
|
159
|
+
const hooks = [];
|
|
160
|
+
function processHooks(arr, kind) {
|
|
161
|
+
for (const hookRaw of arr) {
|
|
162
|
+
if (!hookRaw || typeof hookRaw !== 'object' || Array.isArray(hookRaw))
|
|
163
|
+
continue;
|
|
164
|
+
const h = hookRaw;
|
|
165
|
+
const point = typeof h['point'] === 'string' ? h['point'] : '';
|
|
166
|
+
// Carry the raw `when` value through for visibility
|
|
167
|
+
const whenRaw = h['when'];
|
|
168
|
+
let configured;
|
|
169
|
+
if (whenRaw === undefined || whenRaw === null) {
|
|
170
|
+
// No `when` field → unconditional, always active
|
|
171
|
+
configured = true;
|
|
172
|
+
}
|
|
173
|
+
else if (typeof whenRaw === 'string' && whenRaw.length > 0) {
|
|
174
|
+
// Non-empty string `when` → resolve via _resolveActivationValue
|
|
175
|
+
configured = _resolveActivationValue(whenRaw, config, cwd, registry);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Present-but-empty-string or non-string `when` → malformed, inactive
|
|
179
|
+
// (mirrors loop-resolver.isActive: `typeof when !== 'string' || when.length === 0` → false)
|
|
180
|
+
configured = false;
|
|
181
|
+
}
|
|
182
|
+
// Hook active = capability-level active AND hook's own config gate.
|
|
183
|
+
// The capability's `active` constant (= enabled && configActivation) is
|
|
184
|
+
// used here so that a config-disabled capability (active=false) cannot
|
|
185
|
+
// produce active hooks even when the hook's own `when` is unconditional
|
|
186
|
+
// (configured=true). The capability gate cascades to all its hooks.
|
|
187
|
+
hooks.push({ point, kind, when: whenRaw, configured, active: active && configured });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const stepsRaw = capObj['steps'];
|
|
191
|
+
const gatesRaw = capObj['gates'];
|
|
192
|
+
const contributionsRaw = capObj['contributions'];
|
|
193
|
+
processHooks(Array.isArray(stepsRaw) ? stepsRaw : [], 'step');
|
|
194
|
+
processHooks(Array.isArray(gatesRaw) ? gatesRaw : [], 'gate');
|
|
195
|
+
processHooks(Array.isArray(contributionsRaw) ? contributionsRaw : [], 'contribution');
|
|
196
|
+
results.push({ id: capId, tier, skills, installed, surfaced, enabled, active, hooks });
|
|
197
|
+
}
|
|
198
|
+
// Deterministic sort by id for stable output across calls
|
|
199
|
+
results.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
200
|
+
return { capabilities: results };
|
|
201
|
+
}
|
|
202
|
+
// ─── I/O command handler ───────────────────────────────────────────────────────
|
|
203
|
+
/**
|
|
204
|
+
* Derive the commands/gsd path from __dirname (which resolves to
|
|
205
|
+
* gsd-core/bin/lib/ at runtime). The source tree is:
|
|
206
|
+
* <repo>/gsd-core/bin/lib/capability-state.cjs
|
|
207
|
+
* <repo>/commands/gsd/*.md
|
|
208
|
+
* So we walk up three levels: lib/ → bin/ → gsd-core/ → <repo>/, then
|
|
209
|
+
* into commands/gsd/.
|
|
210
|
+
*/
|
|
211
|
+
function _resolveCommandsGsdDir() {
|
|
212
|
+
// __dirname = pp-core/bin/lib/
|
|
213
|
+
const repoRoot = node_path_1.default.resolve(__dirname, '..', '..', '..');
|
|
214
|
+
// D-12 flat-hyphen: commands ship flat in commands/ as pp-<cmd>.md. Older
|
|
215
|
+
// layouts had the namespaced commands/gsd/ subdir — prefer flat, fall back to
|
|
216
|
+
// legacy so capability/skill-manifest resolution works on both.
|
|
217
|
+
const legacy = node_path_1.default.join(repoRoot, 'commands', 'gsd');
|
|
218
|
+
return node_fs_1.default.existsSync(legacy) ? legacy : node_path_1.default.join(repoRoot, 'commands');
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Build a skill dependency manifest from an INSTALLED runtime's skills directory.
|
|
222
|
+
*
|
|
223
|
+
* In an installed runtime (e.g. Codex at ~/.codex), gsd skills live as
|
|
224
|
+
* configDir/skills/gsd-STEM/SKILL.md. There is no commands/gsd source tree.
|
|
225
|
+
* This function scans that installed layout and builds the same
|
|
226
|
+
* Map shape that loadSkillsManifest produces from sources.
|
|
227
|
+
*
|
|
228
|
+
* Stem extraction: a directory named gsd-secure-phase maps to stem secure-phase.
|
|
229
|
+
* Only directories whose names start with gsd- are included so user-created
|
|
230
|
+
* skills (without the gsd- prefix) are not accidentally pulled in.
|
|
231
|
+
*
|
|
232
|
+
* The requires: field is parsed via the shared parseRequires helper (the same
|
|
233
|
+
* parser loadSkillsManifest uses), so the two paths cannot drift.
|
|
234
|
+
*
|
|
235
|
+
* Returns an empty Map when the skills dir does not exist.
|
|
236
|
+
*/
|
|
237
|
+
function _loadInstalledSkillsManifest(configDir) {
|
|
238
|
+
const manifest = new Map();
|
|
239
|
+
const skillsDir = node_path_1.default.join(configDir, 'skills');
|
|
240
|
+
if (!node_fs_1.default.existsSync(skillsDir))
|
|
241
|
+
return manifest;
|
|
242
|
+
let entries;
|
|
243
|
+
try {
|
|
244
|
+
entries = node_fs_1.default.readdirSync(skillsDir, { withFileTypes: true });
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return manifest;
|
|
248
|
+
}
|
|
249
|
+
for (const entry of entries) {
|
|
250
|
+
if (!entry.isDirectory())
|
|
251
|
+
continue;
|
|
252
|
+
if (!entry.name.startsWith('gsd-'))
|
|
253
|
+
continue;
|
|
254
|
+
// Strip the 'gsd-' prefix to get the skill stem
|
|
255
|
+
const stem = entry.name.slice(4); // 'gsd-'.length === 4
|
|
256
|
+
if (!stem)
|
|
257
|
+
continue;
|
|
258
|
+
const skillMdPath = node_path_1.default.join(skillsDir, entry.name, 'SKILL.md');
|
|
259
|
+
// Parity with loadSkillsManifest: a stem exists only when its artifact
|
|
260
|
+
// file is present. loadSkillsManifest registers a stem per .md FILE (and
|
|
261
|
+
// tolerates an unreadable file as []), but never invents a stem for which
|
|
262
|
+
// no file exists. Mirror that here: a stale gsd-<stem>/ directory with no
|
|
263
|
+
// SKILL.md must NOT register the stem — otherwise the capability would be
|
|
264
|
+
// wrongly reported surfaced/enabled and a verify:post hook would render
|
|
265
|
+
// for a skill that cannot run.
|
|
266
|
+
if (!node_fs_1.default.existsSync(skillMdPath))
|
|
267
|
+
continue;
|
|
268
|
+
let content = '';
|
|
269
|
+
try {
|
|
270
|
+
content = node_fs_1.default.readFileSync(skillMdPath, 'utf8');
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// SKILL.md present but unreadable — register with no deps (parity with
|
|
274
|
+
// loadSkillsManifest's readFileSync catch branch).
|
|
275
|
+
}
|
|
276
|
+
// Parse requires: via the SAME shared parser loadSkillsManifest uses, so
|
|
277
|
+
// installed-runtime dependency resolution can never silently diverge from
|
|
278
|
+
// the source-tree path (single source of truth — no duplicated regex).
|
|
279
|
+
manifest.set(stem, content ? parseRequires(content) : []);
|
|
280
|
+
// Mirror loadSkillsManifest's Map shape: it always sets a companion
|
|
281
|
+
// `_calls_agents_<stem>` key. Installed SKILL.md bodies carry no
|
|
282
|
+
// recoverable agent-call refs, so [] (the no-agents case) keeps the two
|
|
283
|
+
// manifest shapes identical and prevents undefined-vs-[] drift for any
|
|
284
|
+
// consumer that reads the agent-refs companion key.
|
|
285
|
+
manifest.set(`_calls_agents_${stem}`, []);
|
|
286
|
+
}
|
|
287
|
+
return manifest;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Resolve the skill dependency manifest for capability-state resolution.
|
|
291
|
+
*
|
|
292
|
+
* Resolution order (fixes #1160 — installed-runtime capability surface):
|
|
293
|
+
* 1. If commandsGsdDir exists, load from source (repo-checkout behavior).
|
|
294
|
+
* 2. Otherwise, fall back to installed skills at configDir/skills/gsd-[stem]/SKILL.md.
|
|
295
|
+
*
|
|
296
|
+
* In an installed runtime the commands/gsd source tree is absent; only the
|
|
297
|
+
* skills/ layout exists. Returning an empty manifest caused resolveSurface to
|
|
298
|
+
* materialise the full-sentinel to an empty Set, making every capability appear
|
|
299
|
+
* unsurfaced even when the skill was physically installed.
|
|
300
|
+
*/
|
|
301
|
+
function _resolveManifest(commandsGsdDir, configDir) {
|
|
302
|
+
if (node_fs_1.default.existsSync(commandsGsdDir)) {
|
|
303
|
+
return loadSkillsManifest(commandsGsdDir);
|
|
304
|
+
}
|
|
305
|
+
return _loadInstalledSkillsManifest(configDir);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Command entry point: resolve install profile, surface, and config; compute
|
|
309
|
+
* capability state; emit the envelope via io.output.
|
|
310
|
+
*
|
|
311
|
+
* Envelope: { runtimeConfigDir, warnings?: string[], capabilities: CapabilityStateEntry[] }
|
|
312
|
+
*
|
|
313
|
+
* runtimeConfigDir resolution (when not provided or empty):
|
|
314
|
+
* Detects the active runtime via the canonical precedence:
|
|
315
|
+
* process.env.GSD_RUNTIME → config.runtime → 'claude'
|
|
316
|
+
* (using resolveRuntime() from runtime-slash.cjs, the same precedence used
|
|
317
|
+
* by profile-output.cjs and the rest of the runtime resolution chain).
|
|
318
|
+
* Then calls getGlobalConfigDir(detectedRuntime) from runtime-homes.cjs —
|
|
319
|
+
* the same resolver used by install.js. This correctly handles all supported
|
|
320
|
+
* runtimes (claude, codex, cursor, gemini, opencode, grok, etc.) and their
|
|
321
|
+
* env-var overrides (CLAUDE_CONFIG_DIR, CODEX_HOME, CURSOR_CONFIG_DIR, …).
|
|
322
|
+
* Defaults to ~/.claude if either resolver throws.
|
|
323
|
+
*
|
|
324
|
+
* Failure surfacing: genuine resolution failures (manifest/profile/surface
|
|
325
|
+
* errors) are reported in the `warnings` array in the envelope. The output
|
|
326
|
+
* remains useful — degraded to the best available state — but the caller can
|
|
327
|
+
* detect that the state is not fully resolved.
|
|
328
|
+
*
|
|
329
|
+
* Legitimate "no marker → default full profile" is NOT a warning.
|
|
330
|
+
* A thrown error during profile/surface resolution IS a warning.
|
|
331
|
+
*
|
|
332
|
+
* @param cwd Project root directory
|
|
333
|
+
* @param runtimeConfigDir Runtime config directory (e.g. ~/.claude). May be
|
|
334
|
+
* empty/undefined — falls back to auto-detection.
|
|
335
|
+
* Providing a value without a next token (e.g. the flag
|
|
336
|
+
* is last in argv with no following value) should be
|
|
337
|
+
* caught by the caller before invoking this function.
|
|
338
|
+
* @param raw Whether to emit raw JSON (io.output raw mode)
|
|
339
|
+
* @param _options Reserved for future use
|
|
340
|
+
*/
|
|
341
|
+
function resolveCapabilityRuntimeState(cwd, runtimeConfigDir, configOverride) {
|
|
342
|
+
const warnings = [];
|
|
343
|
+
// Resolve runtimeConfigDir using the canonical runtime-homes resolver.
|
|
344
|
+
// When not provided, the active runtime is detected via the canonical
|
|
345
|
+
// precedence: process.env.GSD_RUNTIME → config.runtime → 'claude'
|
|
346
|
+
// (mirrors resolveRuntime() from runtime-slash.cjs and the precedence used
|
|
347
|
+
// by profile-output.cjs and the rest of the runtime resolution chain).
|
|
348
|
+
// getGlobalConfigDir(detectedRuntime) is then called, which honours the
|
|
349
|
+
// runtime-specific env-var override (CLAUDE_CONFIG_DIR, CODEX_HOME,
|
|
350
|
+
// CURSOR_CONFIG_DIR, GROK_AGENTS_HOME, etc.) correctly and without
|
|
351
|
+
// fabricating env vars that don't exist upstream.
|
|
352
|
+
let resolvedConfigDir = runtimeConfigDir || '';
|
|
353
|
+
if (!resolvedConfigDir) {
|
|
354
|
+
try {
|
|
355
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
356
|
+
const runtimeHomes = require('./runtime-homes.cjs');
|
|
357
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
358
|
+
const runtimeSlash = require('./runtime-slash.cjs');
|
|
359
|
+
// Detect the active runtime via GSD_RUNTIME → config.runtime → 'claude'.
|
|
360
|
+
// resolveRuntime reads config.json directly (no side effects) and returns
|
|
361
|
+
// a lowercased canonical runtime name.
|
|
362
|
+
const detectedRuntime = runtimeSlash.resolveRuntime(cwd);
|
|
363
|
+
resolvedConfigDir = runtimeHomes.getGlobalConfigDir(detectedRuntime);
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// Defensive fallback: use ~/.claude if the canonical resolver throws.
|
|
367
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
368
|
+
const os = require('node:os');
|
|
369
|
+
resolvedConfigDir = node_path_1.default.join(os.homedir(), '.claude');
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// ── Load registry (ADR-857 phase 4c) ────────────────────────────────────────
|
|
373
|
+
// Load BEFORE resolveProfile and resolveSurface so both calls receive the
|
|
374
|
+
// registry and capability-contributed skills are reflected in installed/surfaced.
|
|
375
|
+
// No-op today (UI capability is tier:full → only adds to 'full', which returns
|
|
376
|
+
// '*' regardless) but cutover-ready for future tier:core/standard capabilities.
|
|
377
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
378
|
+
const registry = require('./capability-registry.cjs');
|
|
379
|
+
// ── Resolve installed skills (from install profile) ──────────────────────────
|
|
380
|
+
// Distinguish "no profile marker → default full" (legitimate) from a thrown
|
|
381
|
+
// error (surface as a warning and degrade gracefully — do NOT silently report
|
|
382
|
+
// installedSkills='*' as if the install profile were truly unlimited).
|
|
383
|
+
let installedSkills;
|
|
384
|
+
try {
|
|
385
|
+
const commandsGsdDir = _resolveCommandsGsdDir();
|
|
386
|
+
// Fix #1160: use _resolveManifest so installed-runtime layouts (where
|
|
387
|
+
// commands/gsd is absent) fall back to <configDir>/skills/gsd-*/SKILL.md.
|
|
388
|
+
const manifest = _resolveManifest(commandsGsdDir, resolvedConfigDir);
|
|
389
|
+
const profileName = readActiveProfile(resolvedConfigDir) ?? 'full';
|
|
390
|
+
const resolvedInstall = resolveProfile({
|
|
391
|
+
modes: profileName.split(',').map((s) => s.trim()),
|
|
392
|
+
manifest,
|
|
393
|
+
registry,
|
|
394
|
+
});
|
|
395
|
+
installedSkills = resolvedInstall.skills;
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
// Genuine resolution failure — surface it so the caller is not misled.
|
|
399
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
400
|
+
warnings.push(`profile-resolution failed: ${msg}`);
|
|
401
|
+
// Degrade to empty set (not '*') so installed=false is reported accurately.
|
|
402
|
+
installedSkills = new Set();
|
|
403
|
+
}
|
|
404
|
+
// ── Resolve surfaced skills (from runtime surface) ────────────────────────────
|
|
405
|
+
let surfacedSkills;
|
|
406
|
+
try {
|
|
407
|
+
const commandsGsdDir = _resolveCommandsGsdDir();
|
|
408
|
+
// Fix #1160: use _resolveManifest so installed-runtime layouts (where
|
|
409
|
+
// commands/gsd is absent) fall back to <configDir>/skills/gsd-*/SKILL.md.
|
|
410
|
+
const manifest = _resolveManifest(commandsGsdDir, resolvedConfigDir);
|
|
411
|
+
const surfaceResult = resolveSurface(resolvedConfigDir, manifest, undefined, registry);
|
|
412
|
+
// resolveSurface returns { name, skills: Set<string>, agents: Set<string> }
|
|
413
|
+
// (always a concrete Set — full profile is materialized)
|
|
414
|
+
surfacedSkills = surfaceResult.skills instanceof Set
|
|
415
|
+
? surfaceResult.skills
|
|
416
|
+
: new Set();
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
// Genuine surface resolution failure — surface it so the caller is not misled.
|
|
420
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
421
|
+
warnings.push(`surface-resolution failed: ${msg}`);
|
|
422
|
+
surfacedSkills = new Set();
|
|
423
|
+
}
|
|
424
|
+
// ── Load config ───────────────────────────────────────────────────────────────
|
|
425
|
+
// When the caller already holds a loadConfig snapshot (e.g. cmdLoopRenderHooks),
|
|
426
|
+
// accept it via configOverride so capability `active` and hook resolution
|
|
427
|
+
// share the SAME config object — single snapshot, no TOCTOU window.
|
|
428
|
+
let config;
|
|
429
|
+
if (configOverride !== undefined) {
|
|
430
|
+
config = configOverride;
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
try {
|
|
434
|
+
config = loadConfig(cwd);
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
config = {};
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
// ── Resolve state ────────────────────────────────────────────────────────────
|
|
441
|
+
const result = resolveCapabilityState({
|
|
442
|
+
registry,
|
|
443
|
+
installedSkills,
|
|
444
|
+
surfacedSkills,
|
|
445
|
+
config,
|
|
446
|
+
cwd,
|
|
447
|
+
});
|
|
448
|
+
return {
|
|
449
|
+
runtimeConfigDir: resolvedConfigDir,
|
|
450
|
+
warnings,
|
|
451
|
+
capabilities: result.capabilities,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function cmdCapabilityState(cwd, runtimeConfigDir, raw, _options = {}) {
|
|
455
|
+
const result = resolveCapabilityRuntimeState(cwd, runtimeConfigDir);
|
|
456
|
+
for (const warning of result.warnings) {
|
|
457
|
+
coreError(`capability state: ${warning}`);
|
|
458
|
+
}
|
|
459
|
+
// Build envelope — include warnings array only when non-empty so the nominal
|
|
460
|
+
// path keeps the output clean and callers can check `warnings` for degraded state.
|
|
461
|
+
const envelope = {
|
|
462
|
+
runtimeConfigDir: result.runtimeConfigDir,
|
|
463
|
+
capabilities: result.capabilities,
|
|
464
|
+
};
|
|
465
|
+
if (result.warnings.length > 0) {
|
|
466
|
+
envelope.warnings = result.warnings;
|
|
467
|
+
}
|
|
468
|
+
coreOutput(envelope, raw);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Convenience predicate: returns true if the capability identified by `capId`
|
|
472
|
+
* is active (installed && surfaced && config-enabled) in the current runtime
|
|
473
|
+
* environment at `cwd`.
|
|
474
|
+
*
|
|
475
|
+
* Internally calls `resolveCapabilityRuntimeState(cwd, undefined)` and returns
|
|
476
|
+
* the `active` field of the matching CapabilityStateEntry.
|
|
477
|
+
* Returns `false` when the capability is not found in the registry.
|
|
478
|
+
*
|
|
479
|
+
* @param capId Capability identifier (e.g. 'graphify', 'intel')
|
|
480
|
+
* @param cwd Project root directory for config resolution
|
|
481
|
+
*/
|
|
482
|
+
function isCapabilityActive(capId, cwd) {
|
|
483
|
+
const result = resolveCapabilityRuntimeState(cwd, undefined);
|
|
484
|
+
const entry = result.capabilities.find((c) => c.id === capId);
|
|
485
|
+
return entry !== undefined ? entry.active : false;
|
|
486
|
+
}
|
|
487
|
+
module.exports = {
|
|
488
|
+
resolveCapabilityState,
|
|
489
|
+
resolveCapabilityRuntimeState,
|
|
490
|
+
isCapabilityActive,
|
|
491
|
+
cmdCapabilityState,
|
|
492
|
+
// Exported for tests
|
|
493
|
+
_resolveCommandsGsdDir,
|
|
494
|
+
_loadInstalledSkillsManifest,
|
|
495
|
+
_resolveManifest,
|
|
496
|
+
_isSafePropKey,
|
|
497
|
+
};
|