@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.
Files changed (618) hide show
  1. package/.claude-plugin/plugin.json +23 -0
  2. package/GEMINI.md +53 -0
  3. package/LICENSE +22 -0
  4. package/README.md +100 -0
  5. package/agents/pp-advisor-researcher.md +108 -0
  6. package/agents/pp-ai-researcher.md +114 -0
  7. package/agents/pp-assumptions-analyzer.md +105 -0
  8. package/agents/pp-code-fixer.md +669 -0
  9. package/agents/pp-code-reviewer.md +387 -0
  10. package/agents/pp-codebase-mapper.md +853 -0
  11. package/agents/pp-debug-session-manager.md +315 -0
  12. package/agents/pp-debugger.md +1453 -0
  13. package/agents/pp-doc-classifier.md +168 -0
  14. package/agents/pp-doc-synthesizer.md +204 -0
  15. package/agents/pp-doc-verifier.md +217 -0
  16. package/agents/pp-doc-writer.md +616 -0
  17. package/agents/pp-domain-researcher.md +147 -0
  18. package/agents/pp-eval-auditor.md +191 -0
  19. package/agents/pp-eval-planner.md +154 -0
  20. package/agents/pp-executor.md +808 -0
  21. package/agents/pp-framework-selector.md +160 -0
  22. package/agents/pp-integration-checker.md +470 -0
  23. package/agents/pp-intel-updater.md +339 -0
  24. package/agents/pp-mempalace-curator.md +47 -0
  25. package/agents/pp-nyquist-auditor.md +204 -0
  26. package/agents/pp-pattern-mapper.md +335 -0
  27. package/agents/pp-phase-researcher.md +867 -0
  28. package/agents/pp-plan-checker.md +988 -0
  29. package/agents/pp-planner.md +1052 -0
  30. package/agents/pp-project-researcher.md +612 -0
  31. package/agents/pp-research-synthesizer.md +260 -0
  32. package/agents/pp-roadmapper.md +741 -0
  33. package/agents/pp-security-auditor.md +156 -0
  34. package/agents/pp-ui-auditor.md +495 -0
  35. package/agents/pp-ui-checker.md +309 -0
  36. package/agents/pp-ui-researcher.md +375 -0
  37. package/agents/pp-user-profiler.md +171 -0
  38. package/agents/pp-verifier.md +967 -0
  39. package/assets/gsd-logo-2000-transparent.png +0 -0
  40. package/assets/gsd-logo-2000-transparent.svg +17 -0
  41. package/assets/gsd-logo-2000.png +0 -0
  42. package/assets/gsd-logo-2000.svg +21 -0
  43. package/assets/terminal.svg +68 -0
  44. package/bin/install.js +12370 -0
  45. package/bin/lib/ui-safety-gate.cjs +107 -0
  46. package/commands/pp-add-tests.md +42 -0
  47. package/commands/pp-ai-integration-phase.md +37 -0
  48. package/commands/pp-audit-fix.md +34 -0
  49. package/commands/pp-audit-milestone.md +37 -0
  50. package/commands/pp-audit-uat.md +24 -0
  51. package/commands/pp-autonomous.md +51 -0
  52. package/commands/pp-capture.md +62 -0
  53. package/commands/pp-cleanup.md +24 -0
  54. package/commands/pp-code-review.md +59 -0
  55. package/commands/pp-complete-milestone.md +143 -0
  56. package/commands/pp-config.md +56 -0
  57. package/commands/pp-debug.md +52 -0
  58. package/commands/pp-discovery.md +34 -0
  59. package/commands/pp-discuss-phase.md +77 -0
  60. package/commands/pp-docs-update.md +49 -0
  61. package/commands/pp-eval-review.md +33 -0
  62. package/commands/pp-execute-phase.md +65 -0
  63. package/commands/pp-explore.md +27 -0
  64. package/commands/pp-extract-learnings.md +23 -0
  65. package/commands/pp-fast.md +31 -0
  66. package/commands/pp-forensics.md +57 -0
  67. package/commands/pp-graphify.md +204 -0
  68. package/commands/pp-health.md +31 -0
  69. package/commands/pp-help.md +28 -0
  70. package/commands/pp-import.md +45 -0
  71. package/commands/pp-inbox.md +39 -0
  72. package/commands/pp-ingest-docs.md +42 -0
  73. package/commands/pp-manager.md +45 -0
  74. package/commands/pp-map-codebase.md +83 -0
  75. package/commands/pp-mempalace-capture.md +71 -0
  76. package/commands/pp-mempalace-recall.md +102 -0
  77. package/commands/pp-milestone-summary.md +51 -0
  78. package/commands/pp-mvp-phase.md +45 -0
  79. package/commands/pp-new-milestone.md +45 -0
  80. package/commands/pp-new-project.md +47 -0
  81. package/commands/pp-ns-context.md +25 -0
  82. package/commands/pp-ns-ideate.md +24 -0
  83. package/commands/pp-ns-manage.md +36 -0
  84. package/commands/pp-ns-project.md +27 -0
  85. package/commands/pp-ns-review.md +29 -0
  86. package/commands/pp-ns-workflow.md +35 -0
  87. package/commands/pp-pause-work.md +43 -0
  88. package/commands/pp-phase.md +56 -0
  89. package/commands/pp-plan-phase.md +63 -0
  90. package/commands/pp-plan-review-convergence.md +60 -0
  91. package/commands/pp-pr-branch.md +26 -0
  92. package/commands/pp-profile-user.md +46 -0
  93. package/commands/pp-progress.md +49 -0
  94. package/commands/pp-quick.md +174 -0
  95. package/commands/pp-resume-work.md +30 -0
  96. package/commands/pp-review-backlog.md +63 -0
  97. package/commands/pp-review.md +42 -0
  98. package/commands/pp-secure-phase.md +36 -0
  99. package/commands/pp-settings.md +29 -0
  100. package/commands/pp-ship.md +24 -0
  101. package/commands/pp-sketch.md +60 -0
  102. package/commands/pp-spec-phase.md +63 -0
  103. package/commands/pp-spike.md +57 -0
  104. package/commands/pp-stats.md +20 -0
  105. package/commands/pp-surface.md +162 -0
  106. package/commands/pp-thread.md +24 -0
  107. package/commands/pp-ui-phase.md +35 -0
  108. package/commands/pp-ui-review.md +33 -0
  109. package/commands/pp-ultraplan-phase.md +34 -0
  110. package/commands/pp-undo.md +35 -0
  111. package/commands/pp-update.md +49 -0
  112. package/commands/pp-validate-phase.md +36 -0
  113. package/commands/pp-verify-work.md +39 -0
  114. package/commands/pp-workspace.md +52 -0
  115. package/commands/pp-workstreams.md +70 -0
  116. package/gemini-extension.json +6 -0
  117. package/hooks/dist/lib/git-cmd.js +150 -0
  118. package/hooks/dist/lib/pp-graphify-rebuild.sh +65 -0
  119. package/hooks/dist/managed-hooks-registry.cjs +39 -0
  120. package/hooks/dist/pp-check-update-worker.js +108 -0
  121. package/hooks/dist/pp-check-update.js +66 -0
  122. package/hooks/dist/pp-config-reload.js +133 -0
  123. package/hooks/dist/pp-context-monitor.js +196 -0
  124. package/hooks/dist/pp-cursor-post-tool.js +75 -0
  125. package/hooks/dist/pp-cursor-session-start.js +52 -0
  126. package/hooks/dist/pp-ensure-canonical-path.js +305 -0
  127. package/hooks/dist/pp-graphify-update.sh +158 -0
  128. package/hooks/dist/pp-phase-boundary.sh +47 -0
  129. package/hooks/dist/pp-prompt-guard.js +97 -0
  130. package/hooks/dist/pp-read-guard.js +101 -0
  131. package/hooks/dist/pp-read-injection-scanner.js +203 -0
  132. package/hooks/dist/pp-session-state.sh +59 -0
  133. package/hooks/dist/pp-statusline.js +566 -0
  134. package/hooks/dist/pp-update-banner.js +138 -0
  135. package/hooks/dist/pp-validate-commit.sh +57 -0
  136. package/hooks/dist/pp-workflow-guard.js +167 -0
  137. package/hooks/dist/pp-worktree-path-guard.js +185 -0
  138. package/hooks/hooks.json +70 -0
  139. package/hooks/lib/git-cmd.js +150 -0
  140. package/hooks/lib/pp-graphify-rebuild.sh +65 -0
  141. package/hooks/managed-hooks-registry.cjs +39 -0
  142. package/hooks/pp-check-update-worker.js +108 -0
  143. package/hooks/pp-check-update.js +66 -0
  144. package/hooks/pp-config-reload.js +133 -0
  145. package/hooks/pp-context-monitor.js +196 -0
  146. package/hooks/pp-cursor-post-tool.js +75 -0
  147. package/hooks/pp-cursor-session-start.js +52 -0
  148. package/hooks/pp-ensure-canonical-path.js +305 -0
  149. package/hooks/pp-graphify-update.sh +158 -0
  150. package/hooks/pp-phase-boundary.sh +47 -0
  151. package/hooks/pp-prompt-guard.js +97 -0
  152. package/hooks/pp-read-guard.js +101 -0
  153. package/hooks/pp-read-injection-scanner.js +203 -0
  154. package/hooks/pp-session-state.sh +59 -0
  155. package/hooks/pp-statusline.js +566 -0
  156. package/hooks/pp-update-banner.js +138 -0
  157. package/hooks/pp-validate-commit.sh +57 -0
  158. package/hooks/pp-workflow-guard.js +167 -0
  159. package/hooks/pp-worktree-path-guard.js +185 -0
  160. package/package.json +125 -0
  161. package/pp-core/bin/check-latest-version.cjs +161 -0
  162. package/pp-core/bin/lib/active-workstream-store.cjs +297 -0
  163. package/pp-core/bin/lib/adr-parser.cjs +399 -0
  164. package/pp-core/bin/lib/agent-command-router.cjs +68 -0
  165. package/pp-core/bin/lib/agent-install-check.cjs +143 -0
  166. package/pp-core/bin/lib/artifacts.cjs +51 -0
  167. package/pp-core/bin/lib/audit-command-router.cjs +61 -0
  168. package/pp-core/bin/lib/audit.cjs +743 -0
  169. package/pp-core/bin/lib/capability-activation.cjs +113 -0
  170. package/pp-core/bin/lib/capability-registry.cjs +3727 -0
  171. package/pp-core/bin/lib/capability-state.cjs +497 -0
  172. package/pp-core/bin/lib/capability-writer.cjs +355 -0
  173. package/pp-core/bin/lib/check-command-router.cjs +800 -0
  174. package/pp-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  175. package/pp-core/bin/lib/cli-exit.cjs +61 -0
  176. package/pp-core/bin/lib/clock.cjs +95 -0
  177. package/pp-core/bin/lib/clusters.cjs +131 -0
  178. package/pp-core/bin/lib/code-review-flags.cjs +59 -0
  179. package/pp-core/bin/lib/command-aliases.cjs +809 -0
  180. package/pp-core/bin/lib/command-arg-projection.cjs +55 -0
  181. package/pp-core/bin/lib/command-roster.cjs +19 -0
  182. package/pp-core/bin/lib/command-routing-hub.cjs +300 -0
  183. package/pp-core/bin/lib/commands.cjs +1244 -0
  184. package/pp-core/bin/lib/config-loader.cjs +714 -0
  185. package/pp-core/bin/lib/config-schema.cjs +58 -0
  186. package/pp-core/bin/lib/config-types.cjs +20 -0
  187. package/pp-core/bin/lib/config.cjs +796 -0
  188. package/pp-core/bin/lib/configuration.cjs +209 -0
  189. package/pp-core/bin/lib/context-utilization.cjs +48 -0
  190. package/pp-core/bin/lib/core-utils.cjs +198 -0
  191. package/pp-core/bin/lib/decisions.cjs +136 -0
  192. package/pp-core/bin/lib/docs.cjs +264 -0
  193. package/pp-core/bin/lib/drift.cjs +364 -0
  194. package/pp-core/bin/lib/edge-probe.cjs +196 -0
  195. package/pp-core/bin/lib/fallow-runner.cjs +153 -0
  196. package/pp-core/bin/lib/federated-config.cjs +182 -0
  197. package/pp-core/bin/lib/frontmatter.cjs +494 -0
  198. package/pp-core/bin/lib/gap-checker.cjs +260 -0
  199. package/pp-core/bin/lib/git-base-branch.cjs +220 -0
  200. package/pp-core/bin/lib/graphify-command-router.cjs +72 -0
  201. package/pp-core/bin/lib/graphify.cjs +472 -0
  202. package/pp-core/bin/lib/gsd2-import.cjs +456 -0
  203. package/pp-core/bin/lib/init-command-router.cjs +62 -0
  204. package/pp-core/bin/lib/init.cjs +1912 -0
  205. package/pp-core/bin/lib/install-profiles.cjs +814 -0
  206. package/pp-core/bin/lib/installer-migration-authoring.cjs +122 -0
  207. package/pp-core/bin/lib/installer-migration-report.cjs +351 -0
  208. package/pp-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +225 -0
  209. package/pp-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  210. package/pp-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  211. package/pp-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  212. package/pp-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs +123 -0
  213. package/pp-core/bin/lib/installer-migrations/005-rename-gsd-core-to-pp-core.cjs +109 -0
  214. package/pp-core/bin/lib/installer-migrations/006-rename-gsd-command-namespace.cjs +135 -0
  215. package/pp-core/bin/lib/installer-migrations.cjs +823 -0
  216. package/pp-core/bin/lib/intel-command-router.cjs +119 -0
  217. package/pp-core/bin/lib/intel.cjs +584 -0
  218. package/pp-core/bin/lib/io.cjs +220 -0
  219. package/pp-core/bin/lib/learnings.cjs +270 -0
  220. package/pp-core/bin/lib/legacy-cleanup.cjs +253 -0
  221. package/pp-core/bin/lib/loop-host-contract.cjs +105 -0
  222. package/pp-core/bin/lib/loop-resolver.cjs +479 -0
  223. package/pp-core/bin/lib/milestone.cjs +381 -0
  224. package/pp-core/bin/lib/model-catalog.cjs +154 -0
  225. package/pp-core/bin/lib/model-profiles.cjs +24 -0
  226. package/pp-core/bin/lib/model-resolver.cjs +467 -0
  227. package/pp-core/bin/lib/observability/event.cjs +51 -0
  228. package/pp-core/bin/lib/observability/logger.cjs +146 -0
  229. package/pp-core/bin/lib/observability/redaction.cjs +48 -0
  230. package/pp-core/bin/lib/package-identity.cjs +35 -0
  231. package/pp-core/bin/lib/package-legitimacy.cjs +368 -0
  232. package/pp-core/bin/lib/phase-command-router.cjs +209 -0
  233. package/pp-core/bin/lib/phase-id.cjs +213 -0
  234. package/pp-core/bin/lib/phase-lifecycle.cjs +74 -0
  235. package/pp-core/bin/lib/phase-locator.cjs +145 -0
  236. package/pp-core/bin/lib/phase.cjs +1446 -0
  237. package/pp-core/bin/lib/phases-command-router.cjs +43 -0
  238. package/pp-core/bin/lib/plan-drift-guard.cjs +117 -0
  239. package/pp-core/bin/lib/plan-scan.cjs +91 -0
  240. package/pp-core/bin/lib/planning-workspace.cjs +245 -0
  241. package/pp-core/bin/lib/probe-core.cjs +402 -0
  242. package/pp-core/bin/lib/profile-output.cjs +1164 -0
  243. package/pp-core/bin/lib/profile-pipeline-command-router.cjs +138 -0
  244. package/pp-core/bin/lib/profile-pipeline.cjs +519 -0
  245. package/pp-core/bin/lib/prohibition-enforcement.cjs +660 -0
  246. package/pp-core/bin/lib/project-root.cjs +119 -0
  247. package/pp-core/bin/lib/prompt-budget.cjs +305 -0
  248. package/pp-core/bin/lib/research-provider.cjs +137 -0
  249. package/pp-core/bin/lib/research-store.cjs +167 -0
  250. package/pp-core/bin/lib/review-reviewer-selection.cjs +121 -0
  251. package/pp-core/bin/lib/roadmap-command-router.cjs +166 -0
  252. package/pp-core/bin/lib/roadmap-parser.cjs +456 -0
  253. package/pp-core/bin/lib/roadmap-upgrade.cjs +476 -0
  254. package/pp-core/bin/lib/roadmap.cjs +738 -0
  255. package/pp-core/bin/lib/runtime-artifact-conversion.cjs +1966 -0
  256. package/pp-core/bin/lib/runtime-artifact-layout.cjs +342 -0
  257. package/pp-core/bin/lib/runtime-config-adapter-registry.cjs +103 -0
  258. package/pp-core/bin/lib/runtime-homes.cjs +272 -0
  259. package/pp-core/bin/lib/runtime-hooks-surface.cjs +1460 -0
  260. package/pp-core/bin/lib/runtime-name-policy.cjs +97 -0
  261. package/pp-core/bin/lib/runtime-slash.cjs +137 -0
  262. package/pp-core/bin/lib/schema-detect.cjs +159 -0
  263. package/pp-core/bin/lib/secrets.cjs +34 -0
  264. package/pp-core/bin/lib/security.cjs +480 -0
  265. package/pp-core/bin/lib/semver-compare.cjs +42 -0
  266. package/pp-core/bin/lib/shell-command-projection.cjs +550 -0
  267. package/pp-core/bin/lib/state-command-router.cjs +172 -0
  268. package/pp-core/bin/lib/state-document.cjs +312 -0
  269. package/pp-core/bin/lib/state.cjs +2587 -0
  270. package/pp-core/bin/lib/surface.cjs +505 -0
  271. package/pp-core/bin/lib/task-command-router.cjs +85 -0
  272. package/pp-core/bin/lib/teams-status.cjs +74 -0
  273. package/pp-core/bin/lib/template.cjs +246 -0
  274. package/pp-core/bin/lib/uat-predicate.cjs +329 -0
  275. package/pp-core/bin/lib/uat.cjs +359 -0
  276. package/pp-core/bin/lib/ui-safety-gate.cjs +98 -0
  277. package/pp-core/bin/lib/update-context.cjs +221 -0
  278. package/pp-core/bin/lib/validate-command-router.cjs +91 -0
  279. package/pp-core/bin/lib/validate.cjs +122 -0
  280. package/pp-core/bin/lib/verification-command-router.cjs +31 -0
  281. package/pp-core/bin/lib/verification.cjs +196 -0
  282. package/pp-core/bin/lib/verify-command-router.cjs +44 -0
  283. package/pp-core/bin/lib/verify.cjs +1932 -0
  284. package/pp-core/bin/lib/workstream-inventory-builder.cjs +81 -0
  285. package/pp-core/bin/lib/workstream-inventory.cjs +147 -0
  286. package/pp-core/bin/lib/workstream-name-policy.cjs +91 -0
  287. package/pp-core/bin/lib/workstream.cjs +386 -0
  288. package/pp-core/bin/lib/worktree-base-ref.cjs +350 -0
  289. package/pp-core/bin/lib/worktree-safety.cjs +985 -0
  290. package/pp-core/bin/pp-tools.cjs +2239 -0
  291. package/pp-core/bin/pp_run +20 -0
  292. package/pp-core/bin/shared/config-defaults.manifest.json +97 -0
  293. package/pp-core/bin/shared/config-schema.manifest.json +176 -0
  294. package/pp-core/bin/shared/model-catalog.json +160 -0
  295. package/pp-core/bin/shared/runtime-aliases.manifest.json +79 -0
  296. package/pp-core/bin/verify-reapply-patches.cjs +400 -0
  297. package/pp-core/contexts/dev.md +21 -0
  298. package/pp-core/contexts/research.md +22 -0
  299. package/pp-core/contexts/review.md +23 -0
  300. package/pp-core/references/agent-contracts.md +79 -0
  301. package/pp-core/references/ai-evals.md +156 -0
  302. package/pp-core/references/ai-frameworks.md +186 -0
  303. package/pp-core/references/artifact-types.md +131 -0
  304. package/pp-core/references/autonomous-smart-discuss.md +277 -0
  305. package/pp-core/references/checkpoints.md +814 -0
  306. package/pp-core/references/common-bug-patterns.md +114 -0
  307. package/pp-core/references/context-budget.md +85 -0
  308. package/pp-core/references/continuation-format.md +253 -0
  309. package/pp-core/references/debugger-philosophy.md +76 -0
  310. package/pp-core/references/decimal-phase-calculation.md +64 -0
  311. package/pp-core/references/doc-conflict-engine.md +91 -0
  312. package/pp-core/references/domain-probes.md +125 -0
  313. package/pp-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +7 -0
  314. package/pp-core/references/edge-probe-fixtures/01-round-half-even/requirements.json +1 -0
  315. package/pp-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +8 -0
  316. package/pp-core/references/edge-probe-fixtures/02-merge-intervals/requirements.json +1 -0
  317. package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +7 -0
  318. package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/requirements.json +1 -0
  319. package/pp-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +7 -0
  320. package/pp-core/references/edge-probe-fixtures/04-money-rounding/requirements.json +1 -0
  321. package/pp-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +8 -0
  322. package/pp-core/references/edge-probe-fixtures/05-list-dedupe/requirements.json +1 -0
  323. package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +8 -0
  324. package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/requirements.json +1 -0
  325. package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/resolutions.json +4 -0
  326. package/pp-core/references/edge-probe.md +272 -0
  327. package/pp-core/references/execute-mvp-tdd.md +81 -0
  328. package/pp-core/references/executor-examples.md +110 -0
  329. package/pp-core/references/few-shot-examples/plan-checker.md +73 -0
  330. package/pp-core/references/few-shot-examples/verifier.md +109 -0
  331. package/pp-core/references/gate-prompts.md +100 -0
  332. package/pp-core/references/gates.md +70 -0
  333. package/pp-core/references/git-integration.md +298 -0
  334. package/pp-core/references/git-planning-commit.md +40 -0
  335. package/pp-core/references/ios-scaffold.md +123 -0
  336. package/pp-core/references/loop-hook-dispatch.md +61 -0
  337. package/pp-core/references/mandatory-initial-read.md +2 -0
  338. package/pp-core/references/model-profile-resolution.md +38 -0
  339. package/pp-core/references/model-profiles.md +245 -0
  340. package/pp-core/references/mvp-concepts.md +49 -0
  341. package/pp-core/references/phase-argument-parsing.md +61 -0
  342. package/pp-core/references/planner-antipatterns.md +176 -0
  343. package/pp-core/references/planner-chunked.md +49 -0
  344. package/pp-core/references/planner-gap-closure.md +62 -0
  345. package/pp-core/references/planner-graphify-auto-update.md +67 -0
  346. package/pp-core/references/planner-guidance.md +186 -0
  347. package/pp-core/references/planner-human-verify-mode.md +57 -0
  348. package/pp-core/references/planner-interface-context.md +62 -0
  349. package/pp-core/references/planner-load-graph-context.md +36 -0
  350. package/pp-core/references/planner-mvp-mode.md +53 -0
  351. package/pp-core/references/planner-reviews.md +42 -0
  352. package/pp-core/references/planner-revision.md +87 -0
  353. package/pp-core/references/planner-source-audit.md +73 -0
  354. package/pp-core/references/planning-config.md +477 -0
  355. package/pp-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json +14 -0
  356. package/pp-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json +4 -0
  357. package/pp-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json +32 -0
  358. package/pp-core/references/prohibition-probe.md +326 -0
  359. package/pp-core/references/project-skills-discovery.md +19 -0
  360. package/pp-core/references/questioning.md +162 -0
  361. package/pp-core/references/research-documentation-lookup.md +29 -0
  362. package/pp-core/references/research-philosophy.md +29 -0
  363. package/pp-core/references/research-verification-protocol.md +27 -0
  364. package/pp-core/references/revision-loop.md +97 -0
  365. package/pp-core/references/scout-codebase.md +51 -0
  366. package/pp-core/references/skeleton-template.md +48 -0
  367. package/pp-core/references/sketch-interactivity.md +41 -0
  368. package/pp-core/references/sketch-theme-system.md +94 -0
  369. package/pp-core/references/sketch-tooling.md +45 -0
  370. package/pp-core/references/sketch-variant-patterns.md +81 -0
  371. package/pp-core/references/spidr-splitting.md +69 -0
  372. package/pp-core/references/tdd.md +330 -0
  373. package/pp-core/references/thinking-models-debug.md +44 -0
  374. package/pp-core/references/thinking-models-execution.md +50 -0
  375. package/pp-core/references/thinking-models-planning.md +62 -0
  376. package/pp-core/references/thinking-models-research.md +50 -0
  377. package/pp-core/references/thinking-models-verification.md +55 -0
  378. package/pp-core/references/thinking-partner.md +96 -0
  379. package/pp-core/references/ui-brand.md +162 -0
  380. package/pp-core/references/universal-anti-patterns.md +63 -0
  381. package/pp-core/references/user-profiling.md +681 -0
  382. package/pp-core/references/user-story-template.md +58 -0
  383. package/pp-core/references/verification-overrides.md +227 -0
  384. package/pp-core/references/verification-patterns.md +612 -0
  385. package/pp-core/references/verify-mvp-mode.md +85 -0
  386. package/pp-core/references/workstream-flag.md +111 -0
  387. package/pp-core/references/worktree-branch-check.md +44 -0
  388. package/pp-core/references/worktree-path-safety.md +67 -0
  389. package/pp-core/templates/AI-SPEC.md +246 -0
  390. package/pp-core/templates/DEBUG.md +169 -0
  391. package/pp-core/templates/README.md +77 -0
  392. package/pp-core/templates/SECURITY.md +61 -0
  393. package/pp-core/templates/UAT.md +265 -0
  394. package/pp-core/templates/UI-SPEC.md +100 -0
  395. package/pp-core/templates/VALIDATION.md +76 -0
  396. package/pp-core/templates/claude-md.md +145 -0
  397. package/pp-core/templates/codebase/architecture.md +255 -0
  398. package/pp-core/templates/codebase/concerns.md +310 -0
  399. package/pp-core/templates/codebase/conventions.md +307 -0
  400. package/pp-core/templates/codebase/integrations.md +280 -0
  401. package/pp-core/templates/codebase/stack.md +186 -0
  402. package/pp-core/templates/codebase/structure.md +285 -0
  403. package/pp-core/templates/codebase/testing.md +480 -0
  404. package/pp-core/templates/config.json +62 -0
  405. package/pp-core/templates/context.md +352 -0
  406. package/pp-core/templates/continue-here.md +78 -0
  407. package/pp-core/templates/copilot-instructions.md +7 -0
  408. package/pp-core/templates/debug-subagent-prompt.md +91 -0
  409. package/pp-core/templates/dev-preferences.md +21 -0
  410. package/pp-core/templates/discovery.md +146 -0
  411. package/pp-core/templates/discussion-log.md +63 -0
  412. package/pp-core/templates/milestone-archive.md +123 -0
  413. package/pp-core/templates/milestone.md +115 -0
  414. package/pp-core/templates/phase-prompt.md +610 -0
  415. package/pp-core/templates/planner-subagent-prompt.md +117 -0
  416. package/pp-core/templates/project.md +203 -0
  417. package/pp-core/templates/requirements.md +231 -0
  418. package/pp-core/templates/research-project/ARCHITECTURE.md +204 -0
  419. package/pp-core/templates/research-project/FEATURES.md +147 -0
  420. package/pp-core/templates/research-project/PITFALLS.md +200 -0
  421. package/pp-core/templates/research-project/STACK.md +120 -0
  422. package/pp-core/templates/research-project/SUMMARY.md +170 -0
  423. package/pp-core/templates/research.md +592 -0
  424. package/pp-core/templates/retrospective.md +54 -0
  425. package/pp-core/templates/roadmap.md +202 -0
  426. package/pp-core/templates/spec.md +333 -0
  427. package/pp-core/templates/state.md +195 -0
  428. package/pp-core/templates/summary-complex.md +60 -0
  429. package/pp-core/templates/summary-minimal.md +42 -0
  430. package/pp-core/templates/summary-standard.md +49 -0
  431. package/pp-core/templates/summary.md +249 -0
  432. package/pp-core/templates/user-profile.md +146 -0
  433. package/pp-core/templates/user-setup.md +311 -0
  434. package/pp-core/templates/verification-report.md +335 -0
  435. package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -0
  436. package/pp-core/workflows/add-backlog.md +91 -0
  437. package/pp-core/workflows/add-phase.md +113 -0
  438. package/pp-core/workflows/add-tests.md +355 -0
  439. package/pp-core/workflows/add-todo.md +161 -0
  440. package/pp-core/workflows/ai-integration-phase.md +295 -0
  441. package/pp-core/workflows/analyze-dependencies.md +96 -0
  442. package/pp-core/workflows/audit-fix.md +178 -0
  443. package/pp-core/workflows/audit-milestone.md +362 -0
  444. package/pp-core/workflows/audit-uat.md +110 -0
  445. package/pp-core/workflows/autonomous.md +886 -0
  446. package/pp-core/workflows/check-todos.md +180 -0
  447. package/pp-core/workflows/cleanup.md +195 -0
  448. package/pp-core/workflows/code-review-fix.md +506 -0
  449. package/pp-core/workflows/code-review.md +696 -0
  450. package/pp-core/workflows/complete-milestone.md +857 -0
  451. package/pp-core/workflows/debug.md +237 -0
  452. package/pp-core/workflows/diagnose-issues.md +245 -0
  453. package/pp-core/workflows/discovery-phase.md +291 -0
  454. package/pp-core/workflows/discovery-sprint.md +1546 -0
  455. package/pp-core/workflows/discuss-phase/modes/advisor.md +176 -0
  456. package/pp-core/workflows/discuss-phase/modes/all.md +28 -0
  457. package/pp-core/workflows/discuss-phase/modes/analyze.md +44 -0
  458. package/pp-core/workflows/discuss-phase/modes/auto.md +57 -0
  459. package/pp-core/workflows/discuss-phase/modes/batch.md +52 -0
  460. package/pp-core/workflows/discuss-phase/modes/chain.md +98 -0
  461. package/pp-core/workflows/discuss-phase/modes/default.md +141 -0
  462. package/pp-core/workflows/discuss-phase/modes/power.md +44 -0
  463. package/pp-core/workflows/discuss-phase/modes/text.md +55 -0
  464. package/pp-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
  465. package/pp-core/workflows/discuss-phase/templates/context.md +136 -0
  466. package/pp-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
  467. package/pp-core/workflows/discuss-phase-assumptions.md +675 -0
  468. package/pp-core/workflows/discuss-phase-power.md +291 -0
  469. package/pp-core/workflows/discuss-phase.md +520 -0
  470. package/pp-core/workflows/do.md +111 -0
  471. package/pp-core/workflows/docs-update.md +1168 -0
  472. package/pp-core/workflows/edit-phase.md +295 -0
  473. package/pp-core/workflows/eval-review.md +159 -0
  474. package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
  475. package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  476. package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
  477. package/pp-core/workflows/execute-phase/steps/worktree-recovery-policy.md +9 -0
  478. package/pp-core/workflows/execute-phase.md +1707 -0
  479. package/pp-core/workflows/execute-plan.md +541 -0
  480. package/pp-core/workflows/explore.md +146 -0
  481. package/pp-core/workflows/extract-learnings.md +243 -0
  482. package/pp-core/workflows/fast.md +124 -0
  483. package/pp-core/workflows/forensics.md +279 -0
  484. package/pp-core/workflows/graduation.md +196 -0
  485. package/pp-core/workflows/health.md +224 -0
  486. package/pp-core/workflows/help/modes/brief.md +22 -0
  487. package/pp-core/workflows/help/modes/default.md +50 -0
  488. package/pp-core/workflows/help/modes/full.md +791 -0
  489. package/pp-core/workflows/help/modes/topic.md +74 -0
  490. package/pp-core/workflows/help.md +24 -0
  491. package/pp-core/workflows/import.md +256 -0
  492. package/pp-core/workflows/inbox.md +387 -0
  493. package/pp-core/workflows/ingest-docs.md +340 -0
  494. package/pp-core/workflows/insert-phase.md +152 -0
  495. package/pp-core/workflows/list-phase-assumptions.md +178 -0
  496. package/pp-core/workflows/list-workspaces.md +57 -0
  497. package/pp-core/workflows/manager.md +435 -0
  498. package/pp-core/workflows/map-codebase.md +444 -0
  499. package/pp-core/workflows/milestone-summary.md +224 -0
  500. package/pp-core/workflows/mvp-phase.md +222 -0
  501. package/pp-core/workflows/new-milestone.md +643 -0
  502. package/pp-core/workflows/new-project.md +1563 -0
  503. package/pp-core/workflows/new-workspace.md +240 -0
  504. package/pp-core/workflows/next.md +347 -0
  505. package/pp-core/workflows/node-repair.md +92 -0
  506. package/pp-core/workflows/note.md +158 -0
  507. package/pp-core/workflows/pause-work.md +250 -0
  508. package/pp-core/workflows/plan-milestone-gaps.md +281 -0
  509. package/pp-core/workflows/plan-phase.md +1755 -0
  510. package/pp-core/workflows/plan-review-convergence.md +369 -0
  511. package/pp-core/workflows/plant-seed.md +230 -0
  512. package/pp-core/workflows/pr-branch.md +159 -0
  513. package/pp-core/workflows/profile-user.md +455 -0
  514. package/pp-core/workflows/progress.md +756 -0
  515. package/pp-core/workflows/quick.md +1045 -0
  516. package/pp-core/workflows/reapply-patches.md +443 -0
  517. package/pp-core/workflows/remove-phase.md +156 -0
  518. package/pp-core/workflows/remove-workspace.md +108 -0
  519. package/pp-core/workflows/resume-project.md +348 -0
  520. package/pp-core/workflows/review.md +765 -0
  521. package/pp-core/workflows/scan.md +107 -0
  522. package/pp-core/workflows/secure-phase.md +184 -0
  523. package/pp-core/workflows/session-report.md +146 -0
  524. package/pp-core/workflows/settings-advanced.md +816 -0
  525. package/pp-core/workflows/settings-integrations.md +312 -0
  526. package/pp-core/workflows/settings.md +592 -0
  527. package/pp-core/workflows/ship.md +465 -0
  528. package/pp-core/workflows/sketch-wrap-up.md +286 -0
  529. package/pp-core/workflows/sketch.md +361 -0
  530. package/pp-core/workflows/spec-phase.md +495 -0
  531. package/pp-core/workflows/spike-wrap-up.md +307 -0
  532. package/pp-core/workflows/spike.md +453 -0
  533. package/pp-core/workflows/stats.md +80 -0
  534. package/pp-core/workflows/sync-skills.md +182 -0
  535. package/pp-core/workflows/thread.md +222 -0
  536. package/pp-core/workflows/transition.md +694 -0
  537. package/pp-core/workflows/ui-phase.md +328 -0
  538. package/pp-core/workflows/ui-review.md +193 -0
  539. package/pp-core/workflows/ultraplan-phase.md +199 -0
  540. package/pp-core/workflows/undo.md +314 -0
  541. package/pp-core/workflows/update.md +501 -0
  542. package/pp-core/workflows/validate-phase.md +183 -0
  543. package/pp-core/workflows/verify-phase.md +569 -0
  544. package/pp-core/workflows/verify-work.md +804 -0
  545. package/scripts/affected-tests-lib.cjs +554 -0
  546. package/scripts/audit-workflow-script-paths.cjs +73 -0
  547. package/scripts/base64-scan.sh +351 -0
  548. package/scripts/build-hooks.js +254 -0
  549. package/scripts/changeset/README.md +129 -0
  550. package/scripts/changeset/cli.cjs +597 -0
  551. package/scripts/changeset/github-release-notes.cjs +199 -0
  552. package/scripts/changeset/lint.cjs +147 -0
  553. package/scripts/changeset/new.cjs +151 -0
  554. package/scripts/changeset/parse.cjs +114 -0
  555. package/scripts/changeset/render.cjs +34 -0
  556. package/scripts/changeset/serialize.cjs +130 -0
  557. package/scripts/check-alias-drift.cjs +114 -0
  558. package/scripts/check-env.cjs +312 -0
  559. package/scripts/check-npm-integrity.cjs +215 -0
  560. package/scripts/ci-guard-runner.cjs +22 -0
  561. package/scripts/ci-prepare-test-scope.cjs +93 -0
  562. package/scripts/ci-rebase-check.cjs +86 -0
  563. package/scripts/ci-test-scope.cjs +441 -0
  564. package/scripts/command-contract-helpers.cjs +64 -0
  565. package/scripts/diff-touches-shipped-paths.cjs +149 -0
  566. package/scripts/fix-slash-commands.cjs +161 -0
  567. package/scripts/gen-capability-registry.cjs +2646 -0
  568. package/scripts/gen-commands-reference.cjs +139 -0
  569. package/scripts/gen-inventory-manifest.cjs +114 -0
  570. package/scripts/gen-loop-host-contract.cjs +526 -0
  571. package/scripts/gen-research-agents.cjs +276 -0
  572. package/scripts/generate-package-identity.cjs +134 -0
  573. package/scripts/issue-dedupe.cjs +278 -0
  574. package/scripts/issue-version-gate.cjs +140 -0
  575. package/scripts/lib/allowlist-ratchet.cjs +236 -0
  576. package/scripts/lib/cli-exit.cjs +56 -0
  577. package/scripts/lint-allow-test-rule-refs.allowlist.json +328 -0
  578. package/scripts/lint-allow-test-rule-refs.cjs +162 -0
  579. package/scripts/lint-command-contract.cjs +118 -0
  580. package/scripts/lint-descriptions.cjs +87 -0
  581. package/scripts/lint-docs-required.cjs +222 -0
  582. package/scripts/lint-legacy-dir-name.cjs +166 -0
  583. package/scripts/lint-package-identity-drift.cjs +141 -0
  584. package/scripts/lint-pr-check-project-dir.cjs +99 -0
  585. package/scripts/lint-regression-test-names.allowlist.json +269 -0
  586. package/scripts/lint-regression-test-names.cjs +117 -0
  587. package/scripts/lint-shell-command-projection-drift.cjs +62 -0
  588. package/scripts/lint-skill-deps.cjs +185 -0
  589. package/scripts/lint-test-file-count.allowlist.json +181 -0
  590. package/scripts/lint-test-file-count.cjs +246 -0
  591. package/scripts/lint-windows-test-portability.cjs +178 -0
  592. package/scripts/mutation-matrix.cjs +323 -0
  593. package/scripts/pr-target-policy.cjs +63 -0
  594. package/scripts/pr-template-policy.cjs +268 -0
  595. package/scripts/prompt-injection-scan.sh +207 -0
  596. package/scripts/registry-smoke.cjs +337 -0
  597. package/scripts/release-notes/discord-release-summary.cjs +373 -0
  598. package/scripts/release-notes/format-github-release-notes.cjs +261 -0
  599. package/scripts/release-tarball-smoke.cjs +763 -0
  600. package/scripts/research-profiles.cjs +149 -0
  601. package/scripts/run-affected-tests.cjs +7 -0
  602. package/scripts/run-tests.cjs +589 -0
  603. package/scripts/secret-scan-lint.sh +231 -0
  604. package/scripts/secret-scan.sh +358 -0
  605. package/scripts/setup-branch-protection.sh +234 -0
  606. package/scripts/strip-prose-atrefs.cjs +106 -0
  607. package/scripts/sync-manifest-versions.cjs +119 -0
  608. package/scripts/sync-next-version.cjs +133 -0
  609. package/scripts/sync-rulesets.sh +34 -0
  610. package/scripts/sync-runtime-launcher.cjs +425 -0
  611. package/scripts/test-failure-reasons.cjs +34 -0
  612. package/scripts/update-size-baseline.cjs +68 -0
  613. package/scripts/verify-npm-publish.cjs +240 -0
  614. package/scripts/verify-opengsd-sweep.cjs +288 -0
  615. package/scripts/verify-phase-02-rename.sh +258 -0
  616. package/scripts/verify-phase-03-rename.sh +376 -0
  617. package/scripts/workflow-policy.cjs +483 -0
  618. package/scripts/workflow-size.cjs +90 -0
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ /**
3
+ * CLI I/O primitives — output(), error(), ERROR_REASON, JSON-error mode,
4
+ * and the temp-file helpers that output() depends on.
5
+ *
6
+ * Extracted from core.cts (ADR-857 rollout phase 1 / issue #859).
7
+ * The hand-written bodies are preserved byte-for-behaviour; only the module
8
+ * boundary moved. The core.cjs re-export spine was retired in epic #1267;
9
+ * callers import I/O primitives from io.cjs directly.
10
+ */
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ const node_fs_1 = __importDefault(require("node:fs"));
15
+ const node_os_1 = __importDefault(require("node:os"));
16
+ const node_path_1 = __importDefault(require("node:path"));
17
+ const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
18
+ // ─── Temp-file helpers (needed by output()) ──────────────────────────────────
19
+ /**
20
+ * Dedicated GSD temp directory: path.join(os.tmpdir(), 'gsd').
21
+ * Created on first use. Keeps GSD temp files isolated from the system
22
+ * temp directory so reap scans only GSD files (#1975).
23
+ */
24
+ const GSD_TEMP_DIR = node_path_1.default.join(node_os_1.default.tmpdir(), 'gsd');
25
+ function ensureGsdTempDir() {
26
+ (0, shell_command_projection_cjs_1.platformEnsureDir)(GSD_TEMP_DIR);
27
+ }
28
+ /**
29
+ * Remove stale gsd-* temp files/dirs older than maxAgeMs (default: 5 minutes).
30
+ * Runs opportunistically before each new temp file write to prevent unbounded accumulation.
31
+ * @param prefix - filename prefix to match (e.g., 'gsd-')
32
+ * @param opts
33
+ * @param opts.maxAgeMs - max age in ms before removal (default: 5 min)
34
+ * @param opts.dirsOnly - if true, only remove directories (default: false)
35
+ */
36
+ function reapStaleTempFiles(prefix = 'gsd-', { maxAgeMs = 5 * 60 * 1000, dirsOnly = false } = {}) {
37
+ try {
38
+ ensureGsdTempDir();
39
+ const now = Date.now();
40
+ const entries = node_fs_1.default.readdirSync(GSD_TEMP_DIR);
41
+ for (const entry of entries) {
42
+ if (!entry.startsWith(prefix))
43
+ continue;
44
+ const fullPath = node_path_1.default.join(GSD_TEMP_DIR, entry);
45
+ try {
46
+ const stat = node_fs_1.default.statSync(fullPath);
47
+ if (now - stat.mtimeMs > maxAgeMs) {
48
+ if (stat.isDirectory()) {
49
+ node_fs_1.default.rmSync(fullPath, { recursive: true, force: true });
50
+ }
51
+ else if (!dirsOnly) {
52
+ node_fs_1.default.unlinkSync(fullPath);
53
+ }
54
+ }
55
+ }
56
+ catch {
57
+ // File may have been removed between readdir and stat — ignore
58
+ }
59
+ }
60
+ }
61
+ catch {
62
+ // Non-critical — don't let cleanup failures break output
63
+ }
64
+ }
65
+ // ─── Output helpers ───────────────────────────────────────────────────────────
66
+ /**
67
+ * Transient write errnos. When stdout/stderr is a NON-BLOCKING pipe — as it is
68
+ * under the parallel `node --test` runner on Linux CI — a full pipe buffer makes
69
+ * `fs.writeSync` throw EAGAIN, and a signal can interrupt it with EINTR. Both
70
+ * clear on retry once the reader drains. This is the same transient class the
71
+ * STATE.md lock path already retries (ACQUIRE_LOCK_RETRY_ERRNOS, #3776); #1008.
72
+ */
73
+ const WRITE_RETRY_ERRNOS = new Set(['EAGAIN', 'EINTR']);
74
+ // Bounded so a pathological never-draining fd cannot spin forever. Each retry
75
+ // yields the thread for ~1ms via Atomics.wait (the project's sync-sleep idiom —
76
+ // see clock.cts realClock.sleep), so the cap is ~1s of total back-pressure wait.
77
+ const WRITE_MAX_RETRIES = 1000;
78
+ const WRITE_RETRY_BACKOFF_MS = 1;
79
+ // Sleep buffer is lazily allocated on the FIRST back-pressure retry (rare — only
80
+ // when a non-blocking pipe is full) and then reused. Keeping it out of module
81
+ // load costs nothing on the overwhelmingly common no-retry path and avoids
82
+ // perturbing SharedArrayBuffer-allocation accounting in other modules (perf-316).
83
+ let _writeSleepBuf = null;
84
+ function backoffOnce() {
85
+ if (_writeSleepBuf === null)
86
+ _writeSleepBuf = new Int32Array(new SharedArrayBuffer(4));
87
+ Atomics.wait(_writeSleepBuf, 0, 0, WRITE_RETRY_BACKOFF_MS);
88
+ }
89
+ /**
90
+ * Write the entire payload to `fd`, tolerating non-blocking-pipe back-pressure.
91
+ *
92
+ * `fs.writeSync` does NOT block on a non-blocking pipe: a full buffer throws
93
+ * EAGAIN, and a partially-drained buffer returns a SHORT count (fewer bytes than
94
+ * requested). The previous bare `fs.writeSync(fd, string)` call assumed it always
95
+ * blocked until the kernel accepted every byte — false under load, which both
96
+ * threw spurious errors and risked silently truncating output (#1008).
97
+ *
98
+ * This loops on short counts (advancing the offset) and retries EAGAIN/EINTR with
99
+ * a brief Atomics.wait backoff that yields the thread so the reader can drain.
100
+ * Non-transient errors (e.g. EPIPE) propagate unchanged.
101
+ */
102
+ function writeAllSync(fd, data) {
103
+ const buf = Buffer.from(data, 'utf8');
104
+ let offset = 0;
105
+ let retries = 0;
106
+ while (offset < buf.length) {
107
+ try {
108
+ offset += node_fs_1.default.writeSync(fd, buf, offset, buf.length - offset);
109
+ }
110
+ catch (err) {
111
+ const code = err.code ?? '';
112
+ if (WRITE_RETRY_ERRNOS.has(code) && retries < WRITE_MAX_RETRIES) {
113
+ retries += 1;
114
+ backoffOnce();
115
+ continue;
116
+ }
117
+ throw err;
118
+ }
119
+ }
120
+ }
121
+ function output(result, raw, rawValue) {
122
+ let data;
123
+ if (raw && rawValue !== undefined) {
124
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
125
+ data = String(rawValue);
126
+ }
127
+ else {
128
+ const json = JSON.stringify(result, null, 2);
129
+ // Large payloads exceed Claude Code's Bash tool buffer (~50KB).
130
+ // Write to tmpfile and output the path prefixed with @file: so callers can detect it.
131
+ if (json.length > 50000) {
132
+ reapStaleTempFiles();
133
+ ensureGsdTempDir();
134
+ const tmpPath = node_path_1.default.join(GSD_TEMP_DIR, `gsd-${Date.now()}.json`);
135
+ (0, shell_command_projection_cjs_1.platformWriteSync)(tmpPath, json);
136
+ data = '@file:' + tmpPath;
137
+ }
138
+ else {
139
+ data = json;
140
+ }
141
+ }
142
+ // process.stdout.write() is async when stdout is a pipe — process.exit()
143
+ // can tear down the process before the reader consumes the buffer. writeAllSync
144
+ // pushes every byte synchronously (looping short counts, retrying EAGAIN/EINTR),
145
+ // and skipping process.exit() lets the event loop drain naturally.
146
+ writeAllSync(1, data);
147
+ }
148
+ /**
149
+ * Frozen enum of typed reason codes used by error() for structured errors.
150
+ * Each subcommand contributes its own codes; the enum exists so tests can
151
+ * assert against typed values instead of grepping stderr (#2974).
152
+ *
153
+ * Adding a new code:
154
+ * - Pick a snake_case lowercase value (the JSON wire form)
155
+ * - Group by subsystem prefix (CONFIG_*, SDK_*, etc)
156
+ * - Pass it to error(msg, ERROR_REASON.NEW_CODE) at the call site
157
+ */
158
+ const ERROR_REASON = Object.freeze({
159
+ // config-get / config-set
160
+ CONFIG_KEY_NOT_FOUND: 'config_key_not_found',
161
+ CONFIG_NO_FILE: 'config_no_file',
162
+ CONFIG_PARSE_FAILED: 'config_parse_failed',
163
+ CONFIG_INVALID_KEY: 'config_invalid_key',
164
+ // SDK / gsd-tools dispatch
165
+ SDK_FAIL_FAST: 'sdk_fail_fast',
166
+ SDK_UNKNOWN_COMMAND: 'sdk_unknown_command',
167
+ SDK_MISSING_ARG: 'sdk_missing_arg',
168
+ // workflow / phase
169
+ PHASE_NOT_FOUND: 'phase_not_found',
170
+ SUMMARY_NO_PLANNING: 'summary_no_planning',
171
+ // graphify
172
+ GRAPHIFY_NO_GRAPH: 'graphify_no_graph',
173
+ GRAPHIFY_INVALID_QUERY: 'graphify_invalid_query',
174
+ // hooks
175
+ HOOKS_OPT_OUT: 'hooks_opt_out',
176
+ // security-scan
177
+ SECURITY_SCAN_FAILED: 'security_scan_failed',
178
+ // generic
179
+ USAGE: 'usage',
180
+ UNKNOWN: 'unknown',
181
+ });
182
+ /**
183
+ * Process-level flag: when true, error() emits structured JSON to stderr
184
+ * instead of plain "Error: <message>" text. Set by gsd-tools.cjs when the
185
+ * CLI is invoked with `--json-errors`. Tests opt in to typed-IR error
186
+ * assertions by passing that flag and parsing the JSON.
187
+ *
188
+ * Default off so existing callers and human operators keep their plain-text
189
+ * diagnostics. The structured form is opt-in for tooling and tests (#2974).
190
+ */
191
+ let _jsonErrorMode = false;
192
+ function setJsonErrorMode(v) { _jsonErrorMode = !!v; }
193
+ function getJsonErrorMode() { return _jsonErrorMode; }
194
+ /**
195
+ * Emit an error and exit. When the second argument is provided it must be
196
+ * a value from ERROR_REASON; tests can assert on `result.reason`. When the
197
+ * process is in JSON-error mode, stderr receives `{ ok: false, reason,
198
+ * message }` so callers can parse it; otherwise stderr keeps the plain
199
+ * text form for human operators.
200
+ */
201
+ function error(message, reason = ERROR_REASON.UNKNOWN) {
202
+ if (_jsonErrorMode) {
203
+ const payload = JSON.stringify({ ok: false, reason, message }) + '\n';
204
+ writeAllSync(2, payload);
205
+ }
206
+ else {
207
+ writeAllSync(2, 'Error: ' + message + '\n');
208
+ }
209
+ process.exit(1);
210
+ }
211
+ module.exports = {
212
+ GSD_TEMP_DIR,
213
+ ensureGsdTempDir,
214
+ reapStaleTempFiles,
215
+ output,
216
+ ERROR_REASON,
217
+ setJsonErrorMode,
218
+ getJsonErrorMode,
219
+ error,
220
+ };
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ /**
3
+ * Learnings — Global knowledge store with CRUD operations
4
+ *
5
+ * Provides a cross-project learnings store at ~/.gsd/knowledge/.
6
+ * Each learning is stored as an individual JSON file with content-hash
7
+ * deduplication. Supports write, read, list, query, delete, copy-from-project,
8
+ * and prune operations.
9
+ *
10
+ * Storage format: { id, source_project, date, context, learning, tags, content_hash }
11
+ * File naming: {id}.json
12
+ * Deduplication: SHA-256 of learning text + source_project
13
+ *
14
+ * ADR-457 build-at-publish: the hand-written bin/lib/learnings.cjs collapsed
15
+ * to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
16
+ * from the prior hand-written .cjs; only strict types are added.
17
+ */
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ const node_fs_1 = __importDefault(require("node:fs"));
22
+ const node_path_1 = __importDefault(require("node:path"));
23
+ const node_crypto_1 = __importDefault(require("node:crypto"));
24
+ const node_os_1 = __importDefault(require("node:os"));
25
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
26
+ const ioMod = require("./io.cjs");
27
+ const { output, error: coreError } = ioMod;
28
+ const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
29
+ // ─── Constants ───────────────────────────────────────────────────────────────
30
+ const DEFAULT_STORE_DIR = node_path_1.default.join(node_os_1.default.homedir(), '.gsd', 'knowledge');
31
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
32
+ function getStoreDir(opts) {
33
+ return (opts && opts.storeDir) || DEFAULT_STORE_DIR;
34
+ }
35
+ function ensureStoreDir(dir) {
36
+ if (!node_fs_1.default.existsSync(dir)) {
37
+ node_fs_1.default.mkdirSync(dir, { recursive: true });
38
+ }
39
+ }
40
+ function contentHash(learning, sourceProject) {
41
+ return node_crypto_1.default.createHash('sha256')
42
+ .update(learning + '\n' + sourceProject)
43
+ .digest('hex');
44
+ }
45
+ function generateId() {
46
+ const ts = Date.now().toString(36);
47
+ const rand = node_crypto_1.default.randomBytes(4).toString('hex');
48
+ return `${ts}-${rand}`;
49
+ }
50
+ function readLearningFile(filePath) {
51
+ try {
52
+ const content = node_fs_1.default.readFileSync(filePath, 'utf-8');
53
+ return JSON.parse(content);
54
+ }
55
+ catch (err) {
56
+ process.stderr.write(`Warning: skipping malformed file ${filePath}: ${err.message}\n`);
57
+ return null;
58
+ }
59
+ }
60
+ // ─── CRUD Operations ─────────────────────────────────────────────────────────
61
+ function learningsWrite(entry, opts) {
62
+ const dir = getStoreDir(opts);
63
+ ensureStoreDir(dir);
64
+ const hash = contentHash(entry.learning, entry.source_project);
65
+ // #306: In bulk-import paths, callers may supply a pre-built dedupeIndex
66
+ // (Map<content_hash, id>) to avoid the per-write O(N) store scan.
67
+ if (opts && opts.dedupeIndex) {
68
+ const dedupeIndex = opts.dedupeIndex;
69
+ if (dedupeIndex.has(hash)) {
70
+ return { id: dedupeIndex.get(hash), created: false, content_hash: hash };
71
+ }
72
+ const id = generateId();
73
+ const record = {
74
+ id,
75
+ source_project: entry.source_project,
76
+ date: new Date().toISOString(),
77
+ context: entry.context || '',
78
+ learning: entry.learning,
79
+ tags: entry.tags || [],
80
+ content_hash: hash,
81
+ };
82
+ (0, shell_command_projection_cjs_1.platformWriteSync)(node_path_1.default.join(dir, `${id}.json`), JSON.stringify(record, null, 2));
83
+ dedupeIndex.set(hash, id);
84
+ return { id, created: true, content_hash: hash };
85
+ }
86
+ // Check for duplicate by scanning existing files (single-write path, unchanged)
87
+ const files = node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'));
88
+ for (const file of files) {
89
+ const existing = readLearningFile(node_path_1.default.join(dir, file));
90
+ if (existing && existing.content_hash === hash) {
91
+ return { id: existing.id, created: false, content_hash: hash };
92
+ }
93
+ }
94
+ const id = generateId();
95
+ const record = {
96
+ id,
97
+ source_project: entry.source_project,
98
+ date: new Date().toISOString(),
99
+ context: entry.context || '',
100
+ learning: entry.learning,
101
+ tags: entry.tags || [],
102
+ content_hash: hash,
103
+ };
104
+ (0, shell_command_projection_cjs_1.platformWriteSync)(node_path_1.default.join(dir, `${id}.json`), JSON.stringify(record, null, 2));
105
+ return { id, created: true, content_hash: hash };
106
+ }
107
+ function learningsRead(id, opts) {
108
+ if (!/^[a-z0-9]+-[a-f0-9]+$/.test(id))
109
+ return null;
110
+ const dir = getStoreDir(opts);
111
+ const filePath = node_path_1.default.join(dir, `${id}.json`);
112
+ if (!node_fs_1.default.existsSync(filePath))
113
+ return null;
114
+ return readLearningFile(filePath);
115
+ }
116
+ function learningsList(opts) {
117
+ const dir = getStoreDir(opts);
118
+ if (!node_fs_1.default.existsSync(dir))
119
+ return [];
120
+ const files = node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'));
121
+ const results = [];
122
+ for (const file of files) {
123
+ const record = readLearningFile(node_path_1.default.join(dir, file));
124
+ if (record)
125
+ results.push(record);
126
+ }
127
+ // Sort by date descending (newest first)
128
+ results.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
129
+ return results;
130
+ }
131
+ function learningsQuery(query, opts) {
132
+ const all = learningsList(opts);
133
+ if (query && query.tag) {
134
+ return all.filter(r => r.tags && r.tags.includes(query.tag));
135
+ }
136
+ return all;
137
+ }
138
+ function learningsDelete(id, opts) {
139
+ if (!/^[a-z0-9]+-[a-f0-9]+$/.test(id))
140
+ return false;
141
+ const dir = getStoreDir(opts);
142
+ const filePath = node_path_1.default.join(dir, `${id}.json`);
143
+ if (!node_fs_1.default.existsSync(filePath))
144
+ return false;
145
+ node_fs_1.default.unlinkSync(filePath);
146
+ return true;
147
+ }
148
+ function learningsCopyFromProject(planningDir, opts) {
149
+ const learningsPath = node_path_1.default.join(planningDir, 'LEARNINGS.md');
150
+ if (!node_fs_1.default.existsSync(learningsPath)) {
151
+ return { total: 0, created: 0, skipped: 0 };
152
+ }
153
+ const content = node_fs_1.default.readFileSync(learningsPath, 'utf-8');
154
+ const sourceProject = (opts && opts.sourceProject) || node_path_1.default.basename(node_path_1.default.resolve(planningDir, '..'));
155
+ // #306: Build the content_hash -> id dedupe index once before the loop so
156
+ // that learningsWrite does not re-scan the entire store on every call —
157
+ // O(K*N) -> O(N+K).
158
+ const dir = getStoreDir(opts);
159
+ ensureStoreDir(dir);
160
+ const dedupeIndex = new Map();
161
+ for (const file of node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'))) {
162
+ const existing = readLearningFile(node_path_1.default.join(dir, file));
163
+ // First-seen-wins, matching the legacy scan path's first-match return so the
164
+ // dedupe-hit `id` is identical on both paths even if the store already holds
165
+ // duplicate content_hashes. (#306)
166
+ if (existing && existing.content_hash && !dedupeIndex.has(existing.content_hash)) {
167
+ dedupeIndex.set(existing.content_hash, existing.id);
168
+ }
169
+ }
170
+ // Parse markdown: split on ## headings
171
+ const sections = content.split(/^## /m).slice(1); // skip preamble before first ##
172
+ let created = 0;
173
+ let skipped = 0;
174
+ for (const section of sections) {
175
+ const lines = section.trim().split('\n');
176
+ const title = lines[0].trim();
177
+ const body = lines.slice(1).join('\n').trim();
178
+ if (!body)
179
+ continue;
180
+ // Extract tags from title (simple: use words as tags)
181
+ const tags = title.toLowerCase().split(/\s+/).filter(w => w.length > 2);
182
+ const result = learningsWrite({
183
+ source_project: sourceProject,
184
+ learning: body,
185
+ context: title,
186
+ tags,
187
+ }, { ...opts, dedupeIndex });
188
+ if (result.created) {
189
+ created++;
190
+ }
191
+ else {
192
+ skipped++;
193
+ }
194
+ }
195
+ return { total: created + skipped, created, skipped };
196
+ }
197
+ function learningsPrune(olderThan, opts) {
198
+ const match = /^(\d+)d$/.exec(olderThan);
199
+ if (!match) {
200
+ throw new Error(`Invalid duration format: "${olderThan}" — expected format like "90d"`);
201
+ }
202
+ const days = parseInt(match[1], 10);
203
+ const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
204
+ const dir = getStoreDir(opts);
205
+ if (!node_fs_1.default.existsSync(dir))
206
+ return { removed: 0, kept: 0 };
207
+ const files = node_fs_1.default.readdirSync(dir).filter(f => f.endsWith('.json'));
208
+ let removed = 0;
209
+ let kept = 0;
210
+ for (const file of files) {
211
+ const filePath = node_path_1.default.join(dir, file);
212
+ const record = readLearningFile(filePath);
213
+ if (!record)
214
+ continue;
215
+ const recordDate = new Date(record.date);
216
+ if (recordDate < cutoff) {
217
+ node_fs_1.default.unlinkSync(filePath);
218
+ removed++;
219
+ }
220
+ else {
221
+ kept++;
222
+ }
223
+ }
224
+ return { removed, kept };
225
+ }
226
+ // ─── CLI Command Handlers ────────────────────────────────────────────────────
227
+ function cmdLearningsList(raw) {
228
+ const results = learningsList();
229
+ output({ learnings: results, count: results.length }, raw, undefined);
230
+ }
231
+ function cmdLearningsQuery(tag, raw) {
232
+ const results = learningsQuery({ tag });
233
+ output({ learnings: results, count: results.length, tag }, raw, undefined);
234
+ }
235
+ function cmdLearningsCopy(cwd, raw) {
236
+ const planDir = node_path_1.default.join(cwd, '.planning');
237
+ const result = learningsCopyFromProject(planDir);
238
+ output(result, raw, undefined);
239
+ }
240
+ function cmdLearningsPrune(olderThan, raw) {
241
+ try {
242
+ const result = learningsPrune(olderThan);
243
+ output(result, raw, undefined);
244
+ }
245
+ catch (err) {
246
+ coreError(err.message);
247
+ }
248
+ }
249
+ function cmdLearningsDelete(id, raw) {
250
+ if (!/^[a-z0-9]+-[a-f0-9]+$/.test(id)) {
251
+ coreError(`Invalid learning ID: "${id}"`);
252
+ }
253
+ const deleted = learningsDelete(id);
254
+ output({ id, deleted }, raw, undefined);
255
+ }
256
+ module.exports = {
257
+ learningsWrite,
258
+ learningsRead,
259
+ learningsList,
260
+ learningsQuery,
261
+ learningsDelete,
262
+ learningsCopyFromProject,
263
+ learningsPrune,
264
+ cmdLearningsList,
265
+ cmdLearningsQuery,
266
+ cmdLearningsCopy,
267
+ cmdLearningsPrune,
268
+ cmdLearningsDelete,
269
+ DEFAULT_STORE_DIR,
270
+ };