@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,337 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scripts/registry-smoke.cjs
4
+ *
5
+ * Post-publish registry smoke test (D-12 regression guard).
6
+ *
7
+ * Strategy: install the REAL published @pareto4/pp-core from the npm registry
8
+ * into a temp prefix, invoke the installed pp-core installer in a clean fixture
9
+ * HOME, assert the /pp-progress artifact lands. Reuses the Phase-5 clean-room
10
+ * helpers from release-tarball-smoke.cjs, repointed from a local tarball at the
11
+ * live registry.
12
+ *
13
+ * Purpose: SC2's mandatory gate is the live human smoke (plan 10). This automated
14
+ * check is a regression guard for FUTURE releases. Build it now so plan 10 can
15
+ * run it against the freshly published package, and so CI can run it post-publish.
16
+ *
17
+ * Exports:
18
+ * SMOKE — frozen enum of result codes (re-exported from release-tarball-smoke.cjs)
19
+ * runRegistrySmoke — pure function; accepts { registryTag, expectedVersion,
20
+ * installPrefix, fixtureDir, dryRun }
21
+ *
22
+ * CLI entry: node scripts/registry-smoke.cjs [--registry-tag <tag>]
23
+ * [--expected-version <ver>]
24
+ * [--dry-run]
25
+ * Installs from the registry, runs the pp-core installer, asserts /pp-progress artifact.
26
+ * Exits 0 on SMOKE.OK, 1 otherwise.
27
+ *
28
+ * Key links:
29
+ * - scripts/release-tarball-smoke.cjs : reuses SMOKE enum, locateProgressArtifact,
30
+ * findInstallerBin, binInvocation, RUNTIME_FLAGS
31
+ * - pp-core/bin/lib/package-identity.cjs : PACKAGE_NAME (never hardcode @pareto4/pp-core)
32
+ */
33
+
34
+ 'use strict';
35
+
36
+ const { execFileSync, spawnSync } = require('child_process');
37
+ const fs = require('fs');
38
+ const os = require('os');
39
+ const path = require('path');
40
+
41
+ const { PACKAGE_NAME } = require('../pp-core/bin/lib/package-identity.cjs');
42
+ const { ExitError, runMain } = require('./lib/cli-exit.cjs');
43
+
44
+ // Reuse helpers from release-tarball-smoke — do not re-implement.
45
+ const {
46
+ SMOKE,
47
+ locateProgressArtifact,
48
+ findInstallerBin,
49
+ binInvocation,
50
+ RUNTIME_FLAGS, // eslint-disable-line no-unused-vars -- re-exported for callers
51
+ } = require('./release-tarball-smoke.cjs');
52
+
53
+ // Same timeout as release-tarball-smoke.cjs (600 s on Windows, 120 s elsewhere).
54
+ // Windows npm global installs on cold-cache can take up to 10 minutes.
55
+ const CHILD_TIMEOUT_MS = process.platform === 'win32' ? 600_000 : 120_000;
56
+
57
+ // Suppress npm noise during install — mirrors the constant in release-tarball-smoke.cjs.
58
+ const QUIET_NPM_ENV = Object.freeze({
59
+ npm_config_loglevel: 'error',
60
+ npm_config_update_notifier: 'false',
61
+ NO_UPDATE_NOTIFIER: '1',
62
+ });
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Registry availability wait (synchronous — adapted from verify-npm-publish.cjs)
66
+ // ---------------------------------------------------------------------------
67
+
68
+ /**
69
+ * Synchronously wait for PACKAGE_NAME@version to appear on the npm registry.
70
+ * Uses a blocking Atomics.wait sleep between retries (safe in Node.js main thread).
71
+ *
72
+ * Adapted from verify-npm-publish.cjs verifyPublish() lines 45-95, converted to
73
+ * synchronous form so it composes with spawnSync-based install without requiring
74
+ * an async runRegistrySmoke.
75
+ *
76
+ * @param {string} version
77
+ * @param {{ maxAttempts?: number, intervalMs?: number }} [opts]
78
+ * @returns {{ ok: boolean, attempts: number }}
79
+ */
80
+ function waitForRegistryVersion(version, { maxAttempts = 20, intervalMs = 5000 } = {}) {
81
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
82
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
83
+ try {
84
+ const out = execFileSync(
85
+ npmCmd,
86
+ ['view', `${PACKAGE_NAME}@${version}`, 'version'],
87
+ {
88
+ encoding: 'utf-8',
89
+ stdio: ['ignore', 'pipe', 'ignore'],
90
+ timeout: 15_000,
91
+ shell: process.platform === 'win32',
92
+ },
93
+ ).trim();
94
+ if (out === version) return { ok: true, attempts: attempt };
95
+ } catch {
96
+ // Version not yet available — retry below.
97
+ }
98
+ if (attempt < maxAttempts) {
99
+ // Synchronous sleep: safe in Node.js main thread (unlike browsers).
100
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, intervalMs);
101
+ }
102
+ }
103
+ return { ok: false, attempts: maxAttempts };
104
+ }
105
+
106
+ // ---------------------------------------------------------------------------
107
+ // Cleanup helper
108
+ // ---------------------------------------------------------------------------
109
+
110
+ function cleanup(...dirs) {
111
+ for (const dir of dirs) {
112
+ try {
113
+ fs.rmSync(dir, { recursive: true, force: true });
114
+ } catch {
115
+ // best-effort
116
+ }
117
+ }
118
+ }
119
+
120
+ // ---------------------------------------------------------------------------
121
+ // Pure function: runRegistrySmoke
122
+ // ---------------------------------------------------------------------------
123
+
124
+ /**
125
+ * Install the REAL published package from the npm registry into a clean tmp
126
+ * HOME, invoke the pp-core installer, and assert the /pp-progress artifact
127
+ * lands. The ONLY substantive difference from runSmoke() in release-tarball-
128
+ * smoke.cjs is the install spec (registry spec instead of a .tgz path) and
129
+ * the absence of an npm pack step.
130
+ *
131
+ * @param {object} opts
132
+ * @param {string} [opts.registryTag='latest'] - npm dist-tag to install (e.g. 'latest', 'next')
133
+ * @param {string} [opts.expectedVersion] - If provided, wait for this exact version to be
134
+ * visible on the registry before installing; also recorded in result details.
135
+ * @param {string} opts.installPrefix - Temp directory for npm --prefix (global install)
136
+ * @param {string} opts.fixtureDir - Temp dir used as cwd+HOME for the installer
137
+ * @param {boolean} [opts.dryRun=false] - If true, short-circuit immediately without
138
+ * touching the network (mirrors release-tarball-smoke.cjs lines 420-422)
139
+ * @returns {{ code: string, details: object }}
140
+ */
141
+ function runRegistrySmoke({
142
+ registryTag = 'latest',
143
+ expectedVersion,
144
+ installPrefix,
145
+ fixtureDir,
146
+ dryRun = false,
147
+ }) {
148
+ const details = {
149
+ packageName: PACKAGE_NAME,
150
+ registryTag,
151
+ expectedVersion,
152
+ prefix: installPrefix,
153
+ };
154
+
155
+ // Dry-run short-circuit — mirrors release-tarball-smoke.cjs lines 420-422.
156
+ if (dryRun) {
157
+ return { code: SMOKE.OK, details: { ...details, version: expectedVersion, dryRun: true } };
158
+ }
159
+
160
+ // Optionally wait for the expected version to be available on the registry.
161
+ // This bounds the wait for registry/CDN propagation lag after a fresh publish
162
+ // (T-06-08 mitigation — denial-of-service / registry not yet propagated).
163
+ if (expectedVersion) {
164
+ const waitResult = waitForRegistryVersion(expectedVersion);
165
+ if (!waitResult.ok) {
166
+ return {
167
+ code: SMOKE.INSTALL_FAILED,
168
+ details: {
169
+ ...details,
170
+ reason: 'registry-version-not-visible',
171
+ attempts: waitResult.attempts,
172
+ },
173
+ };
174
+ }
175
+ }
176
+
177
+ // Install from the registry.
178
+ // ONLY substantive difference from the tarball harness: use a registry spec
179
+ // (${PACKAGE_NAME}@${registryTag}) instead of a .tgz path; no npm pack step.
180
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
181
+ const effectiveNpmEnv = { ...process.env, ...QUIET_NPM_ENV };
182
+ const registrySpec = `${PACKAGE_NAME}@${registryTag}`;
183
+
184
+ const installResult = spawnSync(
185
+ npmCmd,
186
+ ['install', '-g', '--prefix', installPrefix, registrySpec],
187
+ {
188
+ encoding: 'utf-8',
189
+ shell: process.platform === 'win32',
190
+ timeout: CHILD_TIMEOUT_MS,
191
+ env: effectiveNpmEnv,
192
+ },
193
+ );
194
+
195
+ if (installResult.status !== 0) {
196
+ return {
197
+ code: SMOKE.INSTALL_FAILED,
198
+ details: {
199
+ ...details,
200
+ registrySpec,
201
+ stderr: installResult.stderr,
202
+ stdout: installResult.stdout,
203
+ signal: installResult.signal ?? null,
204
+ installError: installResult.error ? String(installResult.error) : null,
205
+ },
206
+ };
207
+ }
208
+
209
+ // Locate the installed pp-core installer binary.
210
+ const installerBin = findInstallerBin(installPrefix);
211
+ if (!installerBin) {
212
+ return {
213
+ code: SMOKE.BIN_NOT_CALLABLE,
214
+ details: { ...details, registrySpec, installPrefix },
215
+ };
216
+ }
217
+
218
+ // Invoke pp-core --local --claude in the clean fixture dir.
219
+ // Set HOME+USERPROFILE to fixtureDir so npm/installer writes never touch the
220
+ // operator's real ~/.claude (T-06-07 mitigation: isolated fixture HOME).
221
+ const childEnv = { ...effectiveNpmEnv, HOME: fixtureDir, USERPROFILE: fixtureDir };
222
+ delete childEnv.GSD_TEST_MODE; // install.js skips main() when GSD_TEST_MODE is set
223
+
224
+ const inv = binInvocation(installerBin, ['--local', '--claude']);
225
+ const initResult = spawnSync(inv.command, inv.args, {
226
+ encoding: 'utf-8',
227
+ cwd: fixtureDir,
228
+ stdio: ['pipe', 'pipe', 'pipe'],
229
+ env: childEnv,
230
+ timeout: CHILD_TIMEOUT_MS,
231
+ shell: inv.shell,
232
+ });
233
+
234
+ if (initResult.status !== 0) {
235
+ return {
236
+ code: SMOKE.INIT_FAILED,
237
+ details: {
238
+ ...details,
239
+ registrySpec,
240
+ fixtureDir,
241
+ stderr: initResult.stderr,
242
+ stdout: initResult.stdout,
243
+ },
244
+ };
245
+ }
246
+
247
+ // Assert the /pp-progress artifact landed in the installed config root.
248
+ // locateProgressArtifact() checks all three layout forms (command-flat,
249
+ // command-subdir, skill) — mirrors the D-12 flat-hyphen scope asymmetry
250
+ // discovered in Phase 5 (05-05 Task 2).
251
+ const claudeRoot = path.join(fixtureDir, '.claude');
252
+ const artifact = locateProgressArtifact(claudeRoot);
253
+
254
+ if (!artifact) {
255
+ return {
256
+ code: SMOKE.COMMAND_FILE_MISSING,
257
+ details: {
258
+ ...details,
259
+ registrySpec,
260
+ fixtureDir,
261
+ claudeRoot,
262
+ reason: 'pp-progress artifact not found after registry install',
263
+ },
264
+ };
265
+ }
266
+
267
+ details.artifact = artifact;
268
+ details.version = expectedVersion || registryTag;
269
+
270
+ return { code: SMOKE.OK, details };
271
+ }
272
+
273
+ // ---------------------------------------------------------------------------
274
+ // CLI entry
275
+ // ---------------------------------------------------------------------------
276
+
277
+ function cliMain() {
278
+ const argv = process.argv.slice(2);
279
+ let registryTag = 'latest';
280
+ let expectedVersion;
281
+ let dryRun = false;
282
+
283
+ for (let i = 0; i < argv.length; i++) {
284
+ const a = argv[i];
285
+ if (a === '--registry-tag') {
286
+ const v = argv[++i];
287
+ if (!v || v.startsWith('-')) throw new ExitError(2, 'error: --registry-tag requires a value');
288
+ registryTag = v;
289
+ } else if (a === '--expected-version') {
290
+ const v = argv[++i];
291
+ if (!v || v.startsWith('-')) throw new ExitError(2, 'error: --expected-version requires a value');
292
+ expectedVersion = v;
293
+ } else if (a === '--dry-run') {
294
+ dryRun = true;
295
+ } else if (a === '--help' || a === '-h') {
296
+ process.stdout.write(
297
+ 'Usage: node scripts/registry-smoke.cjs [options]\n' +
298
+ '\n' +
299
+ 'Options:\n' +
300
+ ' --registry-tag <tag> npm dist-tag to install (default: latest)\n' +
301
+ ' --expected-version <ver> wait for this version to be visible, then install\n' +
302
+ ' --dry-run skip all network calls; validate flag parsing only\n' +
303
+ ' --help, -h show this help\n',
304
+ );
305
+ throw new ExitError(0);
306
+ } else {
307
+ throw new ExitError(2, `error: unknown argument: ${a}`);
308
+ }
309
+ }
310
+
311
+ const installPrefix = fs.mkdtempSync(path.join(os.tmpdir(), 'pp-reg-smoke-prefix-'));
312
+ const fixtureDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pp-reg-smoke-fixture-'));
313
+
314
+ let result;
315
+ try {
316
+ result = runRegistrySmoke({ registryTag, expectedVersion, installPrefix, fixtureDir, dryRun });
317
+ } finally {
318
+ cleanup(installPrefix, fixtureDir);
319
+ }
320
+
321
+ const statusLine = result.code === SMOKE.OK
322
+ ? `[registry-smoke] OK: ${PACKAGE_NAME}@${registryTag} — ${JSON.stringify(result.details)}`
323
+ : `[registry-smoke] FAIL (${result.code}): ${JSON.stringify(result.details)}`;
324
+ process.stdout.write(statusLine + '\n');
325
+
326
+ return result.code === SMOKE.OK ? 0 : 1;
327
+ }
328
+
329
+ // ---------------------------------------------------------------------------
330
+ // Exports
331
+ // ---------------------------------------------------------------------------
332
+
333
+ module.exports = { SMOKE, runRegistrySmoke };
334
+
335
+ if (require.main === module) {
336
+ runMain(cliMain);
337
+ }
@@ -0,0 +1,373 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const cp = require('node:child_process');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { ExitError, runMain } = require('../lib/cli-exit.cjs');
8
+ const { classifyTitle } = require('./format-github-release-notes.cjs');
9
+
10
+ const DEFAULT_MAX_CONTENT = 1850;
11
+ const SECTION_LIMITS = Object.freeze([
12
+ ['Breaking', 4],
13
+ ['Security', 4],
14
+ ['Feature', 4],
15
+ ['Fix', 4],
16
+ ['Enhancement', 3],
17
+ ['Internal', 2],
18
+ ['New Contributors', 3],
19
+ ]);
20
+
21
+ function normalizeNewlines(value) {
22
+ return String(value || '').replace(/\r\n/g, '\n');
23
+ }
24
+
25
+ function releaseTag(release) {
26
+ return release.tagName || release.tag_name || release.name || 'release';
27
+ }
28
+
29
+ function releaseName(release) {
30
+ return release.name || releaseTag(release);
31
+ }
32
+
33
+ function releaseUrl(release) {
34
+ return release.url || release.html_url || '';
35
+ }
36
+
37
+ function releaseIsPrerelease(release) {
38
+ return release.isPrerelease === true || release.prerelease === true || /-/.test(releaseTag(release));
39
+ }
40
+
41
+ function loadPackageName(repoRoot = path.resolve(__dirname, '..', '..')) {
42
+ const pkgJson = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
43
+ return pkgJson.name || 'package';
44
+ }
45
+
46
+ function normalizeHeading(value) {
47
+ const heading = value.trim().replace(/:$/, '');
48
+ const lower = heading.toLowerCase();
49
+
50
+ if (lower.includes('breaking')) return 'Breaking';
51
+ if (lower.includes('security')) return 'Security';
52
+ if (lower === 'feature' || lower === 'features') return 'Feature';
53
+ if (lower === 'fix' || lower === 'fixes' || lower === 'bug fixes') return 'Fix';
54
+ if (lower === 'enhancement' || lower === 'enhancements' || lower === 'improvements') return 'Enhancement';
55
+ if (lower === 'internal' || lower === 'maintenance') return 'Internal';
56
+ if (lower === 'new contributors') return 'New Contributors';
57
+ if (lower === "what's changed" || lower === 'whats changed') return "What's Changed";
58
+ return heading;
59
+ }
60
+
61
+ function collectSections(body) {
62
+ const sections = new Map();
63
+ let current = null;
64
+
65
+ for (const line of normalizeNewlines(body).split('\n')) {
66
+ const trimmed = line.trim();
67
+ const heading = trimmed.match(/^#{2,3}\s+(.+)$/);
68
+
69
+ if (heading) {
70
+ current = normalizeHeading(heading[1]);
71
+ continue;
72
+ }
73
+
74
+ const bullet = trimmed.match(/^([*-])\s+(.+)$/);
75
+ if (!bullet || !current) continue;
76
+
77
+ let section = current;
78
+ if (section === "What's Changed") {
79
+ section = classifyTitle(trimmed);
80
+ }
81
+
82
+ if (!sections.has(section)) sections.set(section, []);
83
+ sections.get(section).push(cleanBullet(trimmed));
84
+ }
85
+
86
+ return sections;
87
+ }
88
+
89
+ function cleanBullet(value) {
90
+ let text = String(value)
91
+ .replace(/^[*-]\s+/, '')
92
+ .replace(/\s+by\s+@[A-Za-z0-9-]+\s+in\s+https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/(\d+)/g, ' (#$1)')
93
+ .replace(/\[([^\]]+)\]\((https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/(?:pull|issues)\/(\d+))\)/g, '$1 (#$3)')
94
+ .replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, '$1')
95
+ .replace(/https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/(\d+)/g, '#$1')
96
+ .replace(/https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/issues\/(\d+)/g, '#$1')
97
+ .replace(/https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/commit\/([0-9a-f]{7})[0-9a-f]*/gi, '$1')
98
+ .replace(/\*\*/g, '')
99
+ .replace(/\s+/g, ' ')
100
+ .trim();
101
+
102
+ text = text
103
+ .replace(/^\[codex\]\s+/i, '')
104
+ .replace(/^(?:feat|fix|docs|chore|ci|refactor|test)(?:\([^)]+\))?!?:\s+/i, '');
105
+ text = text.replace(/#(\d+)\s+\(#\1\)/g, '#$1');
106
+ text = text.replace(/\s+\(#(\d+)\)\s+\(#\1\)$/g, ' (#$1)');
107
+
108
+ return truncateAtWord(text, 220);
109
+ }
110
+
111
+ function truncateAtWord(value, maxLength) {
112
+ if (value.length <= maxLength) return value;
113
+ const splitAt = value.lastIndexOf(' ', maxLength - 3);
114
+ if (splitAt < 80) return `${value.slice(0, maxLength - 3)}...`;
115
+ return `${value.slice(0, splitAt)}...`;
116
+ }
117
+
118
+ function extractInstallCommand(body, packageName, release) {
119
+ const lines = normalizeNewlines(body).split('\n');
120
+ let inInstall = false;
121
+ let inFence = false;
122
+
123
+ for (const line of lines) {
124
+ const trimmed = line.trim();
125
+
126
+ if (/^##\s+Install\b/i.test(trimmed)) {
127
+ inInstall = true;
128
+ continue;
129
+ }
130
+
131
+ if (inInstall && /^##\s+/.test(trimmed)) break;
132
+ if (!inInstall) continue;
133
+
134
+ if (trimmed.startsWith('```')) {
135
+ inFence = !inFence;
136
+ continue;
137
+ }
138
+
139
+ if (inFence && /^npm\s+(?:i|install)\s+/.test(trimmed)) {
140
+ return trimmed;
141
+ }
142
+ }
143
+
144
+ const channel = releaseIsPrerelease(release) ? 'next' : 'latest';
145
+ return `npm i ${packageName}@${channel}`;
146
+ }
147
+
148
+ function buildDiscordReleasePayload({ release, packageName = loadPackageName(), maxContent = DEFAULT_MAX_CONTENT }) {
149
+ const tag = releaseTag(release);
150
+ const name = releaseName(release);
151
+ const url = releaseUrl(release);
152
+ const prerelease = releaseIsPrerelease(release);
153
+ const channel = prerelease ? 'next' : 'latest';
154
+ const body = release.body || '';
155
+ const sections = collectSections(body);
156
+ const footer = url ? `Full changelog: ${url}` : `Full changelog: ${tag}`;
157
+ const baseLines = [
158
+ `**${packageName} ${name}${prerelease ? ' pre-release' : ''} is out**`,
159
+ '',
160
+ 'Install:',
161
+ `\`${extractInstallCommand(body, packageName, release)}\``,
162
+ ];
163
+
164
+ const lines = baseLines.slice();
165
+ for (const [section, limit] of SECTION_LIMITS) {
166
+ appendSection(lines, section, sections.get(section) || [], limit, footer, maxContent);
167
+ }
168
+
169
+ if (lines.length === baseLines.length) {
170
+ appendLineGroup(lines, ['', 'No release notes were provided.'], footer, maxContent);
171
+ }
172
+
173
+ if (joinedLength(lines, footer) > maxContent) {
174
+ while (lines.length > baseLines.length && joinedLength(lines, footer) > maxContent) {
175
+ lines.pop();
176
+ }
177
+ }
178
+
179
+ const content = [...lines, '', footer].join('\n');
180
+ return {
181
+ username: 'GSD Releases',
182
+ content,
183
+ embeds: [
184
+ {
185
+ title: 'Release details',
186
+ url: url || undefined,
187
+ color: prerelease ? 0xd9a441 : 0x2f9e44,
188
+ fields: [
189
+ { name: 'Package', value: `\`${packageName}\``, inline: true },
190
+ { name: 'Channel', value: `\`${channel}\``, inline: true },
191
+ { name: 'Version', value: `\`${tag}\``, inline: true },
192
+ ],
193
+ },
194
+ ],
195
+ allowed_mentions: { parse: [] },
196
+ };
197
+ }
198
+
199
+ function appendSection(lines, section, bullets, limit, footer, maxContent) {
200
+ if (bullets.length === 0) return;
201
+
202
+ const label = sectionLabel(section);
203
+ const selected = [];
204
+ for (const bullet of bullets.slice(0, limit)) {
205
+ const candidate = ['', `**${label}**`, ...selected.map((item) => `- ${item}`), `- ${bullet}`];
206
+ if (joinedLength([...lines, ...candidate], footer) > maxContent) break;
207
+ selected.push(bullet);
208
+ }
209
+
210
+ if (selected.length === 0) return;
211
+
212
+ const group = ['', `**${label}**`, ...selected.map((item) => `- ${item}`)];
213
+ const remaining = bullets.length - selected.length;
214
+ if (remaining > 0) {
215
+ const moreLine = `- ...and ${remaining} more ${label.toLowerCase()}`;
216
+ if (joinedLength([...lines, ...group, moreLine], footer) <= maxContent) {
217
+ group.push(moreLine);
218
+ }
219
+ }
220
+
221
+ appendLineGroup(lines, group, footer, maxContent);
222
+ }
223
+
224
+ function appendLineGroup(lines, group, footer, maxContent) {
225
+ if (joinedLength([...lines, ...group], footer) <= maxContent) {
226
+ lines.push(...group);
227
+ }
228
+ }
229
+
230
+ function joinedLength(lines, footer) {
231
+ return [...lines, '', footer].join('\n').length;
232
+ }
233
+
234
+ function sectionLabel(section) {
235
+ if (section === 'Feature') return 'Features';
236
+ if (section === 'Fix') return 'Fixes';
237
+ if (section === 'Enhancement') return 'Enhancements';
238
+ return section;
239
+ }
240
+
241
+ function fetchRelease({ tag, repo, latest = false }) {
242
+ const args = ['release', 'view'];
243
+ if (!latest && tag) args.push(tag);
244
+ args.push('--json', 'tagName,name,isPrerelease,body,url');
245
+ if (repo) args.push('--repo', repo);
246
+ const raw = cp.execFileSync('gh', args, { encoding: 'utf8' });
247
+ return JSON.parse(raw);
248
+ }
249
+
250
+ async function postWebhook(webhookUrl, payload) {
251
+ const response = await fetch(webhookUrl, {
252
+ method: 'POST',
253
+ headers: { 'content-type': 'application/json' },
254
+ body: JSON.stringify(payload),
255
+ });
256
+
257
+ if (!response.ok) {
258
+ throw new ExitError(1, `Discord webhook failed with ${response.status}: ${await response.text()}`);
259
+ }
260
+ }
261
+
262
+ function parseArgs(argv) {
263
+ const opts = {
264
+ tag: null,
265
+ repo: null,
266
+ latest: false,
267
+ stdin: false,
268
+ post: false,
269
+ json: false,
270
+ allowMissingWebhook: false,
271
+ packageName: null,
272
+ maxContent: DEFAULT_MAX_CONTENT,
273
+ };
274
+
275
+ const args = argv.slice();
276
+ while (args.length > 0) {
277
+ const arg = args.shift();
278
+ if (arg === '--tag') {
279
+ opts.tag = requireValue(args, arg);
280
+ } else if (arg === '--repo') {
281
+ opts.repo = requireValue(args, arg);
282
+ } else if (arg === '--package') {
283
+ opts.packageName = requireValue(args, arg);
284
+ } else if (arg === '--max-content') {
285
+ opts.maxContent = Number(requireValue(args, arg));
286
+ } else if (arg === '--latest') {
287
+ opts.latest = true;
288
+ } else if (arg === '--stdin') {
289
+ opts.stdin = true;
290
+ } else if (arg === '--post') {
291
+ opts.post = true;
292
+ } else if (arg === '--json') {
293
+ opts.json = true;
294
+ } else if (arg === '--allow-missing-webhook') {
295
+ opts.allowMissingWebhook = true;
296
+ } else if (arg === '--help' || arg === '-h') {
297
+ process.stdout.write(
298
+ 'Usage: node scripts/release-notes/discord-release-summary.cjs [--tag <tag>|--latest|--stdin] [options]\n' +
299
+ '\n' +
300
+ 'Options:\n' +
301
+ ' --tag <tag> GitHub release tag to announce\n' +
302
+ ' --latest Announce the latest GitHub release\n' +
303
+ ' --stdin Read release JSON from stdin\n' +
304
+ ' --repo <owner/repo> Repository for gh release view\n' +
305
+ ' --package <name> Package name override\n' +
306
+ ' --post POST to DISCORD_WEBHOOK_URL\n' +
307
+ ' --allow-missing-webhook Warn and skip instead of failing when posting without a webhook\n' +
308
+ ' --json Print webhook payload JSON instead of content preview\n' +
309
+ ' --max-content <n> Max Discord content characters before webhook footer\n'
310
+ );
311
+ throw new ExitError(0);
312
+ } else {
313
+ throw new ExitError(2, `error: unknown argument ${arg}`);
314
+ }
315
+ }
316
+
317
+ if (!Number.isFinite(opts.maxContent) || opts.maxContent < 500 || opts.maxContent > 2000) {
318
+ throw new ExitError(2, 'error: --max-content must be between 500 and 2000');
319
+ }
320
+
321
+ return opts;
322
+ }
323
+
324
+ function requireValue(args, flag) {
325
+ const value = args.shift();
326
+ if (!value || value.startsWith('-')) {
327
+ throw new ExitError(2, `error: ${flag} requires a value`);
328
+ }
329
+ return value;
330
+ }
331
+
332
+ async function main() {
333
+ const opts = parseArgs(process.argv.slice(2));
334
+ let release;
335
+
336
+ if (opts.stdin) {
337
+ release = JSON.parse(fs.readFileSync('/dev/stdin', 'utf8'));
338
+ } else {
339
+ release = fetchRelease(opts);
340
+ }
341
+
342
+ const payload = buildDiscordReleasePayload({
343
+ release,
344
+ packageName: opts.packageName || loadPackageName(),
345
+ maxContent: opts.maxContent,
346
+ });
347
+
348
+ if (opts.post) {
349
+ const webhookUrl = process.env.DISCORD_WEBHOOK_URL;
350
+ if (!webhookUrl) {
351
+ if (opts.allowMissingWebhook) {
352
+ process.stderr.write('warning: DISCORD_WEBHOOK_URL is not set; skipping Discord announcement\n');
353
+ } else {
354
+ throw new ExitError(1, 'error: DISCORD_WEBHOOK_URL is not set');
355
+ }
356
+ } else {
357
+ await postWebhook(webhookUrl, payload);
358
+ }
359
+ }
360
+
361
+ process.stdout.write(opts.json ? `${JSON.stringify(payload, null, 2)}\n` : `${payload.content}\n`);
362
+ }
363
+
364
+ if (require.main === module) {
365
+ runMain(main);
366
+ }
367
+
368
+ module.exports = {
369
+ buildDiscordReleasePayload,
370
+ cleanBullet,
371
+ collectSections,
372
+ extractInstallCommand,
373
+ };