@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,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project-Root Resolution Module — resolves a project root from a starting
|
|
4
|
+
* directory by walking the ancestor chain and applying four heuristics:
|
|
5
|
+
* (0) own .planning/ guard (#1362)
|
|
6
|
+
* (1) parent .planning/config.json sub_repos
|
|
7
|
+
* (2) legacy multiRepo: true + ancestor .git
|
|
8
|
+
* (3) .git heuristic with parent .planning/
|
|
9
|
+
* Bounded by FIND_PROJECT_ROOT_MAX_DEPTH ancestors. Sync I/O.
|
|
10
|
+
*
|
|
11
|
+
* ADR-457 build-at-publish: the hand-written bin/lib/project-root.cjs
|
|
12
|
+
* collapsed to a TypeScript source of truth. Behaviour is preserved
|
|
13
|
+
* byte-for-behaviour from the prior hand-written .cjs; only types are added.
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.findProjectRoot = findProjectRoot;
|
|
20
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
21
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
22
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
23
|
+
const FIND_PROJECT_ROOT_MAX_DEPTH = 10;
|
|
24
|
+
function findProjectRoot(startDir) {
|
|
25
|
+
let resolvedStart;
|
|
26
|
+
try {
|
|
27
|
+
resolvedStart = node_path_1.default.resolve(startDir);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return startDir;
|
|
31
|
+
}
|
|
32
|
+
const fsRoot = node_path_1.default.parse(resolvedStart).root;
|
|
33
|
+
const home = node_os_1.default.homedir();
|
|
34
|
+
// If startDir already contains .planning/, it IS the project root.
|
|
35
|
+
try {
|
|
36
|
+
const ownPlanningDir = resolvedStart + node_path_1.default.sep + '.planning';
|
|
37
|
+
if (node_fs_1.default.existsSync(ownPlanningDir) && node_fs_1.default.statSync(ownPlanningDir).isDirectory()) {
|
|
38
|
+
return startDir;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// fall through
|
|
43
|
+
}
|
|
44
|
+
// Walk upward, mirroring isInsideGitRepo from the CJS reference.
|
|
45
|
+
function isInsideGitRepo(candidateParent) {
|
|
46
|
+
let d = resolvedStart;
|
|
47
|
+
while (d !== fsRoot) {
|
|
48
|
+
try {
|
|
49
|
+
if (node_fs_1.default.existsSync(d + node_path_1.default.sep + '.git'))
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// ignore
|
|
54
|
+
}
|
|
55
|
+
if (d === candidateParent)
|
|
56
|
+
break;
|
|
57
|
+
const next = node_path_1.default.dirname(d);
|
|
58
|
+
if (next === d)
|
|
59
|
+
break;
|
|
60
|
+
d = next;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
let dir = resolvedStart;
|
|
65
|
+
let depth = 0;
|
|
66
|
+
while (dir !== fsRoot && depth < FIND_PROJECT_ROOT_MAX_DEPTH) {
|
|
67
|
+
const parent = node_path_1.default.dirname(dir);
|
|
68
|
+
if (parent === dir)
|
|
69
|
+
break;
|
|
70
|
+
if (parent === home)
|
|
71
|
+
break;
|
|
72
|
+
const parentPlanning = parent + node_path_1.default.sep + '.planning';
|
|
73
|
+
let parentPlanningIsDir = false;
|
|
74
|
+
try {
|
|
75
|
+
parentPlanningIsDir = node_fs_1.default.existsSync(parentPlanning) && node_fs_1.default.statSync(parentPlanning).isDirectory();
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
parentPlanningIsDir = false;
|
|
79
|
+
}
|
|
80
|
+
if (parentPlanningIsDir) {
|
|
81
|
+
const configPath = parentPlanning + node_path_1.default.sep + 'config.json';
|
|
82
|
+
let matched = false;
|
|
83
|
+
try {
|
|
84
|
+
const raw = node_fs_1.default.readFileSync(configPath, 'utf-8');
|
|
85
|
+
const config = JSON.parse(raw);
|
|
86
|
+
if (config && typeof config === 'object') {
|
|
87
|
+
const cfg = config;
|
|
88
|
+
const subReposValue = cfg['sub_repos'] ??
|
|
89
|
+
(cfg['planning'] && typeof cfg['planning'] === 'object'
|
|
90
|
+
? cfg['planning']['sub_repos']
|
|
91
|
+
: undefined);
|
|
92
|
+
const subRepos = Array.isArray(subReposValue) ? subReposValue : [];
|
|
93
|
+
if (subRepos.length > 0) {
|
|
94
|
+
const relPath = node_path_1.default.relative(parent, resolvedStart);
|
|
95
|
+
const topSegment = relPath.split(node_path_1.default.sep)[0];
|
|
96
|
+
if (subRepos.includes(topSegment)) {
|
|
97
|
+
return parent;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (cfg['multiRepo'] === true && isInsideGitRepo(parent)) {
|
|
101
|
+
matched = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// config.json missing or unparseable — fall through to .git heuristic.
|
|
107
|
+
}
|
|
108
|
+
if (matched)
|
|
109
|
+
return parent;
|
|
110
|
+
// Heuristic: parent has .planning/ and we're inside a git repo.
|
|
111
|
+
if (isInsideGitRepo(parent)) {
|
|
112
|
+
return parent;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
dir = parent;
|
|
116
|
+
depth += 1;
|
|
117
|
+
}
|
|
118
|
+
return startDir;
|
|
119
|
+
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* prompt-budget.cts
|
|
4
|
+
*
|
|
5
|
+
* Pure functions for assembling and trimming review prompts to fit within
|
|
6
|
+
* a token budget (ADR-457 build-at-publish: the hand-written
|
|
7
|
+
* bin/lib/prompt-budget.cjs collapsed to a TypeScript source of truth).
|
|
8
|
+
* Behaviour is preserved byte-for-behaviour from the prior hand-written .cjs;
|
|
9
|
+
* only types are added.
|
|
10
|
+
*
|
|
11
|
+
* Used by the review pipeline to support small-context models.
|
|
12
|
+
*
|
|
13
|
+
* Trim priority (in order — never violate):
|
|
14
|
+
* 1. Instructions: ALWAYS kept verbatim
|
|
15
|
+
* 2. Reserve note tokens FIRST when any trim is anticipated
|
|
16
|
+
* 3. Roadmap: ALWAYS kept verbatim
|
|
17
|
+
* 4. PROJECT.md: head-shrink to projectMdHeadLines (default 40) if over budget
|
|
18
|
+
* 5. Plans: tail-truncate proportionally; never drop a whole plan
|
|
19
|
+
* 6. Context: DROP first if still over
|
|
20
|
+
* 7. Research: DROP second if still over
|
|
21
|
+
* 8. Requirements: DROP last (last-resort)
|
|
22
|
+
* 9. Hard-fail: if minimum-set exceeds effectiveBudget
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.estimateTokens = estimateTokens;
|
|
26
|
+
exports.applyBudget = applyBudget;
|
|
27
|
+
const NOTE_RESERVE_TOKENS = 80;
|
|
28
|
+
const DEFAULT_NOTE_TEMPLATE = [
|
|
29
|
+
'<note>',
|
|
30
|
+
'Prompt automatically trimmed to fit a {budget}-token budget.',
|
|
31
|
+
'Omitted sections: {omittedList}.',
|
|
32
|
+
'Plan content truncated by approximately {planTruncationPct}%.',
|
|
33
|
+
'Treat any missing context as out-of-scope rather than a review concern.',
|
|
34
|
+
'</note>',
|
|
35
|
+
].join('\n');
|
|
36
|
+
/**
|
|
37
|
+
* Estimate tokens for a string. Chars / 4, rounded up.
|
|
38
|
+
*/
|
|
39
|
+
function estimateTokens(text) {
|
|
40
|
+
if (!text)
|
|
41
|
+
return 0;
|
|
42
|
+
return Math.ceil(text.length / 4);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Render the trim-disclosure note.
|
|
46
|
+
*/
|
|
47
|
+
function renderNote(template, budget, omitted, planTruncationPct) {
|
|
48
|
+
const omittedList = omitted.length > 0 ? omitted.join(', ') : 'none';
|
|
49
|
+
return template
|
|
50
|
+
.replace('{budget}', String(budget))
|
|
51
|
+
.replace('{omittedList}', omittedList)
|
|
52
|
+
.replace('{planTruncationPct}', String(Math.round(planTruncationPct)));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Head-shrink a string to at most `maxLines` lines.
|
|
56
|
+
*/
|
|
57
|
+
function headShrink(text, maxLines) {
|
|
58
|
+
if (maxLines <= 0)
|
|
59
|
+
return '';
|
|
60
|
+
let idx = -1;
|
|
61
|
+
let seen = 0;
|
|
62
|
+
while (seen < maxLines) {
|
|
63
|
+
idx = text.indexOf('\n', idx + 1);
|
|
64
|
+
if (idx === -1)
|
|
65
|
+
return text;
|
|
66
|
+
seen += 1;
|
|
67
|
+
}
|
|
68
|
+
return text.slice(0, idx);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Tail-truncate a string to at most `maxChars` characters.
|
|
72
|
+
*/
|
|
73
|
+
function tailTruncate(text, maxChars) {
|
|
74
|
+
if (text.length <= maxChars)
|
|
75
|
+
return text;
|
|
76
|
+
return text.slice(0, maxChars);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Assemble the final prompt string from its sections.
|
|
80
|
+
*/
|
|
81
|
+
function assemblePrompt(parts) {
|
|
82
|
+
const { instructions, note, roadmap, projectMd, plans, context, research, requirements, } = parts;
|
|
83
|
+
const blocks = [];
|
|
84
|
+
blocks.push(instructions);
|
|
85
|
+
if (note)
|
|
86
|
+
blocks.push(note);
|
|
87
|
+
blocks.push('## Roadmap\n\n' + roadmap);
|
|
88
|
+
if (projectMd)
|
|
89
|
+
blocks.push('## Project\n\n' + projectMd);
|
|
90
|
+
const planBlocks = plans
|
|
91
|
+
.map((p) => '### ' + p.file + '\n\n' + p.content)
|
|
92
|
+
.join('\n\n');
|
|
93
|
+
blocks.push('## Plans\n\n' + planBlocks);
|
|
94
|
+
if (context)
|
|
95
|
+
blocks.push('## Context\n\n' + context);
|
|
96
|
+
if (research)
|
|
97
|
+
blocks.push('## Research\n\n' + research);
|
|
98
|
+
if (requirements)
|
|
99
|
+
blocks.push('## Requirements\n\n' + requirements);
|
|
100
|
+
return blocks.join('\n\n');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Apply a token budget to a set of review prompt sections.
|
|
104
|
+
* Returns the trimmed prompt and structured metadata.
|
|
105
|
+
*/
|
|
106
|
+
function applyBudget({ sections, budget, options = {} }) {
|
|
107
|
+
const { safetyMarginPct = 10, noteTemplate = DEFAULT_NOTE_TEMPLATE, projectMdHeadLines = 40, } = options;
|
|
108
|
+
const effectiveBudget = Math.floor(budget * (1 - safetyMarginPct / 100));
|
|
109
|
+
const { instructions, roadmap, plans, projectMd: projectMdRaw = null, context: contextRaw = null, research: researchRaw = null, requirements: requirementsRaw = null, } = sections;
|
|
110
|
+
// Working mutable state
|
|
111
|
+
let projectMd = projectMdRaw;
|
|
112
|
+
let context = contextRaw;
|
|
113
|
+
let research = researchRaw;
|
|
114
|
+
let requirements = requirementsRaw;
|
|
115
|
+
let workingPlans = plans.map((p) => ({ file: p.file, content: p.content }));
|
|
116
|
+
const omitted = [];
|
|
117
|
+
let projectMdShrunk = false;
|
|
118
|
+
let planTruncationPct = 0;
|
|
119
|
+
let noteInjected = false;
|
|
120
|
+
let hardFailed = false;
|
|
121
|
+
// Minimum-set check: instructions + roadmap + 1KB per plan.
|
|
122
|
+
// NOTE_RESERVE_TOKENS is intentionally excluded here: a note is only injected
|
|
123
|
+
// when trimming actually occurs, and a prompt that fits without any trim needs
|
|
124
|
+
// no note at all. Including NOTE_RESERVE_TOKENS here would cause false hard-fails
|
|
125
|
+
// for prompts that genuinely fit the effective budget untrimmed.
|
|
126
|
+
const MIN_PLAN_BYTES = 1024;
|
|
127
|
+
const minPlanTokens = plans.reduce((sum, p) => {
|
|
128
|
+
return sum + estimateTokens(p.content.slice(0, MIN_PLAN_BYTES));
|
|
129
|
+
}, 0);
|
|
130
|
+
const minSet = estimateTokens(instructions) +
|
|
131
|
+
estimateTokens(roadmap) +
|
|
132
|
+
minPlanTokens;
|
|
133
|
+
if (minSet > effectiveBudget) {
|
|
134
|
+
return {
|
|
135
|
+
prompt: '',
|
|
136
|
+
metadata: {
|
|
137
|
+
budget,
|
|
138
|
+
effectiveBudget,
|
|
139
|
+
estimatedTokens: 0,
|
|
140
|
+
omitted: [],
|
|
141
|
+
projectMdShrunk: false,
|
|
142
|
+
planTruncationPct: 0,
|
|
143
|
+
hardFailed: true,
|
|
144
|
+
noteInjected: false,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// ── Budget accounting ──────────────────────────────────────────────────────
|
|
149
|
+
const TOKENS_ROADMAP_HEADER = estimateTokens('## Roadmap\n\n');
|
|
150
|
+
const TOKENS_PROJECT_HEADER = estimateTokens('## Project\n\n');
|
|
151
|
+
const TOKENS_PLANS_HEADER = estimateTokens('## Plans\n\n');
|
|
152
|
+
const TOKENS_CONTEXT_HEADER = estimateTokens('## Context\n\n');
|
|
153
|
+
const TOKENS_RESEARCH_HEADER = estimateTokens('## Research\n\n');
|
|
154
|
+
const TOKENS_REQUIREMENTS_HEADER = estimateTokens('## Requirements\n\n');
|
|
155
|
+
const TOKENS_PLAN_ITEM_HEADERS = workingPlans.reduce((sum, p) => sum + estimateTokens('### ' + p.file + '\n\n'), 0);
|
|
156
|
+
const staticBaseTokens = estimateTokens(instructions) +
|
|
157
|
+
TOKENS_ROADMAP_HEADER +
|
|
158
|
+
estimateTokens(roadmap) +
|
|
159
|
+
TOKENS_PLANS_HEADER +
|
|
160
|
+
TOKENS_PLAN_ITEM_HEADERS;
|
|
161
|
+
let projectTokens = projectMd
|
|
162
|
+
? TOKENS_PROJECT_HEADER + estimateTokens(projectMd)
|
|
163
|
+
: 0;
|
|
164
|
+
let contextTokens = context
|
|
165
|
+
? TOKENS_CONTEXT_HEADER + estimateTokens(context)
|
|
166
|
+
: 0;
|
|
167
|
+
let researchTokens = research
|
|
168
|
+
? TOKENS_RESEARCH_HEADER + estimateTokens(research)
|
|
169
|
+
: 0;
|
|
170
|
+
let requirementsTokens = requirements
|
|
171
|
+
? TOKENS_REQUIREMENTS_HEADER + estimateTokens(requirements)
|
|
172
|
+
: 0;
|
|
173
|
+
let planContentTokens = workingPlans.reduce((sum, p) => sum + estimateTokens(p.content), 0);
|
|
174
|
+
const getCurrentBaseTokens = () => staticBaseTokens +
|
|
175
|
+
projectTokens +
|
|
176
|
+
planContentTokens +
|
|
177
|
+
contextTokens +
|
|
178
|
+
researchTokens +
|
|
179
|
+
requirementsTokens;
|
|
180
|
+
let currentBaseTokens = getCurrentBaseTokens();
|
|
181
|
+
// Detect budget pressure: is ANY trim needed?
|
|
182
|
+
// Pressure exists when the current base tokens already exceed the effective
|
|
183
|
+
// budget. Only when pressure is real do we reserve NOTE_RESERVE_TOKENS so
|
|
184
|
+
// the note itself fits after trimming. Checking against
|
|
185
|
+
// effectiveBudget - NOTE_RESERVE_TOKENS (the old threshold) would cause
|
|
186
|
+
// spurious pressure 80 tokens early, dropping sections that fit fine.
|
|
187
|
+
const baseTokens = currentBaseTokens;
|
|
188
|
+
const budgetUnderPressure = baseTokens > effectiveBudget;
|
|
189
|
+
// Available for content (reserve note slot when under pressure)
|
|
190
|
+
const contentBudget = budgetUnderPressure
|
|
191
|
+
? effectiveBudget - NOTE_RESERVE_TOKENS
|
|
192
|
+
: effectiveBudget;
|
|
193
|
+
// ── Trim step 1: head-shrink PROJECT.md ───────────────────────────────────
|
|
194
|
+
if (currentBaseTokens > contentBudget && projectMd) {
|
|
195
|
+
const shrunk = headShrink(projectMd, projectMdHeadLines);
|
|
196
|
+
if (shrunk !== projectMd) {
|
|
197
|
+
projectMd = shrunk;
|
|
198
|
+
projectMdShrunk = true;
|
|
199
|
+
projectTokens = TOKENS_PROJECT_HEADER + estimateTokens(projectMd);
|
|
200
|
+
currentBaseTokens = getCurrentBaseTokens();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// ── Trim step 2: proportional plan truncation ─────────────────────────────
|
|
204
|
+
if (currentBaseTokens > contentBudget) {
|
|
205
|
+
// Compute tokens available for plan content only
|
|
206
|
+
const overhead = staticBaseTokens +
|
|
207
|
+
projectTokens +
|
|
208
|
+
contextTokens +
|
|
209
|
+
researchTokens +
|
|
210
|
+
requirementsTokens;
|
|
211
|
+
const planBudgetTokens = contentBudget - overhead;
|
|
212
|
+
const totalPlanTokens = planContentTokens;
|
|
213
|
+
if (planBudgetTokens > 0 && planBudgetTokens < totalPlanTokens) {
|
|
214
|
+
// Proportional share per plan (at least 1KB per plan)
|
|
215
|
+
const totalOriginalChars = plans.reduce((sum, p) => sum + p.content.length, 0);
|
|
216
|
+
const totalPlanCharsBudget = planBudgetTokens * 4;
|
|
217
|
+
workingPlans = workingPlans.map((p) => {
|
|
218
|
+
const proportionalShare = totalOriginalChars > 0
|
|
219
|
+
? Math.floor((p.content.length / totalOriginalChars) * totalPlanCharsBudget)
|
|
220
|
+
: 0;
|
|
221
|
+
const maxChars = Math.max(proportionalShare, MIN_PLAN_BYTES);
|
|
222
|
+
return { file: p.file, content: tailTruncate(p.content, maxChars) };
|
|
223
|
+
});
|
|
224
|
+
const newTotalChars = workingPlans.reduce((sum, p) => sum + p.content.length, 0);
|
|
225
|
+
if (totalOriginalChars > 0) {
|
|
226
|
+
planTruncationPct =
|
|
227
|
+
((totalOriginalChars - newTotalChars) / totalOriginalChars) * 100;
|
|
228
|
+
}
|
|
229
|
+
planContentTokens = workingPlans.reduce((sum, p) => sum + estimateTokens(p.content), 0);
|
|
230
|
+
currentBaseTokens = getCurrentBaseTokens();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// ── Trim step 3: drop context ─────────────────────────────────────────────
|
|
234
|
+
if (currentBaseTokens > contentBudget && context) {
|
|
235
|
+
context = null;
|
|
236
|
+
omitted.push('context');
|
|
237
|
+
contextTokens = 0;
|
|
238
|
+
currentBaseTokens = getCurrentBaseTokens();
|
|
239
|
+
}
|
|
240
|
+
// ── Trim step 4: drop research ────────────────────────────────────────────
|
|
241
|
+
if (currentBaseTokens > contentBudget && research) {
|
|
242
|
+
research = null;
|
|
243
|
+
omitted.push('research');
|
|
244
|
+
researchTokens = 0;
|
|
245
|
+
currentBaseTokens = getCurrentBaseTokens();
|
|
246
|
+
}
|
|
247
|
+
// ── Trim step 5: drop requirements (last resort) ──────────────────────────
|
|
248
|
+
if (currentBaseTokens > contentBudget && requirements) {
|
|
249
|
+
requirements = null;
|
|
250
|
+
omitted.push('requirements');
|
|
251
|
+
requirementsTokens = 0;
|
|
252
|
+
currentBaseTokens = getCurrentBaseTokens();
|
|
253
|
+
}
|
|
254
|
+
// ── Decide whether note is actually needed ────────────────────────────────
|
|
255
|
+
const anyTrimOccurred = omitted.length > 0 || projectMdShrunk || planTruncationPct > 0;
|
|
256
|
+
let note = null;
|
|
257
|
+
if (anyTrimOccurred) {
|
|
258
|
+
note = renderNote(noteTemplate, budget, omitted, planTruncationPct);
|
|
259
|
+
noteInjected = true;
|
|
260
|
+
}
|
|
261
|
+
// Suppress unused variable warning — currentBaseTokens is used via the
|
|
262
|
+
// closure in getCurrentBaseTokens(); the final value is not used directly.
|
|
263
|
+
void currentBaseTokens;
|
|
264
|
+
// ── Assemble ──────────────────────────────────────────────────────────────
|
|
265
|
+
const prompt = assemblePrompt({
|
|
266
|
+
instructions,
|
|
267
|
+
note,
|
|
268
|
+
roadmap,
|
|
269
|
+
projectMd,
|
|
270
|
+
plans: workingPlans,
|
|
271
|
+
context,
|
|
272
|
+
research,
|
|
273
|
+
requirements,
|
|
274
|
+
});
|
|
275
|
+
const estimatedTokens = estimateTokens(prompt);
|
|
276
|
+
if (estimatedTokens > effectiveBudget) {
|
|
277
|
+
hardFailed = true;
|
|
278
|
+
return {
|
|
279
|
+
prompt: '',
|
|
280
|
+
metadata: {
|
|
281
|
+
budget,
|
|
282
|
+
effectiveBudget,
|
|
283
|
+
estimatedTokens,
|
|
284
|
+
omitted,
|
|
285
|
+
projectMdShrunk,
|
|
286
|
+
planTruncationPct,
|
|
287
|
+
hardFailed,
|
|
288
|
+
noteInjected,
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
prompt,
|
|
294
|
+
metadata: {
|
|
295
|
+
budget,
|
|
296
|
+
effectiveBudget,
|
|
297
|
+
estimatedTokens,
|
|
298
|
+
omitted,
|
|
299
|
+
projectMdShrunk,
|
|
300
|
+
planTruncationPct,
|
|
301
|
+
hardFailed,
|
|
302
|
+
noteInjected,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Research Provider Module
|
|
4
|
+
*
|
|
5
|
+
* Encodes the Balanced-set provider decision: PROVIDER_WATERFALL constant,
|
|
6
|
+
* classifyConfidence, providerAvailability, and planResearch (with injectable
|
|
7
|
+
* store for testability).
|
|
8
|
+
*
|
|
9
|
+
* ADR-457 build-at-publish: authored as TypeScript .cts → emits .cjs via tsc.
|
|
10
|
+
*/
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Cycle 1 / Cycle 6: PROVIDER_WATERFALL (Balanced-set decision)
|
|
13
|
+
// firecrawl appears ONLY in scrape — demoted to known-URL scrape, NOT in docs/web
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const PROVIDER_WATERFALL = {
|
|
16
|
+
docs: ['context7', 'ref', 'jina', 'websearch'],
|
|
17
|
+
web: ['exa', 'tavily', 'perplexity', 'brave', 'websearch'],
|
|
18
|
+
scrape: ['firecrawl', 'jina'],
|
|
19
|
+
};
|
|
20
|
+
function authorityOf(provider) {
|
|
21
|
+
switch (provider) {
|
|
22
|
+
case 'context7':
|
|
23
|
+
case 'ref':
|
|
24
|
+
return 'official';
|
|
25
|
+
case 'jina':
|
|
26
|
+
case 'firecrawl':
|
|
27
|
+
return 'scrape';
|
|
28
|
+
case 'exa':
|
|
29
|
+
case 'tavily':
|
|
30
|
+
case 'perplexity':
|
|
31
|
+
case 'brave':
|
|
32
|
+
case 'websearch':
|
|
33
|
+
return 'web';
|
|
34
|
+
default:
|
|
35
|
+
return 'none';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function normalizeLegitimacyVerdict(raw) {
|
|
39
|
+
if (typeof raw !== 'string')
|
|
40
|
+
return null;
|
|
41
|
+
const upper = raw.toUpperCase();
|
|
42
|
+
if (upper === 'OK' || upper === 'SUS' || upper === 'SLOP')
|
|
43
|
+
return upper;
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function classifyConfidence(input) {
|
|
47
|
+
try {
|
|
48
|
+
const { provider, verifiedAgainstOfficial, legitimacyVerdict } = input;
|
|
49
|
+
const authority = authorityOf(provider);
|
|
50
|
+
const verdict = normalizeLegitimacyVerdict(legitimacyVerdict);
|
|
51
|
+
const groundTruth = verdict === 'OK';
|
|
52
|
+
// SLOP caps everything — checked first
|
|
53
|
+
if (verdict === 'SLOP')
|
|
54
|
+
return 'LOW';
|
|
55
|
+
// Ground-truth corroboration + known authority → HIGH
|
|
56
|
+
if (groundTruth && authority !== 'none')
|
|
57
|
+
return 'HIGH';
|
|
58
|
+
// Official or scrape provider (authority alone) → MEDIUM
|
|
59
|
+
if (authority === 'official' || authority === 'scrape')
|
|
60
|
+
return 'MEDIUM';
|
|
61
|
+
// Ground-truth but unknown provider → MEDIUM
|
|
62
|
+
if (groundTruth)
|
|
63
|
+
return 'MEDIUM';
|
|
64
|
+
// Web provider with self-reported verification → MEDIUM
|
|
65
|
+
if (authority === 'web' && verifiedAgainstOfficial === true)
|
|
66
|
+
return 'MEDIUM';
|
|
67
|
+
return 'LOW';
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return 'LOW';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Cycle 5: providerAvailability
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
function providerAvailability(config) {
|
|
77
|
+
const cfg = config ?? {};
|
|
78
|
+
return {
|
|
79
|
+
context7: true,
|
|
80
|
+
jina: cfg.jina !== undefined ? Boolean(cfg.jina) : true,
|
|
81
|
+
websearch: true,
|
|
82
|
+
exa: Boolean(cfg.exa_search),
|
|
83
|
+
tavily: Boolean(cfg.tavily_search),
|
|
84
|
+
brave: Boolean(cfg.brave_search),
|
|
85
|
+
firecrawl: Boolean(cfg.firecrawl),
|
|
86
|
+
ref: Boolean(cfg.ref_search),
|
|
87
|
+
perplexity: Boolean(cfg.perplexity),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Lazy-load default store (avoids circular require at module eval time)
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
let _defaultStore;
|
|
94
|
+
function getDefaultStore() {
|
|
95
|
+
if (!_defaultStore) {
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- lazy default store; tests inject their own
|
|
97
|
+
_defaultStore = require('./research-store.cjs');
|
|
98
|
+
}
|
|
99
|
+
return _defaultStore;
|
|
100
|
+
}
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// Cycle 1–3, 5, 7: planResearch
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
function planResearch(options) {
|
|
105
|
+
const { questions, ecosystem = '', cwd, config, clock = Date, homeDir, store = getDefaultStore(), } = options;
|
|
106
|
+
const availability = providerAvailability(config);
|
|
107
|
+
const items = questions.flatMap((q) => {
|
|
108
|
+
const { text, kind, library, version } = q;
|
|
109
|
+
// Skip questions without a non-empty string text — emitting an item with
|
|
110
|
+
// question:undefined / fetch.query:undefined would produce corrupt output.
|
|
111
|
+
if (typeof text !== 'string' || text.length === 0) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
const key = store.researchKey({ ecosystem, library, version, query: text, kind });
|
|
115
|
+
const res = store.getResearch(cwd, key, { clock, homeDir, kind });
|
|
116
|
+
// Fresh cache hit — no fetch needed
|
|
117
|
+
if (res.hit && !res.stale) {
|
|
118
|
+
return { question: text, key, cache: { hit: true, stale: false } };
|
|
119
|
+
}
|
|
120
|
+
// Determine which waterfall to use
|
|
121
|
+
const waterfall = PROVIDER_WATERFALL[kind] ?? PROVIDER_WATERFALL.web;
|
|
122
|
+
// Pick first available provider
|
|
123
|
+
const provider = waterfall.find((p) => availability[p] === true) ?? 'websearch';
|
|
124
|
+
const item = {
|
|
125
|
+
question: text,
|
|
126
|
+
key,
|
|
127
|
+
fetch: { provider, query: text },
|
|
128
|
+
};
|
|
129
|
+
// Stale hit: include cache info
|
|
130
|
+
if (res.hit) {
|
|
131
|
+
item.cache = { hit: true, stale: true };
|
|
132
|
+
}
|
|
133
|
+
return item;
|
|
134
|
+
});
|
|
135
|
+
return { items };
|
|
136
|
+
}
|
|
137
|
+
module.exports = { PROVIDER_WATERFALL, classifyConfidence, providerAvailability, planResearch };
|