@planu/cli 4.14.1 → 5.1.1

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 (452) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/LICENSE +55 -12
  3. package/README.md +10 -2
  4. package/dist/cli/commands/install.d.ts +1 -12
  5. package/dist/cli/commands/install.js +9 -65
  6. package/dist/cli/commands/job.js +4 -3
  7. package/dist/cli/commands/spec.js +12 -3
  8. package/dist/cli/commands/validate.js +2 -2
  9. package/dist/cli/router.js +1 -3
  10. package/dist/config/environment-schema.json +1 -3
  11. package/dist/config/official-sdd-tools.d.ts +4 -0
  12. package/dist/config/official-sdd-tools.js +35 -0
  13. package/dist/config/product-public.d.ts +139 -3
  14. package/dist/config/product-public.js +8 -1
  15. package/dist/config/product-public.json +7 -36
  16. package/dist/config/registries/hosts/codex.json +20 -363
  17. package/dist/config/release-policy.json +84 -2
  18. package/dist/config/runtime-policy.json +12 -1
  19. package/dist/config/skill-templates/planu-resume-work.md +2 -2
  20. package/dist/core/index.d.ts +1 -1
  21. package/dist/core/spec-validator.d.ts +4 -4
  22. package/dist/core/spec-validator.js +33 -19
  23. package/dist/engine/abortable-process-runner.d.ts +20 -2
  24. package/dist/engine/abortable-process-runner.js +243 -74
  25. package/dist/engine/ambiguity-scorer.js +4 -26
  26. package/dist/engine/auth/scope-mapper.js +1 -7
  27. package/dist/engine/autopilot/state-updater.js +4 -4
  28. package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
  29. package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
  30. package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
  31. package/dist/engine/ci-generator/planu-config.js +1 -7
  32. package/dist/engine/clarification-gate/gate.d.ts +3 -3
  33. package/dist/engine/code-scanner/layer-scanner.js +6 -22
  34. package/dist/engine/core-bridge.d.ts +3 -3
  35. package/dist/engine/cost-guardrails.d.ts +1 -1
  36. package/dist/engine/cost-guardrails.js +1 -1
  37. package/dist/engine/criterion-identity.d.ts +1 -0
  38. package/dist/engine/criterion-identity.js +7 -0
  39. package/dist/engine/dashboard/data-loader.js +2 -7
  40. package/dist/engine/dashboard/templates-layout.js +0 -3
  41. package/dist/engine/dashboard/templates-project.js +1 -13
  42. package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
  43. package/dist/engine/docs-site-generator/data-collector.js +7 -28
  44. package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
  45. package/dist/engine/evidence-gates/artifact-reader.d.ts +12 -1
  46. package/dist/engine/evidence-gates/artifact-reader.js +174 -4
  47. package/dist/engine/evidence-gates/evidence-autofill.d.ts +10 -0
  48. package/dist/engine/evidence-gates/evidence-autofill.js +148 -0
  49. package/dist/engine/evidence-gates/evidence-skeletons.d.ts +19 -0
  50. package/dist/engine/evidence-gates/evidence-skeletons.js +69 -0
  51. package/dist/engine/evidence-gates/lifecycle-gate.js +4 -3
  52. package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
  53. package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
  54. package/dist/engine/evidence-index/done-drift.d.ts +1 -1
  55. package/dist/engine/evidence-index/done-drift.js +40 -18
  56. package/dist/engine/execution/context.js +3 -0
  57. package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
  58. package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
  59. package/dist/engine/execution/job-runtime.d.ts +30 -0
  60. package/dist/engine/execution/job-runtime.js +114 -6
  61. package/dist/engine/execution/operation-journal.js +10 -4
  62. package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
  63. package/dist/engine/execution/public-job-sanitizer.js +31 -0
  64. package/dist/engine/execution/validate-job-executor.d.ts +12 -1
  65. package/dist/engine/execution/validate-job-executor.js +549 -86
  66. package/dist/engine/execution/validate-job-payload.js +107 -50
  67. package/dist/engine/execution/validate-job-recovery.js +1 -1
  68. package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
  69. package/dist/engine/execution/validate-worker-runtime.js +90 -2
  70. package/dist/engine/execution/validate-worker-thread.js +17 -24
  71. package/dist/engine/handoff-artifacts/schemas.d.ts +2 -1
  72. package/dist/engine/handoff-artifacts/schemas.js +33 -0
  73. package/dist/engine/handoff-packager.d.ts +19 -0
  74. package/dist/engine/handoff-packager.js +415 -13
  75. package/dist/engine/hooks/effort-configurator.js +1 -1
  76. package/dist/engine/impact-detector/test-break-predictor.js +3 -3
  77. package/dist/engine/impact-detector/tool-registration.js +1 -1
  78. package/dist/engine/implementation-contract/renderer.js +23 -8
  79. package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
  80. package/dist/engine/lifecycle-reconciliation-io.js +180 -0
  81. package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
  82. package/dist/engine/lifecycle-reconciliation.js +406 -0
  83. package/dist/engine/local-first/tool-classification.js +2 -0
  84. package/dist/engine/macos-keychain-native-port.d.ts +5 -0
  85. package/dist/engine/macos-keychain-native-port.js +19 -7
  86. package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
  87. package/dist/engine/migrations/remove-commercial-state.js +343 -0
  88. package/dist/engine/minimality/policy-loader.js +247 -6
  89. package/dist/engine/network-policy.js +1 -0
  90. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
  91. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +20 -20
  92. package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
  93. package/dist/engine/planu-core.darwin-x64.node.sbom.json +20 -20
  94. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
  95. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +20 -20
  96. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
  97. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +20 -20
  98. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
  99. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +20 -20
  100. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
  101. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +20 -20
  102. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
  103. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +20 -20
  104. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
  105. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +20 -20
  106. package/dist/engine/readiness-checker.d.ts +1 -16
  107. package/dist/engine/readiness-checker.js +27 -88
  108. package/dist/engine/reverse-engineer/api-detector.js +2 -13
  109. package/dist/engine/reverse-engineer/complexity-analyzer.js +2 -13
  110. package/dist/engine/reverse-engineer/config-analyzer.js +2 -13
  111. package/dist/engine/reverse-engineer/dependency-graph.js +2 -13
  112. package/dist/engine/reverse-engineer/test-analyzer.js +2 -13
  113. package/dist/engine/reverse-engineer/walk-ignore.d.ts +3 -0
  114. package/dist/engine/reverse-engineer/walk-ignore.js +26 -0
  115. package/dist/engine/runtime-policy.d.ts +2 -0
  116. package/dist/engine/runtime-policy.js +42 -5
  117. package/dist/engine/runtime-security/rate-limiter.js +0 -1
  118. package/dist/engine/safety/contained-project-file.d.ts +3 -0
  119. package/dist/engine/safety/contained-project-file.js +23 -0
  120. package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
  121. package/dist/engine/scope-boundaries/scope-validator.js +45 -7
  122. package/dist/engine/session/checkpoint-writer.js +0 -9
  123. package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
  124. package/dist/engine/spec-format/acceptance-criteria.js +82 -22
  125. package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
  126. package/dist/engine/spec-format/markdown-sections.js +105 -0
  127. package/dist/engine/spec-format/read-technical-section.js +33 -5
  128. package/dist/engine/spec-format/technical-md-populator.js +3 -2
  129. package/dist/engine/spec-format/text-fences.js +20 -2
  130. package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
  131. package/dist/engine/spec-format/unified-spec-builder.js +202 -0
  132. package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
  133. package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
  134. package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
  135. package/dist/engine/spec-migrator/filesystem-import.js +121 -14
  136. package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
  137. package/dist/engine/spec-migrator/index.d.ts +1 -0
  138. package/dist/engine/spec-migrator/index.js +1 -0
  139. package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
  140. package/dist/engine/spec-state-machine/transition-spec.js +10 -1
  141. package/dist/engine/spec-state-syncer.js +1 -1
  142. package/dist/engine/technical-enricher/index.js +16 -8
  143. package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
  144. package/dist/engine/technical-enricher/render-enriched.js +42 -14
  145. package/dist/engine/telemetry/health-checker.js +53 -17
  146. package/dist/engine/telemetry/telemetry-client.js +26 -8
  147. package/dist/engine/text-signal-boundaries.d.ts +2 -0
  148. package/dist/engine/text-signal-boundaries.js +25 -2
  149. package/dist/engine/time/relative-date.d.ts +3 -0
  150. package/dist/engine/time/relative-date.js +16 -0
  151. package/dist/engine/timing/budget.d.ts +11 -0
  152. package/dist/engine/timing/budget.js +31 -9
  153. package/dist/engine/token-optimizer/analytics.d.ts +1 -1
  154. package/dist/engine/token-optimizer/analytics.js +5 -6
  155. package/dist/engine/usage-tracker/core.d.ts +2 -2
  156. package/dist/engine/usage-tracker/core.js +1 -2
  157. package/dist/engine/usage-tracker/index.d.ts +0 -3
  158. package/dist/engine/usage-tracker/index.js +0 -3
  159. package/dist/engine/usage-tracker/stats.d.ts +2 -2
  160. package/dist/engine/usage-tracker/stats.js +1 -28
  161. package/dist/engine/validation/durable-validation.d.ts +1 -1
  162. package/dist/engine/validation/durable-validation.js +3 -82
  163. package/dist/engine/validation/validation-freshness.d.ts +11 -1
  164. package/dist/engine/validation/validation-freshness.js +231 -91
  165. package/dist/engine/validation/validation-receipt.d.ts +9 -6
  166. package/dist/engine/validation/validation-receipt.js +84 -24
  167. package/dist/engine/validation/validation-source-digest.d.ts +2 -0
  168. package/dist/engine/validation/validation-source-digest.js +86 -0
  169. package/dist/engine/validation/validation-submission.d.ts +5 -4
  170. package/dist/engine/validation/validation-submission.js +25 -11
  171. package/dist/engine/validation/validation-worktree.d.ts +21 -0
  172. package/dist/engine/validation/validation-worktree.js +260 -0
  173. package/dist/engine/validation-impact-planner.d.ts +14 -2
  174. package/dist/engine/validation-impact-planner.js +0 -3
  175. package/dist/engine/validator/dor-dod.d.ts +1 -0
  176. package/dist/engine/validator/dor-dod.js +5 -3
  177. package/dist/engine/validator/extractors.d.ts +1 -5
  178. package/dist/engine/validator/extractors.js +24 -69
  179. package/dist/engine/validator/spec-compliance-runner.d.ts +12 -24
  180. package/dist/engine/validator/spec-compliance-runner.js +429 -211
  181. package/dist/engine/validator.js +35 -22
  182. package/dist/index.js +4 -16
  183. package/dist/resources/usage-stats-resource.js +2 -18
  184. package/dist/security/adapters/linux-secret-service.js +7 -3
  185. package/dist/security/adapters/windows-credential-manager.js +6 -4
  186. package/dist/server/routes/specs.js +13 -1
  187. package/dist/storage/base-store.d.ts +1 -1
  188. package/dist/storage/base-store.js +1 -1
  189. package/dist/storage/feedback-remote.d.ts +2 -3
  190. package/dist/storage/feedback-remote.js +45 -31
  191. package/dist/storage/global-store.d.ts +1 -17
  192. package/dist/storage/global-store.js +1 -42
  193. package/dist/storage/index.d.ts +0 -2
  194. package/dist/storage/index.js +0 -2
  195. package/dist/storage/migrations/canonical-storage.js +124 -11
  196. package/dist/storage/runtime-db.d.ts +9 -0
  197. package/dist/storage/runtime-db.js +64 -8
  198. package/dist/storage/spec-store.d.ts +14 -2
  199. package/dist/storage/spec-store.js +104 -14
  200. package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
  201. package/dist/storage/status-store/atomic-status-write.js +57 -0
  202. package/dist/storage/status-store/file-lock.js +30 -11
  203. package/dist/storage/status-store/self-healing.js +3 -3
  204. package/dist/storage/status-store/version-sync.d.ts +2 -1
  205. package/dist/storage/status-store/version-sync.js +35 -40
  206. package/dist/storage/usage-store.d.ts +1 -5
  207. package/dist/storage/usage-store.js +0 -35
  208. package/dist/tools/auto-update-handler.d.ts +3 -3
  209. package/dist/tools/auto-update-handler.js +3 -3
  210. package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
  211. package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
  212. package/dist/tools/challenge-spec/scenario-collector.js +1 -1
  213. package/dist/tools/challenge-spec/scenarios-data.js +1 -1
  214. package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
  215. package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
  216. package/dist/tools/challenge-spec-helpers.d.ts +10 -1
  217. package/dist/tools/challenge-spec-helpers.js +63 -22
  218. package/dist/tools/challenge-spec.js +23 -8
  219. package/dist/tools/check-readiness.js +38 -14
  220. package/dist/tools/configure-telemetry.js +30 -2
  221. package/dist/tools/create-spec/spec-builder.d.ts +7 -0
  222. package/dist/tools/create-spec/spec-builder.js +19 -15
  223. package/dist/tools/create-spec.d.ts +1 -0
  224. package/dist/tools/create-spec.js +584 -309
  225. package/dist/tools/git/branch-ops.d.ts +1 -1
  226. package/dist/tools/git/branch-ops.js +3 -2
  227. package/dist/tools/init-project/handler.js +10 -12
  228. package/dist/tools/init-project/host-assets-writer.js +26 -1
  229. package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
  230. package/dist/tools/init-project/migration-runner.d.ts +2 -4
  231. package/dist/tools/init-project/migration-runner.js +3 -2
  232. package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
  233. package/dist/tools/init-project/portable-index-reconciler.js +14 -0
  234. package/dist/tools/init-project/result-builder.js +1 -3
  235. package/dist/tools/jobs/handlers.js +38 -6
  236. package/dist/tools/list-specs.js +5 -26
  237. package/dist/tools/merge-risk-handler.js +2 -2
  238. package/dist/tools/package-handoff.js +2 -0
  239. package/dist/tools/reconcile-spec.js +0 -27
  240. package/dist/tools/register-agent-squad-tools.js +2 -2
  241. package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
  242. package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
  243. package/dist/tools/register-sdd-tools.d.ts +1 -1
  244. package/dist/tools/register-sdd-tools.js +2 -29
  245. package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
  246. package/dist/tools/register-spec-tools/core-spec-tools.js +29 -19
  247. package/dist/tools/safe-handler.d.ts +5 -13
  248. package/dist/tools/safe-handler.js +7 -23
  249. package/dist/tools/schemas/index.d.ts +1 -1
  250. package/dist/tools/schemas/index.js +1 -1
  251. package/dist/tools/schemas/output-schemas.d.ts +0 -23
  252. package/dist/tools/schemas/output-schemas.js +0 -28
  253. package/dist/tools/schemas/spec.d.ts +4 -0
  254. package/dist/tools/schemas/spec.js +3 -0
  255. package/dist/tools/schemas/validate-output-schema.d.ts +11 -0
  256. package/dist/tools/schemas/validate-output-schema.js +7 -0
  257. package/dist/tools/spec-prompt-handler.js +3 -3
  258. package/dist/tools/sync-spec-state-handler.d.ts +1 -1
  259. package/dist/tools/sync-spec-state-handler.js +50 -2
  260. package/dist/tools/tool-entry.d.ts +4 -4
  261. package/dist/tools/tool-entry.js +3 -3
  262. package/dist/tools/tool-registry/core-tools.js +31 -15
  263. package/dist/tools/tool-registry/group-infra.js +27 -110
  264. package/dist/tools/tool-registry/group-quality-compliance.js +26 -26
  265. package/dist/tools/tool-registry/inventory.d.ts +2 -0
  266. package/dist/tools/tool-registry/inventory.js +2 -0
  267. package/dist/tools/tool-registry-helpers.d.ts +3 -3
  268. package/dist/tools/tool-registry-helpers.js +3 -3
  269. package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
  270. package/dist/tools/tool-usage-report/registered-tools.js +3 -15
  271. package/dist/tools/update-status/approval-gates.js +3 -0
  272. package/dist/tools/update-status/batch.d.ts +6 -2
  273. package/dist/tools/update-status/batch.js +58 -1
  274. package/dist/tools/update-status/dod-gates.d.ts +16 -1
  275. package/dist/tools/update-status/dod-gates.js +191 -1
  276. package/dist/tools/update-status/done-receipt-verifier.d.ts +8 -0
  277. package/dist/tools/update-status/done-receipt-verifier.js +75 -27
  278. package/dist/tools/update-status/evidence-gate.d.ts +4 -0
  279. package/dist/tools/update-status/evidence-gate.js +103 -3
  280. package/dist/tools/update-status/file-sync.d.ts +4 -3
  281. package/dist/tools/update-status/file-sync.js +57 -6
  282. package/dist/tools/update-status/index.d.ts +25 -1
  283. package/dist/tools/update-status/index.js +292 -78
  284. package/dist/tools/update-status/response-builder.js +3 -3
  285. package/dist/tools/update-status/side-effects.d.ts +2 -0
  286. package/dist/tools/update-status/side-effects.js +2 -2
  287. package/dist/tools/update-status/transition-guard.js +45 -16
  288. package/dist/tools/update-status-actions.d.ts +4 -2
  289. package/dist/tools/update-status-actions.js +16 -14
  290. package/dist/tools/usage-report.js +1 -16
  291. package/dist/tools/usage-stats.js +1 -18
  292. package/dist/tools/usage-tracking.d.ts +4 -0
  293. package/dist/tools/usage-tracking.js +20 -0
  294. package/dist/tools/validate-lint.d.ts +1 -0
  295. package/dist/tools/validate-lint.js +1 -1
  296. package/dist/tools/validate.d.ts +2 -1
  297. package/dist/tools/validate.js +114 -34
  298. package/dist/tools/workspace-dashboard-handler.js +38 -0
  299. package/dist/transports/http-transport.js +6 -8
  300. package/dist/transports/mcp-types.d.ts +0 -2
  301. package/dist/transports/session-context.js +1 -1
  302. package/dist/types/cascade-hooks.d.ts +1 -1
  303. package/dist/types/ci.d.ts +0 -4
  304. package/dist/types/clarification-token.d.ts +1 -1
  305. package/dist/types/claude-code-runtime.d.ts +0 -27
  306. package/dist/types/commercial-migration.d.ts +17 -0
  307. package/dist/types/commercial-migration.js +2 -0
  308. package/dist/types/common/primitives.d.ts +0 -2
  309. package/dist/types/core-bridge.d.ts +4 -10
  310. package/dist/types/dashboard.d.ts +3 -7
  311. package/dist/types/docs.d.ts +0 -1
  312. package/dist/types/durable-job.d.ts +4 -4
  313. package/dist/types/durable-validation.d.ts +100 -2
  314. package/dist/types/durable-validation.js +165 -1
  315. package/dist/types/errors/structured-error.d.ts +3 -3
  316. package/dist/types/estimation.d.ts +2 -0
  317. package/dist/types/evidence-autofill.d.ts +34 -0
  318. package/dist/types/evidence-autofill.js +2 -0
  319. package/dist/types/evidence-gates.d.ts +9 -1
  320. package/dist/types/execution.d.ts +2 -0
  321. package/dist/types/gemini-integration.d.ts +0 -11
  322. package/dist/types/handoff-artifacts.d.ts +41 -0
  323. package/dist/types/hooks-advanced.d.ts +0 -13
  324. package/dist/types/impact-detection.d.ts +2 -2
  325. package/dist/types/index.d.ts +3 -6
  326. package/dist/types/index.js +2 -5
  327. package/dist/types/kiro-integration.d.ts +0 -6
  328. package/dist/types/network-policy.d.ts +1 -1
  329. package/dist/types/project/lint-scaffolder.d.ts +1 -1
  330. package/dist/types/runtime-policy.d.ts +11 -0
  331. package/dist/types/session-safeguard.d.ts +0 -31
  332. package/dist/types/spec/canonical-repair.d.ts +81 -0
  333. package/dist/types/spec/canonical-repair.js +2 -0
  334. package/dist/types/spec/core.d.ts +20 -0
  335. package/dist/types/spec/index.d.ts +1 -0
  336. package/dist/types/spec/index.js +1 -0
  337. package/dist/types/spec/inputs.d.ts +35 -1
  338. package/dist/types/spec-format.d.ts +25 -1
  339. package/dist/types/telemetry.d.ts +4 -1
  340. package/dist/types/transition-log.d.ts +1 -1
  341. package/dist/types/transport.d.ts +0 -2
  342. package/dist/types/usage.d.ts +1 -36
  343. package/dist/types/usage.js +1 -1
  344. package/dist/types/validate-worker.d.ts +6 -0
  345. package/dist/types/validation-receipt.d.ts +1 -1
  346. package/dist/types/validation.d.ts +10 -4
  347. package/package.json +17 -12
  348. package/planu-native.json +1 -1
  349. package/planu-plugin.json +23 -40
  350. package/scripts/lib/pending-release-file.mjs +93 -0
  351. package/src/i18n/messages/en.json +0 -41
  352. package/src/i18n/messages/es.json +0 -41
  353. package/src/i18n/messages/pt.json +0 -41
  354. package/dist/cli/commands/activate.d.ts +0 -14
  355. package/dist/cli/commands/activate.js +0 -174
  356. package/dist/config/license-plans.json +0 -251
  357. package/dist/config/product-public.ts +0 -148
  358. package/dist/config/server-instructions.ts +0 -121
  359. package/dist/config/version-defaults.ts +0 -76
  360. package/dist/config/version.ts +0 -21
  361. package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
  362. package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
  363. package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
  364. package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
  365. package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
  366. package/dist/engine/hooks/full-spectrum-generator.js +0 -117
  367. package/dist/engine/license-validator/config-loader.d.ts +0 -5
  368. package/dist/engine/license-validator/config-loader.js +0 -16
  369. package/dist/engine/license-validator/core.d.ts +0 -15
  370. package/dist/engine/license-validator/core.js +0 -151
  371. package/dist/engine/license-validator/fingerprint.d.ts +0 -3
  372. package/dist/engine/license-validator/fingerprint.js +0 -17
  373. package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
  374. package/dist/engine/license-validator/lemon-squeezy.js +0 -55
  375. package/dist/engine/license-validator.d.ts +0 -5
  376. package/dist/engine/license-validator.js +0 -6
  377. package/dist/engine/product-intelligence/index.d.ts +0 -7
  378. package/dist/engine/product-intelligence/index.js +0 -211
  379. package/dist/engine/session/auto-save.d.ts +0 -18
  380. package/dist/engine/session/auto-save.js +0 -98
  381. package/dist/engine/session/context-snapshot.d.ts +0 -8
  382. package/dist/engine/session/context-snapshot.js +0 -49
  383. package/dist/engine/session/memory-sync.d.ts +0 -12
  384. package/dist/engine/session/memory-sync.js +0 -34
  385. package/dist/engine/session/session-diff.d.ts +0 -11
  386. package/dist/engine/session/session-diff.js +0 -42
  387. package/dist/engine/session/session-merge.d.ts +0 -12
  388. package/dist/engine/session/session-merge.js +0 -55
  389. package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
  390. package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
  391. package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -15
  392. package/dist/engine/session-safeguard/learnings-buffer.js +0 -91
  393. package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
  394. package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
  395. package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
  396. package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
  397. package/dist/engine/spec-changelog/core.d.ts +0 -16
  398. package/dist/engine/spec-changelog/core.js +0 -176
  399. package/dist/engine/spec-changelog/diff.d.ts +0 -18
  400. package/dist/engine/spec-changelog/diff.js +0 -121
  401. package/dist/engine/spec-changelog/index.d.ts +0 -3
  402. package/dist/engine/spec-changelog/index.js +0 -4
  403. package/dist/engine/trial-engine.d.ts +0 -5
  404. package/dist/engine/trial-engine.js +0 -14
  405. package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
  406. package/dist/engine/usage-tracker/rate-check.js +0 -18
  407. package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
  408. package/dist/engine/usage-tracker/rate-limiter.js +0 -73
  409. package/dist/engine/usage-tracker/trial.d.ts +0 -27
  410. package/dist/engine/usage-tracker/trial.js +0 -49
  411. package/dist/engine/webhook/event-handlers.d.ts +0 -25
  412. package/dist/engine/webhook/event-handlers.js +0 -89
  413. package/dist/engine/webhook/index.d.ts +0 -4
  414. package/dist/engine/webhook/index.js +0 -5
  415. package/dist/engine/webhook/server.d.ts +0 -12
  416. package/dist/engine/webhook/server.js +0 -249
  417. package/dist/engine/webhook/signature.d.ts +0 -16
  418. package/dist/engine/webhook/signature.js +0 -49
  419. package/dist/storage/license-store.d.ts +0 -6
  420. package/dist/storage/license-store.js +0 -63
  421. package/dist/storage/session-store.d.ts +0 -20
  422. package/dist/storage/session-store.js +0 -136
  423. package/dist/tools/activate-license.d.ts +0 -6
  424. package/dist/tools/activate-license.js +0 -132
  425. package/dist/tools/checkpoint-handler.d.ts +0 -3
  426. package/dist/tools/checkpoint-handler.js +0 -130
  427. package/dist/tools/export-session.d.ts +0 -3
  428. package/dist/tools/export-session.js +0 -90
  429. package/dist/tools/license-gate.d.ts +0 -18
  430. package/dist/tools/license-gate.js +0 -222
  431. package/dist/tools/license-status.d.ts +0 -3
  432. package/dist/tools/license-status.js +0 -93
  433. package/dist/tools/list-sessions.d.ts +0 -3
  434. package/dist/tools/list-sessions.js +0 -46
  435. package/dist/tools/planu-session-checkpoint.d.ts +0 -6
  436. package/dist/tools/planu-session-checkpoint.js +0 -42
  437. package/dist/tools/restore-session.d.ts +0 -3
  438. package/dist/tools/restore-session.js +0 -71
  439. package/dist/tools/spec-history.d.ts +0 -3
  440. package/dist/tools/spec-history.js +0 -59
  441. package/dist/tools/webhook.d.ts +0 -6
  442. package/dist/tools/webhook.js +0 -150
  443. package/dist/types/changelog.d.ts +0 -49
  444. package/dist/types/changelog.js +0 -3
  445. package/dist/types/licensing.d.ts +0 -109
  446. package/dist/types/licensing.js +0 -4
  447. package/dist/types/product-intelligence.d.ts +0 -60
  448. package/dist/types/product-intelligence.js +0 -3
  449. package/dist/types/session.d.ts +0 -84
  450. package/dist/types/session.js +0 -3
  451. package/dist/types/webhook.d.ts +0 -62
  452. package/dist/types/webhook.js +0 -4
@@ -1,49 +0,0 @@
1
- // engine/webhook/signature.ts — HMAC-SHA256 signature validation for Lemon Squeezy webhooks.
2
- // Validates the X-Signature header against the raw request body.
3
- import { createHmac, timingSafeEqual } from 'node:crypto';
4
- // ---------------------------------------------------------------------------
5
- // Constants
6
- // ---------------------------------------------------------------------------
7
- const SIGNATURE_HEADER = 'x-signature';
8
- const HMAC_ALGO = 'sha256';
9
- // ---------------------------------------------------------------------------
10
- // Public API
11
- // ---------------------------------------------------------------------------
12
- /**
13
- * Validates an HMAC-SHA256 signature from a Lemon Squeezy webhook request.
14
- * Uses timing-safe comparison to prevent timing attacks.
15
- *
16
- * @param rawBody - The raw request body bytes (NOT parsed JSON)
17
- * @param signatureHeader - The value of the X-Signature header
18
- * @param secret - The webhook secret configured in Lemon Squeezy dashboard
19
- * @returns true if signature is valid, false otherwise
20
- */
21
- export function validateSignature(rawBody, signatureHeader, secret) {
22
- if (!secret || !signatureHeader) {
23
- return false;
24
- }
25
- const expectedHex = createHmac(HMAC_ALGO, secret).update(rawBody).digest('hex');
26
- try {
27
- const expectedBuf = Buffer.from(expectedHex, 'hex');
28
- const receivedBuf = Buffer.from(signatureHeader, 'hex');
29
- if (expectedBuf.length !== receivedBuf.length) {
30
- return false;
31
- }
32
- return timingSafeEqual(expectedBuf, receivedBuf);
33
- }
34
- catch /* v8 ignore start */ {
35
- return false;
36
- } /* v8 ignore stop */
37
- }
38
- /**
39
- * Extracts the signature header value from a map of HTTP headers.
40
- * Header names are case-insensitive in HTTP/1.1.
41
- */
42
- export function extractSignatureHeader(headers) {
43
- const raw = headers[SIGNATURE_HEADER];
44
- if (Array.isArray(raw)) {
45
- return raw[0] ?? '';
46
- }
47
- return raw ?? '';
48
- }
49
- //# sourceMappingURL=signature.js.map
@@ -1,6 +0,0 @@
1
- import type { LicenseState } from '../types/index.js';
2
- export declare function getLicenseState(): Promise<LicenseState | null>;
3
- export declare function saveLicenseState(state: LicenseState): Promise<void>;
4
- export declare function deleteLicenseState(): Promise<void>;
5
- export declare function countActiveProjects(): Promise<number>;
6
- //# sourceMappingURL=license-store.d.ts.map
@@ -1,63 +0,0 @@
1
- // storage/license-store.ts — Persistence layer for license state (~/.planu/data/global/license.json).
2
- import { readdir } from 'node:fs/promises';
3
- import { join } from 'node:path';
4
- import { readJson, globalDataDir } from './base-store.js';
5
- import { withFileLock } from './file-mutex.js';
6
- import { resolveStorageLayout } from './storage-layout.js';
7
- import { deleteSecretField, resolveSecretField, storeSecretField, } from '../security/secret-field.js';
8
- import { writeSecureJson } from '../security/secure-json.js';
9
- // ---------------------------------------------------------------------------
10
- // Paths
11
- // ---------------------------------------------------------------------------
12
- function licenseFile() {
13
- return join(globalDataDir(), 'license.json');
14
- }
15
- // ---------------------------------------------------------------------------
16
- // Public API
17
- // ---------------------------------------------------------------------------
18
- export async function getLicenseState() {
19
- const state = await readJson(licenseFile(), null);
20
- if (!state) {
21
- return null;
22
- }
23
- return { ...state, licenseKey: await resolveSecretField(state.licenseKey) };
24
- }
25
- export async function saveLicenseState(state) {
26
- await withFileLock(licenseFile(), async () => {
27
- const licenseKey = await storeSecretField('global/license', 'license', state.licenseKey);
28
- await writeSecureJson(licenseFile(), { ...state, licenseKey });
29
- });
30
- }
31
- export async function deleteLicenseState() {
32
- const { unlink } = await import('node:fs/promises');
33
- try {
34
- const state = await readJson(licenseFile(), null);
35
- await deleteSecretField(state?.licenseKey);
36
- await unlink(licenseFile());
37
- }
38
- catch (err) {
39
- if (isNodeError(err) && err.code === 'ENOENT') {
40
- return;
41
- }
42
- throw err;
43
- }
44
- }
45
- export async function countActiveProjects() {
46
- try {
47
- const entries = await readdir(resolveStorageLayout().projects, { withFileTypes: true });
48
- return entries.filter((e) => e.isDirectory()).length;
49
- }
50
- catch (err) {
51
- if (isNodeError(err) && err.code === 'ENOENT') {
52
- return 0;
53
- }
54
- throw err;
55
- }
56
- }
57
- // ---------------------------------------------------------------------------
58
- // Internal helpers
59
- // ---------------------------------------------------------------------------
60
- function isNodeError(err) {
61
- return err instanceof Error && 'code' in err;
62
- }
63
- //# sourceMappingURL=license-store.js.map
@@ -1,20 +0,0 @@
1
- import type { Session, SessionMemory, SessionListItem } from '../types/index.js';
2
- /** Save a session to disk. */
3
- export declare function save(session: Session): Promise<void>;
4
- /** Load a session by ID. Returns null if not found. */
5
- export declare function load(projectId: string, sessionId: string): Promise<Session | null>;
6
- /** List sessions for a project, ordered by lastSavedAt desc. */
7
- export declare function list(projectId: string): Promise<Session[]>;
8
- /** Get the most recent session for a project. */
9
- export declare function getLatest(projectId: string): Promise<Session | null>;
10
- /** Delete a session by ID. Returns true if removed. */
11
- export declare function deleteSession(projectId: string, sessionId: string): Promise<boolean>;
12
- /** List sessions as lightweight items for display. */
13
- export declare function listItems(projectId: string, limit?: number): Promise<SessionListItem[]>;
14
- /** Clean up old sessions: keep max 50, remove sessions older than 30 days. */
15
- export declare function cleanup(projectId: string): Promise<number>;
16
- /** Load cross-conversation memory for a project. */
17
- export declare function loadMemory(projectId: string): Promise<SessionMemory>;
18
- /** Save cross-conversation memory. */
19
- export declare function saveMemory(memory: SessionMemory): Promise<void>;
20
- //# sourceMappingURL=session-store.d.ts.map
@@ -1,136 +0,0 @@
1
- import { readJson, writeJson, projectDataDir } from './base-store.js';
2
- import { withFileLock } from './file-mutex.js';
3
- import { readdir, unlink } from 'node:fs/promises';
4
- // --- internal helpers ---
5
- function sanitizeId(id) {
6
- const sanitized = id.replace(/[/\\]/g, '_').replace(/\.\./g, '_');
7
- if (!sanitized || sanitized === '.' || sanitized === '..') {
8
- throw new Error(`Invalid ID: ${id}`);
9
- }
10
- return sanitized;
11
- }
12
- function sessionsDir(projectId) {
13
- return `${projectDataDir(projectId)}/sessions`;
14
- }
15
- function sessionFile(projectId, sessionId) {
16
- return `${sessionsDir(projectId)}/session-${sanitizeId(sessionId)}.json`;
17
- }
18
- function memoryFile(projectId) {
19
- return `${projectDataDir(projectId)}/session-memory.json`;
20
- }
21
- async function listSessionFiles(projectId) {
22
- try {
23
- const dir = sessionsDir(projectId);
24
- const entries = await readdir(dir);
25
- return entries.filter((f) => f.startsWith('session-') && f.endsWith('.json'));
26
- }
27
- catch (error) {
28
- if (error.code === 'ENOENT' ||
29
- (error instanceof Error && error.message === 'ENOENT')) {
30
- return [];
31
- }
32
- throw error;
33
- }
34
- }
35
- // --- public API ---
36
- /** Save a session to disk. */
37
- export async function save(session) {
38
- const file = sessionFile(session.projectId, session.id);
39
- await withFileLock(file, () => writeJson(file, session));
40
- }
41
- /** Load a session by ID. Returns null if not found. */
42
- export async function load(projectId, sessionId) {
43
- return readJson(sessionFile(projectId, sessionId), null);
44
- }
45
- /** List sessions for a project, ordered by lastSavedAt desc. */
46
- export async function list(projectId) {
47
- const files = await listSessionFiles(projectId);
48
- const sessions = [];
49
- for (const f of files) {
50
- const id = f.replace('session-', '').replace('.json', '');
51
- const s = await load(projectId, id);
52
- if (s) {
53
- sessions.push(s);
54
- }
55
- }
56
- sessions.sort((a, b) => b.lastSavedAt.localeCompare(a.lastSavedAt));
57
- return sessions;
58
- }
59
- /** Get the most recent session for a project. */
60
- export async function getLatest(projectId) {
61
- const all = await list(projectId);
62
- return all[0] ?? null;
63
- }
64
- /** Delete a session by ID. Returns true if removed. */
65
- export async function deleteSession(projectId, sessionId) {
66
- try {
67
- await unlink(sessionFile(projectId, sessionId));
68
- return true;
69
- }
70
- catch (error) {
71
- if (error.code === 'ENOENT' ||
72
- (error instanceof Error && error.message === 'ENOENT')) {
73
- return false;
74
- }
75
- throw error;
76
- }
77
- }
78
- /** List sessions as lightweight items for display. */
79
- export async function listItems(projectId, limit = 10) {
80
- const all = await list(projectId);
81
- return all.slice(0, limit).map((s) => ({
82
- id: s.id,
83
- startedAt: s.startedAt,
84
- lastSavedAt: s.lastSavedAt,
85
- contextSummary: s.contextSummary.slice(0, 200),
86
- toolCallCount: s.toolCallCount,
87
- }));
88
- }
89
- // --- cleanup (AC-10) ---
90
- const MAX_SESSIONS = 50;
91
- const MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
92
- /** Clean up old sessions: keep max 50, remove sessions older than 30 days. */
93
- export async function cleanup(projectId) {
94
- const all = await list(projectId);
95
- let removed = 0;
96
- const now = Date.now();
97
- // Remove sessions older than 30 days
98
- for (const s of all) {
99
- const age = now - new Date(s.lastSavedAt).getTime();
100
- if (age > MAX_AGE_MS) {
101
- await deleteSession(projectId, s.id);
102
- removed++;
103
- }
104
- }
105
- // Remove excess beyond MAX_SESSIONS (oldest first, list is already desc)
106
- const remaining = all.length - removed;
107
- if (remaining > MAX_SESSIONS) {
108
- const toRemove = all.slice(MAX_SESSIONS).filter((s) => {
109
- const age = now - new Date(s.lastSavedAt).getTime();
110
- return age <= MAX_AGE_MS; // not already removed above
111
- });
112
- for (const s of toRemove) {
113
- await deleteSession(projectId, s.id);
114
- removed++;
115
- }
116
- }
117
- if (removed > 0) {
118
- console.warn(`[Planu] Cleaned up ${String(removed)} old sessions for project ${projectId}`);
119
- }
120
- return removed;
121
- }
122
- // --- session memory (AC-11) ---
123
- /** Load cross-conversation memory for a project. */
124
- export async function loadMemory(projectId) {
125
- return readJson(memoryFile(projectId), {
126
- projectId,
127
- decisions: [],
128
- updatedAt: new Date().toISOString(),
129
- });
130
- }
131
- /** Save cross-conversation memory. */
132
- export async function saveMemory(memory) {
133
- const file = memoryFile(memory.projectId);
134
- await withFileLock(file, () => writeJson(file, memory));
135
- }
136
- //# sourceMappingURL=session-store.js.map
@@ -1,6 +0,0 @@
1
- import type { ActivateLicenseInput, ToolResult } from '../types/index.js';
2
- export declare function handleActivateLicense(args: ActivateLicenseInput): Promise<ToolResult>;
3
- export declare function handleDeactivateLicense(args: {
4
- confirm: boolean;
5
- }): Promise<ToolResult>;
6
- //# sourceMappingURL=activate-license.d.ts.map
@@ -1,132 +0,0 @@
1
- // tools/activate-license.ts — Handler for activate_license MCP tool.
2
- // Activates a license key via Lemon Squeezy API and persists the state locally.
3
- import { hostname, platform, userInfo } from 'node:os';
4
- import { basename } from 'node:path';
5
- import { licenseStore } from '../storage/index.js';
6
- import { activateLicense, computeMachineFingerprint, deactivateLicense, loadLicensePlans, variantToTier, } from '../engine/license-validator.js';
7
- import { invalidateTierCache } from './license-gate.js';
8
- import { t, ti } from '../i18n/index.js';
9
- function buildInstanceName() {
10
- const host = hostname();
11
- const user = userInfo().username;
12
- const os = platform();
13
- const project = basename(process.cwd());
14
- return `planu-${host} Ā· ${user}@${os} Ā· ${project}`;
15
- }
16
- export async function handleActivateLicense(args) {
17
- const { licenseKey, instanceName } = args;
18
- if (!licenseKey || licenseKey.trim().length === 0) {
19
- return {
20
- content: [{ type: 'text', text: t('tools.activate_license.keyRequired') }],
21
- isError: true,
22
- };
23
- }
24
- const name = instanceName ?? buildInstanceName();
25
- try {
26
- const response = await activateLicense(licenseKey.trim(), name);
27
- if (!response.activated) {
28
- return {
29
- content: [
30
- {
31
- type: 'text',
32
- text: ti('tools.activate_license.activationFailed', {
33
- error: response.error ?? 'Unknown error',
34
- }),
35
- },
36
- ],
37
- isError: true,
38
- };
39
- }
40
- const tier = variantToTier(response.meta.variant_name);
41
- const now = new Date().toISOString();
42
- const state = {
43
- licenseKey: response.license_key.key,
44
- instanceId: response.instance.id,
45
- tier,
46
- activatedAt: now,
47
- lastValidatedAt: now,
48
- variantName: response.meta.variant_name,
49
- customerName: response.meta.customer_name,
50
- customerEmail: response.meta.customer_email,
51
- machineFingerprint: computeMachineFingerprint(),
52
- activationLimit: response.license_key.activation_limit,
53
- activationUsage: response.license_key.activation_usage,
54
- };
55
- await licenseStore.saveLicenseState(state);
56
- invalidateTierCache();
57
- const tierLabel = tier.charAt(0).toUpperCase() + tier.slice(1);
58
- return {
59
- content: [
60
- {
61
- type: 'text',
62
- text: [
63
- `āœ… ${t('tools.activate_license.activatedSuccess')}`,
64
- '',
65
- ti('tools.activate_license.plan', { tier: tierLabel }),
66
- ti('tools.activate_license.customer', { name: response.meta.customer_name }),
67
- ti('tools.activate_license.instance', { name }),
68
- '',
69
- tier === 'pro'
70
- ? t('tools.activate_license.proAccess')
71
- : ti('tools.activate_license.tierAccess', { tier }),
72
- ].join('\n'),
73
- },
74
- ],
75
- };
76
- }
77
- catch (error) {
78
- const message = error instanceof Error ? error.message : String(error);
79
- return {
80
- content: [
81
- {
82
- type: 'text',
83
- text: [
84
- ti('tools.activate_license.activationFailed', { error: message }),
85
- '',
86
- t('tools.activate_license.commonCauses'),
87
- `• ${t('tools.activate_license.causeInvalidKey')}`,
88
- `• ${t('tools.activate_license.causeAlreadyActivated')}`,
89
- `• ${t('tools.activate_license.causeNetwork')}`,
90
- ].join('\n'),
91
- },
92
- ],
93
- isError: true,
94
- };
95
- }
96
- }
97
- export async function handleDeactivateLicense(args) {
98
- if (!args.confirm) {
99
- return {
100
- content: [{ type: 'text', text: t('tools.activate_license.deactivationCancelled') }],
101
- };
102
- }
103
- const state = await licenseStore.getLicenseState();
104
- if (!state) {
105
- return {
106
- content: [{ type: 'text', text: t('tools.activate_license.noActiveLicense') }],
107
- };
108
- }
109
- try {
110
- await deactivateLicense(state.licenseKey, state.instanceId);
111
- }
112
- catch {
113
- // Even if remote deactivation fails, we clear local state
114
- }
115
- await licenseStore.deleteLicenseState();
116
- invalidateTierCache();
117
- return {
118
- content: [
119
- {
120
- type: 'text',
121
- text: [
122
- `āœ… ${t('tools.activate_license.deactivatedSuccess')}`,
123
- ti('tools.activate_license.deactivatedFreePlan', {
124
- count: String(loadLicensePlans().freeTools.length),
125
- }),
126
- t('tools.activate_license.keyReusable'),
127
- ].join('\n'),
128
- },
129
- ],
130
- };
131
- }
132
- //# sourceMappingURL=activate-license.js.map
@@ -1,3 +0,0 @@
1
- import type { ToolResult, SessionCheckpointInput } from '../types/index.js';
2
- export declare function handleSessionCheckpoint(args: SessionCheckpointInput): Promise<ToolResult>;
3
- //# sourceMappingURL=checkpoint-handler.d.ts.map
@@ -1,130 +0,0 @@
1
- // tools/checkpoint-handler.ts — Handler for session_checkpoint tool (SPEC-220).
2
- import { execFileSync } from 'node:child_process';
3
- import { saveSessionState, getStagedFiles, getActiveSpecIds, } from '../storage/session-state-store.js';
4
- import { hashProjectPath } from '../storage/base-store.js';
5
- import { listSpecs } from '../storage/spec-store.js';
6
- // ---------------------------------------------------------------------------
7
- // Internal helpers
8
- // ---------------------------------------------------------------------------
9
- const SEPARATOR = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━';
10
- function formatList(items) {
11
- if (items.length === 0) {
12
- return '(none)';
13
- }
14
- return items.map((i) => `- ${i}`).join('\n');
15
- }
16
- function buildHandoffBlock(savedAt, activeSpecs, decisions, nextSteps, stagedFiles) {
17
- const lines = [
18
- `Saved: ${savedAt}`,
19
- '',
20
- `Active specs: ${activeSpecs.length > 0 ? activeSpecs.join(', ') : '(none)'}`,
21
- '',
22
- 'Decisions:',
23
- formatList(decisions),
24
- '',
25
- 'Next steps:',
26
- formatList(nextSteps),
27
- '',
28
- `Staged files: ${stagedFiles.length > 0 ? stagedFiles.join(', ') : '(none)'}`,
29
- ];
30
- return lines.join('\n');
31
- }
32
- async function resolveActiveSpecs(projectPath, projectId) {
33
- // Try spec store first (in-progress specs)
34
- try {
35
- const resolvedId = projectId !== '' ? projectId : hashProjectPath(projectPath);
36
- const specs = await listSpecs(resolvedId);
37
- const inProgress = specs
38
- .filter((s) => s.status === 'implementing')
39
- .map((s) => `${s.id} (${s.status})`);
40
- if (inProgress.length > 0) {
41
- return inProgress;
42
- }
43
- }
44
- catch {
45
- // Fallback to filesystem scan
46
- }
47
- return getActiveSpecIds(projectPath);
48
- }
49
- // ---------------------------------------------------------------------------
50
- // Pending HTML changes notification (SPEC-326)
51
- // ---------------------------------------------------------------------------
52
- function checkPlanuUncommittedChanges(projectPath) {
53
- try {
54
- const output = execFileSync('git', ['status', '--porcelain', 'planu/'], {
55
- cwd: projectPath,
56
- encoding: 'utf-8',
57
- timeout: 5_000,
58
- stdio: ['pipe', 'pipe', 'pipe'],
59
- });
60
- return output.trim().length > 0;
61
- }
62
- catch {
63
- return false;
64
- }
65
- }
66
- // ---------------------------------------------------------------------------
67
- // Worktree teardown recommendation (SPEC-279)
68
- // ---------------------------------------------------------------------------
69
- function buildWorktreeTeardownRecommendation(activeSpecs) {
70
- const specNames = activeSpecs.map((s) => s.replace(/ \(implementing\)$/, '')).join(', ');
71
- return {
72
- type: 'worktree-teardown',
73
- message: `Parallel sprint detected — ${String(activeSpecs.length)} specs in progress (${specNames}). Run these steps to close the sprint safely:`,
74
- steps: [
75
- 'For each worktree: bash scripts/auto-merge.sh (full pipeline + merge to develop)',
76
- 'bash scripts/prune-worktrees.sh (clean up merged/orphan worktrees)',
77
- 'pnpm test:coverage (verify thresholds before promoting to main)',
78
- 'git checkout main && git merge --ff-only develop && git push origin main',
79
- ],
80
- };
81
- }
82
- // ---------------------------------------------------------------------------
83
- // Handler
84
- // ---------------------------------------------------------------------------
85
- export async function handleSessionCheckpoint(args) {
86
- const { projectPath, projectId, decisions = [], nextSteps = [] } = args;
87
- const savedAt = new Date().toISOString();
88
- const stagedFiles = getStagedFiles(projectPath);
89
- const activeSpecs = await resolveActiveSpecs(projectPath, projectId);
90
- await saveSessionState(projectPath, {
91
- savedAt,
92
- activeSpecs,
93
- recentDecisions: decisions.slice(0, 5),
94
- stagedFiles,
95
- nextSteps,
96
- });
97
- const handoff = buildHandoffBlock(savedAt, activeSpecs, decisions, nextSteps, stagedFiles);
98
- // SPEC-256: always include /btw tip in checkpoint recommendations
99
- const recommendations = [
100
- {
101
- type: 'context-tip',
102
- message: 'Use /btw for side questions during implementation — keeps context clean for the task. Example: /btw what does useEffect cleanup do?',
103
- command: '/btw your question here',
104
- },
105
- ];
106
- // SPEC-279: emit worktree teardown instructions when a parallel sprint is detected
107
- if (activeSpecs.length >= 2) {
108
- recommendations.push(buildWorktreeTeardownRecommendation(activeSpecs));
109
- }
110
- // SPEC-326: Pending HTML changes notification
111
- const planuChanges = checkPlanuUncommittedChanges(projectPath);
112
- const planuReminder = planuChanges
113
- ? '\n\nšŸ“ Spec changes pending — commit to save: `git add planu/specs/ planu/conventions.json && git commit -m "chore(planu): save spec updates"`'
114
- : '';
115
- const text = [
116
- `Session checkpoint saved — ${savedAt}`,
117
- '',
118
- 'Session Handoff Block (paste in new session):',
119
- SEPARATOR,
120
- handoff,
121
- SEPARATOR,
122
- ].join('\n') + planuReminder;
123
- return {
124
- content: [{ type: 'text', text }],
125
- structuredContent: {
126
- recommendations,
127
- },
128
- };
129
- }
130
- //# sourceMappingURL=checkpoint-handler.js.map
@@ -1,3 +0,0 @@
1
- import type { ToolResult, ExportSessionInput } from '../types/index.js';
2
- export declare function handleExportSession(params: ExportSessionInput): Promise<ToolResult>;
3
- //# sourceMappingURL=export-session.d.ts.map
@@ -1,90 +0,0 @@
1
- import { hashProjectPath } from '../storage/base-store.js';
2
- import * as sessionStore from '../storage/session-store.js';
3
- function formatAsMarkdown(session) {
4
- const lines = [];
5
- lines.push(`# Session Export: ${session.id}`);
6
- lines.push('');
7
- lines.push(`## Summary`);
8
- lines.push(`- **Project**: ${session.projectId}`);
9
- lines.push(`- **Started**: ${session.startedAt}`);
10
- lines.push(`- **Last Saved**: ${session.lastSavedAt}`);
11
- lines.push(`- **Tool Calls**: ${String(session.toolCallCount)}`);
12
- lines.push('');
13
- if (session.activeSpecs.length > 0) {
14
- lines.push('## Active Specs');
15
- for (const spec of session.activeSpecs) {
16
- lines.push(`- **${spec.specId}** (${spec.status}): ${spec.summary}`);
17
- }
18
- lines.push('');
19
- }
20
- if (session.decisions.length > 0) {
21
- lines.push('## Decisions');
22
- for (const d of session.decisions) {
23
- const specRef = d.specId ? ` [${d.specId}]` : '';
24
- lines.push(`- **${d.decision}**${specRef}`);
25
- if (d.rationale) {
26
- lines.push(` - _${d.rationale}_`);
27
- }
28
- }
29
- lines.push('');
30
- }
31
- if (session.modifiedFiles.length > 0) {
32
- lines.push('## Modified Files');
33
- for (const f of session.modifiedFiles) {
34
- lines.push(`- \`${f.path}\` (${f.action})`);
35
- }
36
- lines.push('');
37
- }
38
- if (Object.keys(session.metadata).length > 0) {
39
- lines.push('## Metadata');
40
- lines.push('```json');
41
- lines.push(JSON.stringify(session.metadata, null, 2));
42
- lines.push('```');
43
- }
44
- return lines.join('\n');
45
- }
46
- export async function handleExportSession(params) {
47
- const projectId = hashProjectPath(params.projectPath);
48
- const format = params.format ?? 'markdown';
49
- try {
50
- let session;
51
- if (params.sessionId) {
52
- session = await sessionStore.load(projectId, params.sessionId);
53
- }
54
- else {
55
- session = await sessionStore.getLatest(projectId);
56
- }
57
- if (!session) {
58
- return {
59
- content: [{ type: 'text', text: 'No sessions found for this project.' }],
60
- };
61
- }
62
- if (format === 'json') {
63
- const summary = [
64
- `āœ… **Session exported:** ${session.id}`,
65
- '',
66
- `**Project:** ${session.projectId}`,
67
- `**Started:** ${session.startedAt}`,
68
- `**Tool Calls:** ${String(session.toolCallCount)}`,
69
- `**Active Specs:** ${String(session.activeSpecs.length)}`,
70
- `**Decisions:** ${String(session.decisions.length)}`,
71
- `**Modified Files:** ${String(session.modifiedFiles.length)}`,
72
- ].join('\n');
73
- return {
74
- content: [{ type: 'text', text: summary }],
75
- structuredContent: session,
76
- };
77
- }
78
- return {
79
- content: [{ type: 'text', text: formatAsMarkdown(session) }],
80
- };
81
- }
82
- catch (error) {
83
- const message = error instanceof Error ? error.message : String(error);
84
- return {
85
- content: [{ type: 'text', text: `Error exporting session: ${message}` }],
86
- isError: true,
87
- };
88
- }
89
- }
90
- //# sourceMappingURL=export-session.js.map
@@ -1,18 +0,0 @@
1
- import type { PricingTier, ToolResult } from '../types/index.js';
2
- export declare function getCurrentTier(): Promise<PricingTier>;
3
- export declare function invalidateTierCache(): void;
4
- /**
5
- * Synchronous tier estimate based on environment variables only — no disk I/O.
6
- * Used at server startup to set the display name before async validation runs.
7
- * Returns 'enterprise' for owner token, 'pro' if a license key env var is set, 'free' otherwise.
8
- */
9
- export declare function getTierSync(): PricingTier;
10
- export declare function shouldBypassDailyRateLimit(toolName: string): boolean;
11
- export declare function withLicenseGate<T>(toolName: string, handler: (args: T, extra?: unknown) => Promise<ToolResult>): (args: T, extra?: unknown) => Promise<ToolResult>;
12
- /**
13
- * Wraps a handler with rate limiting (free tier only) and usage event recording.
14
- * For free tier: checks daily limit + cooldown before executing.
15
- * For all tiers: records a usage event after execution (fire-and-forget).
16
- */
17
- export declare function withUsageTracking<T>(toolName: string, handler: (args: T, extra?: unknown) => Promise<ToolResult>): (args: T, extra?: unknown) => Promise<ToolResult>;
18
- //# sourceMappingURL=license-gate.d.ts.map