peaks-loop 4.0.0-beta.9 → 4.0.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 (552) hide show
  1. package/CHANGELOG.md +910 -141
  2. package/README-en.md +26 -7
  3. package/README.md +75 -6
  4. package/agents/karpathy-reviewer.md +33 -0
  5. package/bin/peaks.js +0 -0
  6. package/dist/cli/cli-helpers.d.ts +31 -6
  7. package/dist/cli/cli-helpers.js +48 -25
  8. package/dist/cli/commands/_register.d.ts +3 -0
  9. package/dist/cli/commands/_register.js +139 -0
  10. package/dist/cli/commands/_super.d.ts +10 -0
  11. package/dist/cli/commands/_super.js +97 -0
  12. package/dist/cli/commands/adapter-commands-s2a.js +1 -1
  13. package/dist/cli/commands/asset-commands.js +33 -16
  14. package/dist/cli/commands/audit-commands.js +2 -2
  15. package/dist/cli/commands/autonomous-swarm-commands.d.ts +12 -0
  16. package/dist/cli/commands/autonomous-swarm-commands.js +120 -0
  17. package/dist/cli/commands/bee-commands.js +1 -1
  18. package/dist/cli/commands/capability-commands.js +1 -1
  19. package/dist/cli/commands/capability-worker-config-sc-commands.js +0 -2
  20. package/dist/cli/commands/changeset-commands.d.ts +13 -0
  21. package/dist/cli/commands/changeset-commands.js +46 -0
  22. package/dist/cli/commands/code-commands.d.ts +11 -1
  23. package/dist/cli/commands/code-commands.js +19 -699
  24. package/dist/cli/commands/code-job-shape-commands.d.ts +9 -0
  25. package/dist/cli/commands/code-job-shape-commands.js +164 -0
  26. package/dist/cli/commands/code-mode-gate-commands.d.ts +9 -0
  27. package/dist/cli/commands/code-mode-gate-commands.js +223 -0
  28. package/dist/cli/commands/code-review-commands.js +2 -2
  29. package/dist/cli/commands/code-run-command.d.ts +12 -0
  30. package/dist/cli/commands/code-run-command.js +68 -0
  31. package/dist/cli/commands/code-runtime-commands.d.ts +11 -0
  32. package/dist/cli/commands/code-runtime-commands.js +391 -0
  33. package/dist/cli/commands/codegraph-commands.js +1 -1
  34. package/dist/cli/commands/compact-command.js +53 -1
  35. package/dist/cli/commands/complexity-commands.js +1 -1
  36. package/dist/cli/commands/config-commands.js +4 -75
  37. package/dist/cli/commands/container-commands.d.ts +28 -0
  38. package/dist/cli/commands/container-commands.js +221 -0
  39. package/dist/cli/commands/context-commands.js +3 -2
  40. package/dist/cli/commands/core/artifacts-command.js +1 -1
  41. package/dist/cli/commands/core/binding-commands.js +1 -1
  42. package/dist/cli/commands/core/doctor-command.js +63 -3
  43. package/dist/cli/commands/core/memory-command.js +1 -1
  44. package/dist/cli/commands/core/profile-command.js +1 -1
  45. package/dist/cli/commands/core/proxy-command.js +1 -1
  46. package/dist/cli/commands/core/session-command.js +9 -7
  47. package/dist/cli/commands/core/skill-command.js +7 -4
  48. package/dist/cli/commands/core/standards-command.js +1 -1
  49. package/dist/cli/commands/cron-commands.d.ts +57 -0
  50. package/dist/cli/commands/cron-commands.js +257 -0
  51. package/dist/cli/commands/cron-scheduler-commands.d.ts +47 -0
  52. package/dist/cli/commands/cron-scheduler-commands.js +284 -0
  53. package/dist/cli/commands/dashboard-commands.d.ts +4 -0
  54. package/dist/cli/commands/dashboard-commands.js +10 -0
  55. package/dist/cli/commands/dashboard-long-run.d.ts +25 -0
  56. package/dist/cli/commands/dashboard-long-run.js +122 -0
  57. package/dist/cli/commands/dashboard-summary.d.ts +12 -0
  58. package/dist/cli/commands/dashboard-summary.js +58 -0
  59. package/dist/cli/commands/dispatch-commands.d.ts +0 -7
  60. package/dist/cli/commands/dispatch-commands.js +372 -8
  61. package/dist/cli/commands/dispatch-from-dag.js +4 -1
  62. package/dist/cli/commands/doc-commands.js +1 -1
  63. package/dist/cli/commands/ecc-commands.d.ts +30 -0
  64. package/dist/cli/commands/ecc-commands.js +119 -0
  65. package/dist/cli/commands/evolution-commands.js +1 -1
  66. package/dist/cli/commands/feedback-commands.js +1 -1
  67. package/dist/cli/commands/final-review-commands.js +1 -1
  68. package/dist/cli/commands/fixture-commands.js +1 -1
  69. package/dist/cli/commands/fork-commands.js +1 -1
  70. package/dist/cli/commands/gate-commands.js +128 -6
  71. package/dist/cli/commands/governance-classify-contract-commands.d.ts +21 -0
  72. package/dist/cli/commands/governance-classify-contract-commands.js +273 -0
  73. package/dist/cli/commands/heartbeat-commands.js +76 -5
  74. package/dist/cli/commands/heartbeat-watch-command.d.ts +31 -0
  75. package/dist/cli/commands/heartbeat-watch-command.js +146 -0
  76. package/dist/cli/commands/hook-handle.js +1 -1
  77. package/dist/cli/commands/hooks-commands.js +126 -10
  78. package/dist/cli/commands/ide-commands.js +1 -1
  79. package/dist/cli/commands/impact-commands.js +1 -1
  80. package/dist/cli/commands/job-commands.js +34 -1
  81. package/dist/cli/commands/lease-metrics-commands.d.ts +67 -0
  82. package/dist/cli/commands/lease-metrics-commands.js +231 -0
  83. package/dist/cli/commands/lease-stats-commands.d.ts +65 -0
  84. package/dist/cli/commands/lease-stats-commands.js +107 -0
  85. package/dist/cli/commands/legacy-commands.js +1 -1
  86. package/dist/cli/commands/log-commands.js +1 -1
  87. package/dist/cli/commands/loop-commands.js +1 -1
  88. package/dist/cli/commands/loop-eval-commands.js +1 -1
  89. package/dist/cli/commands/memory-commands.js +1 -1
  90. package/dist/cli/commands/migrate-1-4-1-command.js +1 -1
  91. package/dist/cli/commands/migrate-v2-10-to-v2-11-command.js +1 -1
  92. package/dist/cli/commands/mut-commands.d.ts +1 -1
  93. package/dist/cli/commands/mut-commands.js +1 -5
  94. package/dist/cli/commands/observability-commands.js +1 -1
  95. package/dist/cli/commands/openspec-commands.js +65 -4
  96. package/dist/cli/commands/perf-audit-commands.js +3 -3
  97. package/dist/cli/commands/perf-commands.js +1 -1
  98. package/dist/cli/commands/polyrepo-commands.js +1 -1
  99. package/dist/cli/commands/prd-blocks-commands.js +1 -1
  100. package/dist/cli/commands/prd-commands.js +4 -2
  101. package/dist/cli/commands/preferences-commands.js +23 -3
  102. package/dist/cli/commands/project-commands.js +1 -1
  103. package/dist/cli/commands/qa-business-review-commands.js +1 -1
  104. package/dist/cli/commands/qa-commands.d.ts +1 -1
  105. package/dist/cli/commands/qa-commands.js +39 -3
  106. package/dist/cli/commands/release-commands.d.ts +15 -0
  107. package/dist/cli/commands/release-commands.js +113 -21
  108. package/dist/cli/commands/request-commands.js +1 -1
  109. package/dist/cli/commands/retrospective-commands.js +1 -1
  110. package/dist/cli/commands/reviewer-commands.js +1 -1
  111. package/dist/cli/commands/role-commands.js +1 -1
  112. package/dist/cli/commands/runtime-commands-helpers.d.ts +7 -0
  113. package/dist/cli/commands/runtime-commands-helpers.js +24 -0
  114. package/dist/cli/commands/runtime-commands.js +1 -2
  115. package/dist/cli/commands/sc-commands.js +4 -2
  116. package/dist/cli/commands/scan-commands.js +1 -1
  117. package/dist/cli/commands/security-audit-commands.js +3 -3
  118. package/dist/cli/commands/sediment-commands.js +10 -1
  119. package/dist/cli/commands/session-24h-mode.d.ts +26 -0
  120. package/dist/cli/commands/session-24h-mode.js +196 -0
  121. package/dist/cli/commands/share-commands.d.ts +19 -0
  122. package/dist/cli/commands/share-commands.js +121 -2
  123. package/dist/cli/commands/skill-conformance-commands.js +1 -1
  124. package/dist/cli/commands/skill-loop-engineering-readiness-commands.js +1 -1
  125. package/dist/cli/commands/skill-search-commands.js +4 -1
  126. package/dist/cli/commands/slice-commands.js +1 -1
  127. package/dist/cli/commands/slice-integrate-commands.js +1 -1
  128. package/dist/cli/commands/slice-review-commands.js +1 -1
  129. package/dist/cli/commands/smoke-commands.js +1 -1
  130. package/dist/cli/commands/sop-commands.js +1 -1
  131. package/dist/cli/commands/spill-demo-command.d.ts +7 -0
  132. package/dist/cli/commands/spill-demo-command.js +29 -0
  133. package/dist/cli/commands/statusline-commands.d.ts +12 -0
  134. package/dist/cli/commands/statusline-commands.js +79 -17
  135. package/dist/cli/commands/sub-agent-commands.js +2 -1
  136. package/dist/cli/commands/sub-agent-shared.d.ts +10 -0
  137. package/dist/cli/commands/sub-agent-shared.js +24 -1
  138. package/dist/cli/commands/swarm-commands.d.ts +13 -0
  139. package/dist/cli/commands/swarm-commands.js +77 -0
  140. package/dist/cli/commands/tech-commands.d.ts +64 -0
  141. package/dist/cli/commands/tech-commands.js +195 -0
  142. package/dist/cli/commands/understand-commands.js +1 -1
  143. package/dist/cli/commands/upgrade-commands.d.ts +2 -0
  144. package/dist/cli/commands/upgrade-commands.js +40 -5
  145. package/dist/cli/commands/user-touchpoint-commands.js +1 -1
  146. package/dist/cli/commands/verdict-aggregate-command.js +1 -1
  147. package/dist/cli/commands/vm-commands.d.ts +31 -0
  148. package/dist/cli/commands/vm-commands.js +274 -0
  149. package/dist/cli/commands/workflow-commands.js +24 -1
  150. package/dist/cli/commands/workflow-plan-commands.js +1 -1
  151. package/dist/cli/commands/workspace/init-command.js +1 -1
  152. package/dist/cli/commands/workspace/migrate-command.js +1 -1
  153. package/dist/cli/commands/workspace/reconcile-command.js +1 -1
  154. package/dist/cli/commands/worktree-auth-commands.d.ts +29 -0
  155. package/dist/cli/commands/worktree-auth-commands.js +652 -0
  156. package/dist/cli/index.js +58 -13
  157. package/dist/cli/program.d.ts +2 -2
  158. package/dist/cli/program.js +86 -281
  159. package/dist/services/24h-mode/decider.d.ts +103 -0
  160. package/dist/services/24h-mode/decider.js +144 -0
  161. package/dist/services/24h-mode/index.d.ts +12 -0
  162. package/dist/services/24h-mode/index.js +12 -0
  163. package/dist/services/24h-mode/state.d.ts +48 -0
  164. package/dist/services/24h-mode/state.js +51 -0
  165. package/dist/services/24h-mode/store.d.ts +27 -0
  166. package/dist/services/24h-mode/store.js +119 -0
  167. package/dist/services/artifacts/artifact-prerequisites.js +1 -1
  168. package/dist/services/artifacts/request-artifact-service.js +1 -1
  169. package/dist/services/artifacts/workspace-service.js +1 -1
  170. package/dist/services/audit/enforcers/lint-bee-runtime-contract.d.ts +25 -0
  171. package/dist/services/audit/enforcers/lint-bee-runtime-contract.js +91 -0
  172. package/dist/services/audit/enforcers/lint-peaks-code-runtime.d.ts +16 -0
  173. package/dist/services/audit/enforcers/lint-peaks-code-runtime.js +31 -0
  174. package/dist/services/audit/enforcers/lint-peaks-skill-runtime.d.ts +23 -0
  175. package/dist/services/audit/enforcers/lint-peaks-skill-runtime.js +59 -0
  176. package/dist/services/audit/enforcers/lint-peaks-ui-sc-txt-runtime.d.ts +28 -0
  177. package/dist/services/audit/enforcers/lint-peaks-ui-sc-txt-runtime.js +86 -0
  178. package/dist/services/audit/enforcers/lint-prd-artifact-handoff.d.ts +16 -0
  179. package/dist/services/audit/enforcers/lint-prd-artifact-handoff.js +41 -0
  180. package/dist/services/audit/enforcers/lint-prd-source-snapshot.d.ts +27 -0
  181. package/dist/services/audit/enforcers/lint-prd-source-snapshot.js +47 -0
  182. package/dist/services/audit/enforcers/lint-qa-gateguard-and-runtime.d.ts +19 -0
  183. package/dist/services/audit/enforcers/lint-qa-gateguard-and-runtime.js +47 -0
  184. package/dist/services/audit/enforcers/lint-rd-handoff-coverage.d.ts +18 -0
  185. package/dist/services/audit/enforcers/lint-rd-handoff-coverage.js +70 -0
  186. package/dist/services/audit/enforcers/lint-skill-presence-mandatory.d.ts +25 -0
  187. package/dist/services/audit/enforcers/lint-skill-presence-mandatory.js +53 -0
  188. package/dist/services/audit/red-line-catalog-p2-a.d.ts +0 -6
  189. package/dist/services/audit/red-line-catalog-p2-a.js +230 -1
  190. package/dist/services/audit/static-service.d.ts +32 -25
  191. package/dist/services/audit/static-service.js +30 -109
  192. package/dist/services/audit-independent/index.d.ts +2 -0
  193. package/dist/services/audit-independent/index.js +2 -0
  194. package/dist/services/autonomous-swarm/autonomous-swarm-service.d.ts +127 -0
  195. package/dist/services/autonomous-swarm/autonomous-swarm-service.js +446 -0
  196. package/dist/services/changeset/changeset-check-service.d.ts +22 -0
  197. package/dist/services/changeset/changeset-check-service.js +47 -0
  198. package/dist/services/code/auto-compact-modes.d.ts +30 -0
  199. package/dist/services/code/auto-compact-modes.js +38 -0
  200. package/dist/services/code/auto-compact-orchestrator.d.ts +43 -5
  201. package/dist/services/code/auto-compact-orchestrator.js +101 -21
  202. package/dist/services/code/dag-orchestrator.d.ts +30 -1
  203. package/dist/services/code/dag-orchestrator.js +106 -1
  204. package/dist/services/code/status-line-renderer.d.ts +2 -0
  205. package/dist/services/code/status-line-renderer.js +21 -3
  206. package/dist/services/code-review/ocr-service.d.ts +1 -1
  207. package/dist/services/code-review/ocr-service.js +6 -3
  208. package/dist/services/compact-history/compact-history-service.d.ts +41 -0
  209. package/dist/services/compact-history/compact-history-service.js +62 -0
  210. package/dist/services/compact-statusline/compact-statusline-service.d.ts +16 -0
  211. package/dist/services/compact-statusline/compact-statusline-service.js +83 -0
  212. package/dist/services/config/config-service.d.ts +1 -12
  213. package/dist/services/config/config-service.js +3 -72
  214. package/dist/services/config/config-types.d.ts +2 -4
  215. package/dist/services/config/config-types.js +1 -1
  216. package/dist/services/container/container-lease.d.ts +67 -0
  217. package/dist/services/container/container-lease.js +135 -0
  218. package/dist/services/context/auto-compact-dispatcher.d.ts +40 -5
  219. package/dist/services/context/auto-compact-dispatcher.js +32 -102
  220. package/dist/services/context/auto-compact-reader.js +1 -1
  221. package/dist/services/context/auto-compact-types.d.ts +27 -2
  222. package/dist/services/context/auto-compact-types.js +8 -1
  223. package/dist/services/context/build-dispatch-system-prompt.d.ts +75 -0
  224. package/dist/services/context/build-dispatch-system-prompt.js +117 -0
  225. package/dist/services/context/collector.d.ts +2 -2
  226. package/dist/services/context/context-builder.d.ts +4 -4
  227. package/dist/services/context/context-schema.d.ts +48 -48
  228. package/dist/services/context/ide-detect.d.ts +4 -0
  229. package/dist/services/context/ide-detect.js +24 -0
  230. package/dist/services/context/main-session-monitor.d.ts +1 -4
  231. package/dist/services/context/main-session-monitor.js +1 -24
  232. package/dist/services/context/memory-index-reader.d.ts +8 -0
  233. package/dist/services/context/memory-index-reader.js +57 -0
  234. package/dist/services/context/memory-lru-cache.d.ts +12 -0
  235. package/dist/services/context/memory-lru-cache.js +60 -0
  236. package/dist/services/context/memory-preflight-config.d.ts +19 -0
  237. package/dist/services/context/memory-preflight-config.js +25 -0
  238. package/dist/services/context/memory-preflight-service.d.ts +19 -0
  239. package/dist/services/context/memory-preflight-service.js +120 -0
  240. package/dist/services/context/spillover-store.d.ts +23 -0
  241. package/dist/services/context/spillover-store.js +155 -0
  242. package/dist/services/context/spillover-types.d.ts +18 -0
  243. package/dist/services/context/spillover-types.js +1 -0
  244. package/dist/services/crystallization/crystallization-service.d.ts +22 -5
  245. package/dist/services/crystallization/crystallization-service.js +8 -14
  246. package/dist/services/crystallization/crystallization-types.d.ts +6 -6
  247. package/dist/services/crystallization/evidence-brief-builder.d.ts +1 -1
  248. package/dist/services/crystallization/index.d.ts +13 -0
  249. package/dist/services/crystallization/index.js +13 -0
  250. package/dist/services/dashboard/project-dashboard-service.js +2 -2
  251. package/dist/services/dispatch/await-batch.d.ts +70 -0
  252. package/dist/services/dispatch/await-batch.js +272 -0
  253. package/dist/services/dispatch/batch-counter.js +1 -1
  254. package/dist/services/dispatch/dispatch-record-writer.d.ts +126 -4
  255. package/dist/services/dispatch/dispatch-record-writer.js +239 -9
  256. package/dist/services/dispatch/slice-dag.d.ts +46 -0
  257. package/dist/services/dispatch/slice-dag.js +6 -0
  258. package/dist/services/dispatch/stage-enum.d.ts +27 -0
  259. package/dist/services/dispatch/stage-enum.js +48 -0
  260. package/dist/services/dispatch/startup-timeout.d.ts +86 -0
  261. package/dist/services/dispatch/startup-timeout.js +97 -0
  262. package/dist/services/dispatch/sub-agent-dispatcher.js +40 -89
  263. package/dist/services/dispatch/test-tool-detection.d.ts +25 -1
  264. package/dist/services/dispatch/test-tool-detection.js +80 -0
  265. package/dist/services/doctor/doctor-service/checks/check-id-schema.d.ts +18 -0
  266. package/dist/services/doctor/doctor-service/checks/check-id-schema.js +64 -0
  267. package/dist/services/doctor/doctor-service/checks/codegraph-capability.d.ts +14 -0
  268. package/dist/services/doctor/doctor-service/checks/codegraph-capability.js +69 -0
  269. package/dist/services/doctor/doctor-service/checks/dist-source-version.d.ts +32 -0
  270. package/dist/services/doctor/doctor-service/checks/dist-source-version.js +110 -0
  271. package/dist/services/doctor/doctor-service/checks/gateguard-conflict.d.ts +24 -0
  272. package/dist/services/doctor/doctor-service/checks/gateguard-conflict.js +164 -0
  273. package/dist/services/doctor/doctor-service/checks/l3-memory-health.d.ts +16 -0
  274. package/dist/services/doctor/doctor-service/checks/l3-memory-health.js +57 -0
  275. package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.d.ts +19 -0
  276. package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.js +66 -0
  277. package/dist/services/doctor/doctor-service/checks/schema-validity.d.ts +10 -0
  278. package/dist/services/doctor/doctor-service/checks/schema-validity.js +33 -0
  279. package/dist/services/doctor/doctor-service/checks/skill-apply-note.d.ts +20 -0
  280. package/dist/services/doctor/doctor-service/checks/skill-apply-note.js +85 -0
  281. package/dist/services/doctor/doctor-service/checks/skill-existence.d.ts +13 -0
  282. package/dist/services/doctor/doctor-service/checks/skill-existence.js +30 -0
  283. package/dist/services/doctor/doctor-service/checks/skill-name-match.d.ts +10 -0
  284. package/dist/services/doctor/doctor-service/checks/skill-name-match.js +25 -0
  285. package/dist/services/doctor/doctor-service/checks/skill-parse.d.ts +10 -0
  286. package/dist/services/doctor/doctor-service/checks/skill-parse.js +19 -0
  287. package/dist/services/doctor/doctor-service/checks/skill-presence.d.ts +21 -0
  288. package/dist/services/doctor/doctor-service/checks/skill-presence.js +75 -0
  289. package/dist/services/doctor/doctor-service/checks/skill-runbook.d.ts +14 -0
  290. package/dist/services/doctor/doctor-service/checks/skill-runbook.js +47 -0
  291. package/dist/services/doctor/doctor-service/checks/statusline-install.d.ts +14 -0
  292. package/dist/services/doctor/doctor-service/checks/statusline-install.js +32 -0
  293. package/dist/services/doctor/doctor-service/checks/statusline-runtime.d.ts +13 -0
  294. package/dist/services/doctor/doctor-service/checks/statusline-runtime.js +30 -0
  295. package/dist/services/doctor/doctor-service/checks/user-config.d.ts +11 -0
  296. package/dist/services/doctor/doctor-service/checks/user-config.js +27 -0
  297. package/dist/services/doctor/doctor-service/checks/workspace-init.d.ts +16 -0
  298. package/dist/services/doctor/doctor-service/checks/workspace-init.js +34 -0
  299. package/dist/services/doctor/doctor-service/checks/workspace-layout.d.ts +33 -0
  300. package/dist/services/doctor/doctor-service/checks/workspace-layout.js +180 -0
  301. package/dist/services/doctor/doctor-service/index.d.ts +48 -0
  302. package/dist/services/doctor/doctor-service/index.js +254 -0
  303. package/dist/services/doctor/doctor-service/plugin-registry.d.ts +41 -0
  304. package/dist/services/doctor/doctor-service/plugin-registry.js +77 -0
  305. package/dist/services/doctor/doctor-service/report/final-summary.d.ts +20 -0
  306. package/dist/services/doctor/doctor-service/report/final-summary.js +29 -0
  307. package/dist/services/doctor/doctor-service/types.d.ts +245 -0
  308. package/dist/services/doctor/doctor-service/types.js +15 -0
  309. package/dist/services/doctor/doctor-service.d.ts +15 -146
  310. package/dist/services/doctor/doctor-service.js +22 -926
  311. package/dist/services/doctor/index.d.ts +22 -0
  312. package/dist/services/doctor/index.js +22 -0
  313. package/dist/services/env/shell-probe.d.ts +71 -0
  314. package/dist/services/env/shell-probe.js +161 -0
  315. package/dist/services/evolution/evolution-types.d.ts +39 -39
  316. package/dist/services/final-review/final-review-service.d.ts +11 -1
  317. package/dist/services/final-review/index.d.ts +2 -0
  318. package/dist/services/final-review/index.js +1 -0
  319. package/dist/services/hooks/auto-compact-hook-install.d.ts +4 -5
  320. package/dist/services/hooks/auto-compact-hook-install.js +4 -5
  321. package/dist/services/hooks/worktree-authorization-gate.d.ts +205 -0
  322. package/dist/services/hooks/worktree-authorization-gate.js +492 -0
  323. package/dist/services/ide/adapters/claude-code-adapter.js +2 -2
  324. package/dist/services/ide/adapters/qoder-adapter.d.ts +25 -0
  325. package/dist/services/ide/adapters/qoder-adapter.js +57 -0
  326. package/dist/services/ide/adapters/tongyi-lingma-adapter.d.ts +16 -0
  327. package/dist/services/ide/adapters/tongyi-lingma-adapter.js +45 -0
  328. package/dist/services/ide/ide-registry.js +6 -0
  329. package/dist/services/ide/ide-types.d.ts +1 -1
  330. package/dist/services/job/job-types.d.ts +56 -56
  331. package/dist/services/job-snapshot/index.d.ts +8 -0
  332. package/dist/services/job-snapshot/index.js +7 -0
  333. package/dist/services/{job/job-resource-snapshot.d.ts → job-snapshot/snapshot.d.ts} +1 -1
  334. package/dist/services/job-snapshot/types.d.ts +7 -0
  335. package/dist/services/job-snapshot/types.js +1 -0
  336. package/dist/services/karpathy-cost/karpathy-cost-check-service.d.ts +67 -0
  337. package/dist/services/karpathy-cost/karpathy-cost-check-service.js +108 -0
  338. package/dist/services/log/retention.d.ts +16 -0
  339. package/dist/services/log/retention.js +17 -0
  340. package/dist/services/loop/loop-bee-relation-types.d.ts +6 -6
  341. package/dist/services/loop/loop-release-types.d.ts +24 -24
  342. package/dist/services/loop/monotonic-runner.d.ts +17 -11
  343. package/dist/services/loop/monotonic-runner.js +118 -79
  344. package/dist/services/memory/project-memory-service/index/kind-dispatch.d.ts +8 -0
  345. package/dist/services/memory/project-memory-service/index/kind-dispatch.js +253 -0
  346. package/dist/services/memory/project-memory-service/index/ranking.d.ts +6 -0
  347. package/dist/services/memory/project-memory-service/index/ranking.js +171 -0
  348. package/dist/services/memory/project-memory-service/index/search.d.ts +34 -0
  349. package/dist/services/memory/project-memory-service/index/search.js +194 -0
  350. package/dist/services/memory/project-memory-service/index.d.ts +9 -0
  351. package/dist/services/memory/project-memory-service/index.js +24 -0
  352. package/dist/services/memory/project-memory-service/parsers/frontmatter.d.ts +9 -0
  353. package/dist/services/memory/project-memory-service/parsers/frontmatter.js +106 -0
  354. package/dist/services/memory/project-memory-service/parsers/markdown-pure.d.ts +7 -0
  355. package/dist/services/memory/project-memory-service/parsers/markdown-pure.js +96 -0
  356. package/dist/services/memory/project-memory-service/store/atomic-write.d.ts +5 -0
  357. package/dist/services/memory/project-memory-service/store/atomic-write.js +56 -0
  358. package/dist/services/memory/project-memory-service/store/paths.d.ts +8 -0
  359. package/dist/services/memory/project-memory-service/store/paths.js +116 -0
  360. package/dist/services/memory/project-memory-service/types.d.ts +128 -0
  361. package/dist/services/memory/project-memory-service/types.js +9 -0
  362. package/dist/services/memory/project-memory-service.d.ts +1 -167
  363. package/dist/services/memory/project-memory-service.js +19 -816
  364. package/dist/services/migrate-skill-name/schema.d.ts +2 -2
  365. package/dist/services/observability/aggregation.d.ts +27 -0
  366. package/dist/services/observability/aggregation.js +72 -0
  367. package/dist/services/observability/observability-service.d.ts +73 -7
  368. package/dist/services/observability/observability-service.js +87 -1
  369. package/dist/services/openspec/artifact-boundary.d.ts +138 -0
  370. package/dist/services/openspec/artifact-boundary.js +150 -0
  371. package/dist/services/openspec/coverage-evidence-reader.d.ts +191 -0
  372. package/dist/services/openspec/coverage-evidence-reader.js +386 -0
  373. package/dist/services/openspec/openspec-archive-service.d.ts +70 -0
  374. package/dist/services/openspec/openspec-archive-service.js +320 -8
  375. package/dist/services/openspec/openspec-bridge-service.js +1 -1
  376. package/dist/services/openspec/openspec-init-service.js +1 -1
  377. package/dist/services/openspec/openspec-propose-from-doctor-service.js +1 -1
  378. package/dist/services/openspec/openspec-render-service.js +7 -4
  379. package/dist/services/openspec/openspec-scan-service.js +1 -1
  380. package/dist/services/openspec/openspec-validate-service.js +5 -4
  381. package/dist/services/preferences/preferences-service.js +10 -0
  382. package/dist/services/preferences/preferences-types.d.ts +13 -0
  383. package/dist/services/preferences/preferences-types.js +11 -0
  384. package/dist/services/qa/screenshot-archive-service.d.ts +51 -0
  385. package/dist/services/qa/screenshot-archive-service.js +134 -0
  386. package/dist/services/rd/rd-service.js +10 -11
  387. package/dist/services/rd/types.d.ts +32 -32
  388. package/dist/services/rd-swarm/rd-swarm-service.d.ts +60 -0
  389. package/dist/services/rd-swarm/rd-swarm-service.js +93 -0
  390. package/dist/services/recommendations/capability-seed-items.js +0 -1
  391. package/dist/services/recommendations/capability-seed-mappings.js +0 -1
  392. package/dist/services/recommendations/capability-seed-sources.js +0 -1
  393. package/dist/services/release/version-precheck-service.d.ts +51 -0
  394. package/dist/services/release/version-precheck-service.js +257 -0
  395. package/dist/services/scan/acceptance-coverage-service.js +1 -1
  396. package/dist/services/scan/archetype-service.js +1 -1
  397. package/dist/services/scan/existing-system-service.js +1 -1
  398. package/dist/services/scan/libraries-service.js +1 -1
  399. package/dist/services/sediment/json-schema.d.ts +40 -40
  400. package/dist/services/share/bundle-types.d.ts +12 -12
  401. package/dist/services/share/run-state-contract.d.ts +2 -2
  402. package/dist/services/skill/skill-search-service.d.ts +12 -7
  403. package/dist/services/skill/skill-search-service.js +8 -4
  404. package/dist/services/skillhub/migrations/001-initial.sql +71 -0
  405. package/dist/services/skillhub/migrations/002-loop-release.sql +32 -0
  406. package/dist/services/skillhub/migrations/003-loop-bee-relation.sql +35 -0
  407. package/dist/services/skillhub/migrations/004-loop-bee-extension.sql +65 -0
  408. package/dist/services/skillhub/migrations/005-evolution-evaluation.sql +81 -0
  409. package/dist/services/skillhub/migrations/006-crystallization-event.sql +92 -0
  410. package/dist/services/skills/hooks-settings-service.d.ts +75 -0
  411. package/dist/services/skills/hooks-settings-service.js +230 -2
  412. package/dist/services/skills/skill-registry.d.ts +1 -0
  413. package/dist/services/skills/skill-registry.js +6 -4
  414. package/dist/services/skills/skill-runbook-service.js +1 -1
  415. package/dist/services/slice/slice-check-service.js +1 -1
  416. package/dist/services/standards/main-session-monitor-ban-hook.d.ts +14 -0
  417. package/dist/services/standards/main-session-monitor-ban-hook.js +19 -0
  418. package/dist/services/standards/missing-standards-detector.d.ts +25 -0
  419. package/dist/services/standards/missing-standards-detector.js +43 -12
  420. package/dist/services/tech/tech-change-id-service.d.ts +82 -0
  421. package/dist/services/tech/tech-change-id-service.js +117 -0
  422. package/dist/services/understand/understand-hybrid-service.js +1 -1
  423. package/dist/services/understand/understand-scan-service.js +2 -2
  424. package/dist/services/upgrade/upgrade-service.js +4 -3
  425. package/dist/services/verdict/envelopes.d.ts +2 -2
  426. package/dist/services/verdict/envelopes.js +2 -2
  427. package/dist/services/verdict/verdict-aggregator.d.ts +3 -3
  428. package/dist/services/vm/vm-lease.d.ts +40 -0
  429. package/dist/services/vm/vm-lease.js +137 -0
  430. package/dist/services/workflow/autonomous-resume-writer.js +1 -1
  431. package/dist/services/workflow/pipeline-verify-gate-support.d.ts +47 -0
  432. package/dist/services/workflow/pipeline-verify-gate-support.js +194 -0
  433. package/dist/services/workflow/pipeline-verify-service.d.ts +17 -81
  434. package/dist/services/workflow/pipeline-verify-service.js +42 -218
  435. package/dist/services/workflow/pipeline-verify-types.d.ts +90 -0
  436. package/dist/services/workflow/pipeline-verify-types.js +10 -0
  437. package/dist/services/workflow/plan-reader.d.ts +1 -1
  438. package/dist/services/workflow/plan-reader.js +1 -1
  439. package/dist/services/workflow/plan-refresher.d.ts +1 -1
  440. package/dist/services/workflow/plan-refresher.js +1 -1
  441. package/dist/services/workflow/plan-trigger-detector.d.ts +1 -1
  442. package/dist/services/workflow/plan-trigger-detector.js +1 -1
  443. package/dist/services/workflow/workflow-autonomous-resume-helpers.d.ts +1 -1
  444. package/dist/services/workflow/workflow-autonomous-service.d.ts +2 -98
  445. package/dist/services/workflow/workflow-autonomous-types.d.ts +114 -0
  446. package/dist/services/workflow/workflow-autonomous-types.js +21 -0
  447. package/dist/services/workflow/workflow-router-service.js +18 -16
  448. package/dist/services/workflow/workflow-spec-lint.d.ts +13 -0
  449. package/dist/services/workflow/workflow-spec-lint.js +75 -0
  450. package/dist/services/workflow/workflow-spec-types.d.ts +100 -0
  451. package/dist/services/workflow/workflow-spec-types.js +13 -0
  452. package/dist/services/workflow/workflow-spec-yaml.d.ts +17 -0
  453. package/dist/services/workflow/workflow-spec-yaml.js +88 -0
  454. package/dist/services/workflow/workflow-spec.d.ts +11 -91
  455. package/dist/services/workflow/workflow-spec.js +16 -145
  456. package/dist/services/workspace/migrate-service.js +1 -1
  457. package/dist/services/workspace/workspace-service.js +1 -1
  458. package/dist/services/worktree/worktree-lease.d.ts +170 -0
  459. package/dist/services/worktree/worktree-lease.js +242 -0
  460. package/package.json +47 -51
  461. package/scripts/clean-dist.mjs +31 -1
  462. package/scripts/copy-templates.mjs +16 -0
  463. package/scripts/sync-version.mjs +53 -2
  464. package/skills/bee/peaks-perf-audit/SKILL.md +17 -0
  465. package/skills/bee/peaks-prd/SKILL.md +16 -0
  466. package/skills/bee/peaks-prd/test-prompts.json +12 -0
  467. package/skills/bee/peaks-qa/SKILL.md +16 -1
  468. package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +22 -0
  469. package/skills/bee/peaks-qa/test-prompts.json +12 -0
  470. package/skills/bee/peaks-rd/SKILL.md +29 -20
  471. package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +39 -0
  472. package/skills/bee/peaks-rd/test-prompts.json +12 -0
  473. package/skills/bee/peaks-reviewer/SKILL.md +17 -0
  474. package/skills/bee/peaks-sc/SKILL.md +16 -0
  475. package/skills/bee/peaks-security-audit/SKILL.md +17 -0
  476. package/skills/bee/peaks-txt/SKILL.md +16 -0
  477. package/skills/bee/peaks-txt/test-prompts.json +12 -0
  478. package/skills/bee/peaks-ui/SKILL.md +49 -43
  479. package/skills/bee/peaks-ui/test-prompts.json +12 -0
  480. package/skills/peaks-code/SKILL.md +54 -109
  481. package/skills/peaks-code/references/boundaries.md +15 -1
  482. package/skills/peaks-code/references/cron-scheduler-deployment.md +313 -0
  483. package/skills/peaks-code/references/external-skill-invocation.md +27 -0
  484. package/skills/peaks-code/references/lease-dashboard.html +224 -0
  485. package/skills/peaks-code/references/lease-stats.sample.json +26 -0
  486. package/skills/peaks-code/references/peaks-worktree-l2-enforcers.md +208 -0
  487. package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
  488. package/skills/peaks-code/references/runbook.md +63 -1
  489. package/skills/peaks-code/references/startup-sequence.md +110 -0
  490. package/skills/peaks-code/references/step-0-8-gate.md +1 -1
  491. package/skills/peaks-code/references/sub-agent-dispatch.md +92 -1
  492. package/skills/peaks-code/references/worktree-governance.md +123 -0
  493. package/skills/peaks-code/test-prompts.json +12 -0
  494. package/skills/peaks-doctor/SKILL.md +1 -1
  495. package/skills/peaks-ide/SKILL.md +1 -1
  496. package/skills/peaks-solo/SKILL.md +21 -0
  497. package/skills/peaks-solo/references/triage-decision-table.md +6 -0
  498. package/skills/peaks-sop/test-prompts.json +17 -0
  499. package/dist/cli/commands/agent-commands.d.ts +0 -20
  500. package/dist/cli/commands/agent-commands.js +0 -48
  501. package/dist/cli/commands/classify-classify-commands.d.ts +0 -19
  502. package/dist/cli/commands/classify-classify-commands.js +0 -151
  503. package/dist/cli/commands/contract-commands.d.ts +0 -26
  504. package/dist/cli/commands/contract-commands.js +0 -114
  505. package/dist/cli/commands/session-auto-compact-hook-command.d.ts +0 -37
  506. package/dist/cli/commands/session-auto-compact-hook-command.js +0 -127
  507. package/dist/cli/commands/worker-commands.d.ts +0 -3
  508. package/dist/cli/commands/worker-commands.js +0 -52
  509. package/dist/services/agent/ecc-agent-service.d.ts +0 -47
  510. package/dist/services/agent/ecc-agent-service.js +0 -143
  511. package/dist/services/config/provider-service.d.ts +0 -48
  512. package/dist/services/config/provider-service.js +0 -143
  513. package/dist/services/context/dispatch-context-guard.d.ts +0 -27
  514. package/dist/services/context/dispatch-context-guard.js +0 -192
  515. package/dist/services/context/shared-channel.d.ts +0 -93
  516. package/dist/services/context/shared-channel.js +0 -308
  517. package/dist/services/filesystem/file-lock.d.ts +0 -11
  518. package/dist/services/filesystem/file-lock.js +0 -152
  519. package/dist/services/mut/assert-scanner.d.ts +0 -6
  520. package/dist/services/mut/assert-scanner.js +0 -116
  521. package/dist/services/mut/index.d.ts +0 -8
  522. package/dist/services/mut/index.js +0 -7
  523. package/dist/services/mut/mut-runner.d.ts +0 -39
  524. package/dist/services/mut/mut-runner.js +0 -29
  525. package/dist/services/mut/production-stryker.d.ts +0 -2
  526. package/dist/services/mut/production-stryker.js +0 -75
  527. package/dist/services/mut/report-builder.d.ts +0 -11
  528. package/dist/services/mut/report-builder.js +0 -110
  529. package/dist/services/mut/report-loader.d.ts +0 -31
  530. package/dist/services/mut/report-loader.js +0 -78
  531. package/dist/services/mut/thresholds.d.ts +0 -21
  532. package/dist/services/mut/thresholds.js +0 -22
  533. package/dist/services/mut/types.d.ts +0 -336
  534. package/dist/services/mut/types.js +0 -59
  535. package/dist/services/providers/minimax-provider-service.d.ts +0 -24
  536. package/dist/services/providers/minimax-provider-service.js +0 -143
  537. package/dist/services/providers/minimax-worker-service.d.ts +0 -21
  538. package/dist/services/providers/minimax-worker-service.js +0 -83
  539. package/dist/shared/fs.d.ts +0 -4
  540. package/dist/shared/fs.js +0 -26
  541. package/dist/shared/paths.d.ts +0 -6
  542. package/dist/shared/paths.js +0 -50
  543. package/dist/shared/result.d.ts +0 -22
  544. package/dist/shared/result.js +0 -46
  545. package/dist/shared/version.d.ts +0 -1
  546. package/dist/shared/version.js +0 -1
  547. package/examples/video-demo/README.md +0 -142
  548. package/examples/video-demo/out/en-closing-960.png +0 -0
  549. package/examples/video-demo/out/zh-closing-960.png +0 -0
  550. package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
  551. package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
  552. /package/dist/services/{job/job-resource-snapshot.js → job-snapshot/snapshot.js} +0 -0
@@ -27,7 +27,9 @@
27
27
  import { existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
28
28
  import { dirname, resolve } from 'node:path';
29
29
  import { assertSafeDispatchRecordPath, dispatchRecordPath } from '../security/safe-settings-path.js';
30
- import { withFileLockSync } from '../filesystem/file-lock.js';
30
+ import { withFileLockSync } from 'peaks-loop-shared-channel';
31
+ import { isStageLabel } from './stage-enum.js';
32
+ import { emitLeaseEvent } from '../observability/observability-service.js';
31
33
  const MAX_PROMPT_BYTES = 256 * 1024;
32
34
  /** Write a new dispatch record (G2 + G5 + G6). Returns the absolute path. */
33
35
  export function writeInitialDispatchRecord(input) {
@@ -42,7 +44,7 @@ export function writeInitialDispatchRecord(input) {
42
44
  const path = dispatchRecordPath(projectRoot, sessionId, requestId, now());
43
45
  const safePath = assertSafeDispatchRecordPath(path, projectRoot);
44
46
  const record = {
45
- version: 2,
47
+ version: '3.1',
46
48
  createdAt: now().toISOString(),
47
49
  completedAt: null,
48
50
  outcome: 'no-execution',
@@ -61,7 +63,30 @@ export function writeInitialDispatchRecord(input) {
61
63
  batchId,
62
64
  heartbeats: [],
63
65
  lastBeatAt: null,
64
- status: 'queued'
66
+ status: 'queued',
67
+ // Slice 2026-07-29-dispatch-stall-governance / S5 (AC-5.1) — new
68
+ // records start with `stage: null`; the sub-agent promotes it
69
+ // through `setStage` / the heartbeat CLI's `--stage` flag.
70
+ stage: null,
71
+ // Slice 2026-07-29-worktree-l2-extended Part 3.A: when the
72
+ // dispatch was issued with --isolation worktree, persist the
73
+ // lease id so the finalize-time release hook in markCompleted
74
+ // can fire. Validation is the same 16-hex regex the gate uses
75
+ // (gate-commands.ts), so an attacker-controlled toolCall.env
76
+ // cannot inject a non-hex value and get the release path to
77
+ // misfire.
78
+ leaseId: typeof input.leaseId === 'string' && /^[a-f0-9]{16}$/.test(input.leaseId)
79
+ ? input.leaseId
80
+ : null,
81
+ // Slice 2026-07-29-worktree-l2-extended Part 7: v3.1 field.
82
+ // ISO timestamp when the isolation mode was set up. Default
83
+ // null when the dispatch did not request isolation. We do
84
+ // NOT validate the format — the writer is the source of
85
+ // truth here, and any ISO 8601 string Date.parse() can
86
+ // handle is acceptable for the dashboard.
87
+ isolationStartedAt: typeof input.isolationStartedAt === 'string' && input.isolationStartedAt.length > 0
88
+ ? input.isolationStartedAt
89
+ : null
65
90
  };
66
91
  writeAtomic(safePath, record);
67
92
  // Slice 2026-06-23-audit-4th #A4: register the path in the
@@ -142,7 +167,15 @@ function unregisterActiveDispatch(input) {
142
167
  }
143
168
  if (input.recordPath in index) {
144
169
  index[input.recordPath] = { ...index[input.recordPath], status: input.status };
145
- if (input.status === 'done' || input.status === 'failed' || input.status === 'cancelled' || input.status === 'no-execution') {
170
+ // Slice 2026-07-29-dispatch-stall-governance / S1 — `never-started`
171
+ // and `unreadable` are terminal (the startup-timeout service writes
172
+ // them as terminal markers). Unregister on the full terminal set.
173
+ if (input.status === 'done' ||
174
+ input.status === 'failed' ||
175
+ input.status === 'cancelled' ||
176
+ input.status === 'no-execution' ||
177
+ input.status === 'never-started' ||
178
+ input.status === 'unreadable') {
146
179
  delete index[input.recordPath];
147
180
  }
148
181
  const tmp = `${indexPath}.tmp-${process.pid}-${Date.now()}`;
@@ -267,6 +300,109 @@ function mapStatusToAggregate(latest, current) {
267
300
  }
268
301
  return latest;
269
302
  }
303
+ /**
304
+ * Slice 2026-07-29-worktree-l2-extended Part 3.A: fire-and-forget
305
+ * auto-release for the lease owned by a dispatch. Called from
306
+ * `markCompleted` (terminal status) and from the heartbeat CLI
307
+ * (`--status done`).
308
+ *
309
+ * Design:
310
+ * - The release subprocess is spawned ASYNC and detached. The
311
+ * finalize-time caller (heartbeat / share / dispatch reducer)
312
+ * does NOT await it; the caller's job is to record the
313
+ * finalization, not to wait for the lease cleanup.
314
+ * - Failures are swallowed (best-effort, same as `git worktree
315
+ * remove` inside `peaks worktree release` itself). The next
316
+ * `peaks worktree gc` pass is the safety net.
317
+ * - Idempotent: re-calling with the same leaseId is a no-op on
318
+ * the release side (the CLI refuses to re-release an already-
319
+ * released lease; see Part 1 release command).
320
+ * - The leaseId MUST be 16-hex (same regex the gate uses). Any
321
+ * other value is silently ignored — we never shell out to
322
+ * `peaks worktree release` with attacker-controlled input.
323
+ */
324
+ export function tryAutoReleaseLease(args) {
325
+ if (typeof args.leaseId !== 'string' || !/^[a-f0-9]{16}$/.test(args.leaseId)) {
326
+ return;
327
+ }
328
+ if (typeof args.projectRoot !== 'string' || args.projectRoot.length === 0) {
329
+ return;
330
+ }
331
+ // Spawn detached. The CLI itself runs `git worktree remove` and
332
+ // marks the lease released; we trust its at-least-once semantics.
333
+ // `node:child_process` is loaded via dynamic import so this module
334
+ // remains ESM-compatible (the compiled heartbeat CLI throws
335
+ // `require is not defined` if we use `require` here).
336
+ void (async () => {
337
+ let spawned = false;
338
+ try {
339
+ const cp = await import('node:child_process');
340
+ const child = cp.spawn(process.execPath, [
341
+ process.argv[1] ?? '',
342
+ 'worktree', 'release',
343
+ '--lease-id', args.leaseId,
344
+ '--project', args.projectRoot,
345
+ '--session', args.sessionId,
346
+ '--json'
347
+ ],
348
+ // `pipe` rather than `ignore` so a spawn failure (e.g. ENOENT
349
+ // on process.argv[1] in a test) shows up on stderr instead
350
+ // of vanishing into the void. The release CLI is short-lived
351
+ // so buffering is irrelevant.
352
+ { stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true, detached: true });
353
+ spawned = true;
354
+ if (process.env.PEAKS_WORKTREE_LEASE_DEBUG) {
355
+ child.stderr?.on('data', (d) => process.stderr.write(`[release] ${d.toString('utf8')}`));
356
+ child.stdout?.on('data', (d) => process.stderr.write(`[release] ${d.toString('utf8')}`));
357
+ child.on('error', (e) => process.stderr.write(`[release error] ${e.message}\n`));
358
+ child.on('exit', (code) => process.stderr.write(`[release exit] code=${code}\n`));
359
+ }
360
+ else {
361
+ child.stderr?.on('data', () => { });
362
+ child.stdout?.on('data', () => { });
363
+ child.on('error', () => { });
364
+ }
365
+ child.unref();
366
+ }
367
+ catch (e) {
368
+ // Slice 2026-07-29-worktree-l2-extended Part 4.A: surface
369
+ // auto-release failures to the observability stream so the
370
+ // dashboard can alert. The spawn-attempt itself threw (not
371
+ // a child-process exit-code failure — those are not
372
+ // catchable from the parent because the child is detached
373
+ // and unref'd). emitLeaseEvent is fire-and-forget; it
374
+ // returns a result we don't inspect.
375
+ emitLeaseEvent({
376
+ sessionId: args.sessionId,
377
+ projectRoot: args.projectRoot,
378
+ kind: 'autoRelease-failed',
379
+ leaseId: args.leaseId,
380
+ reason: e.message
381
+ });
382
+ }
383
+ if (spawned) {
384
+ // Record the success path. Idempotent with the manual
385
+ // `peaks worktree release` metric — the release CLI itself
386
+ // emits a 'release' event when it runs and lands. Two
387
+ // events for one logical release is acceptable; the
388
+ // dashboard can dedup or count both under
389
+ // lease.autoRelease.count.
390
+ emitLeaseEvent({
391
+ sessionId: args.sessionId,
392
+ projectRoot: args.projectRoot,
393
+ kind: 'autoRelease',
394
+ leaseId: args.leaseId
395
+ });
396
+ }
397
+ })();
398
+ // NB: we deliberately do NOT log per-call here — every heartbeat
399
+ // that reports done in a busy session would otherwise spam the
400
+ // log. The release CLI itself emits a structured envelope on
401
+ // success; that's the audit record.
402
+ if (args.logger !== undefined) {
403
+ args.logger(`peaks.worktree.autoRelease leaseId=${args.leaseId} sessionId=${args.sessionId}`);
404
+ }
405
+ }
270
406
  /** Mark a record as completed (success / failed / cancelled / no-execution). */
271
407
  export function markCompleted(input) {
272
408
  // Slice 2026-06-23-audit-3rd #3: lock + re-read so a concurrent
@@ -302,6 +438,25 @@ export function markCompleted(input) {
302
438
  /* best-effort */
303
439
  }
304
440
  }
441
+ // Slice 2026-07-29-worktree-l2-extended Part 3.A: finalize-time
442
+ // lease release. The terminal status (done/failed/cancelled/
443
+ // no-execution) means the sub-agent is no longer using the
444
+ // worktree; auto-release closes the loop. The release is detached
445
+ // and best-effort; a crash here cannot roll back the markCompleted
446
+ // write (we already returned from the lock). The next gc pass is
447
+ // the safety net.
448
+ if (result.record.leaseId !== null && typeof input.projectRoot === 'string' && input.projectRoot.length > 0) {
449
+ try {
450
+ tryAutoReleaseLease({
451
+ projectRoot: input.projectRoot,
452
+ sessionId: result.record.sessionId,
453
+ leaseId: result.record.leaseId
454
+ });
455
+ }
456
+ catch { // best-effort; release is async anyway
457
+ /* swallow */
458
+ }
459
+ }
305
460
  return result;
306
461
  }
307
462
  /** Mark a record as disposed (reducer ran). */
@@ -318,6 +473,32 @@ export function markDisposed(recordPath, now = () => new Date()) {
318
473
  return { record: next };
319
474
  });
320
475
  }
476
+ /**
477
+ * Slice 2026-07-29-dispatch-stall-governance / S5 (AC-5.1) — promote
478
+ * the record's `stage` field. Rejects unknown values with
479
+ * `INVALID_STAGE`; the LLM-side runner surfaces the error so the
480
+ * sub-agent can pick from the bounded enum in ./stage-enum.ts.
481
+ *
482
+ * Atomic via the same `withFileLockSync` lock as `appendHeartbeat` /
483
+ * `markCompleted`. `null` is a valid argument ("clear the stage")
484
+ * but unknown strings are not.
485
+ */
486
+ export function setStage(input) {
487
+ if (input.stage !== null && !isStageLabel(input.stage)) {
488
+ const err = new Error(`stage must be one of the bounded stage labels (got: ${JSON.stringify(input.stage)})`);
489
+ err.code = 'INVALID_STAGE';
490
+ throw err;
491
+ }
492
+ return withFileLockSync(input.recordPath, () => {
493
+ const existing = readRecord(input.recordPath);
494
+ const next = {
495
+ ...existing,
496
+ stage: input.stage
497
+ };
498
+ writeAtomic(input.recordPath, next);
499
+ return { record: next };
500
+ });
501
+ }
321
502
  /**
322
503
  * Read a dispatch record with backward-compat defaults. Old records
323
504
  * missing G5 / G6 fields are upgraded on read (no error, no overwrite).
@@ -363,6 +544,19 @@ function upgradeRecord(parsed) {
363
544
  throw new Error('Dispatch record root must be an object');
364
545
  }
365
546
  const obj = parsed;
547
+ // Slice 2026-07-29-rid-prose-only-sweep Part 34: the version
548
+ // field is now the literal '3.1'. Legacy v2 and v3 records
549
+ // (version: 2 or version: 3) are accepted transparently and
550
+ // upgraded to v3.1 on read. The forward-compat check rejects
551
+ // records with an unknown version string (which would
552
+ // indicate either a much-older build or a much-newer one
553
+ // with a schema we have not implemented). v1 records
554
+ // (pre-audit-trail) must be regenerated.
555
+ const rawVersion = obj.version;
556
+ if (rawVersion !== '3.1' && rawVersion !== 3 && rawVersion !== 2 && rawVersion !== 1) {
557
+ throw new Error(`Dispatch record version mismatch: expected '3.1', 3, 2, or 1, got ${JSON.stringify(rawVersion)}. ` +
558
+ 'The v1 → v3.1 migration is in-file; records from much older or newer builds must be regenerated.');
559
+ }
366
560
  const role = stringField(obj, 'role');
367
561
  const requestId = stringField(obj, 'requestId');
368
562
  const sessionId = stringField(obj, 'sessionId');
@@ -384,7 +578,14 @@ function upgradeRecord(parsed) {
384
578
  ? obj.heartbeats.filter(isValidHeartbeat)
385
579
  : [];
386
580
  const lastBeatAt = typeof obj.lastBeatAt === 'string' ? obj.lastBeatAt : null;
387
- const status = isDispatchStatus(obj.status) ? obj.status : 'no-execution';
581
+ // Slice 2026-07-29-dispatch-stall-governance / S1 (UQ-1) — `no-execution`
582
+ // keeps its natural "dispatched, never executed" reading; an unparseable
583
+ // status field now resolves to a *distinct* `unreadable` label so the
584
+ // caller can tell "corrupt record" apart from "record written, no first
585
+ // heartbeat" (which is the new `never-started` state).
586
+ const status = isDispatchStatus(obj.status)
587
+ ? obj.status
588
+ : 'unreadable';
388
589
  const completedAt = typeof obj.completedAt === 'string' ? obj.completedAt : null;
389
590
  const outcome = isOutcome(obj.outcome) ? obj.outcome : 'no-execution';
390
591
  const artifactPaths = Array.isArray(obj.artifactPaths)
@@ -396,7 +597,7 @@ function upgradeRecord(parsed) {
396
597
  ? obj.batchId
397
598
  : 'legacy-batch';
398
599
  return {
399
- version: 2,
600
+ version: '3.1',
400
601
  createdAt,
401
602
  completedAt,
402
603
  outcome,
@@ -411,7 +612,27 @@ function upgradeRecord(parsed) {
411
612
  batchId,
412
613
  heartbeats,
413
614
  lastBeatAt,
414
- status
615
+ status,
616
+ // Slice 2026-07-29-dispatch-stall-governance / S5 (AC-5.1 / PB-2)
617
+ // — legacy records (pre-slice) had no `stage` field. The reader
618
+ // defaults to `null` so the watch surface can tell "no stage ever
619
+ // emitted" apart from "stage: ''" (which is itself a *valid*
620
+ // round-trip through the writer — an empty stage is rejected by
621
+ // `setStage`, but a record that round-tripped through a non-strict
622
+ // tool would land here).
623
+ stage: typeof obj.stage === 'string' && obj.stage.length > 0 ? obj.stage : null,
624
+ // Slice 2026-07-29-worktree-l2-extended Part 3.A: legacy records
625
+ // have no `leaseId`; default to `null` so the auto-release hook
626
+ // in `markCompleted` is a clean no-op for them.
627
+ leaseId: typeof obj.leaseId === 'string' && /^[a-f0-9]{16}$/.test(obj.leaseId)
628
+ ? obj.leaseId
629
+ : null,
630
+ // Slice 2026-07-29-worktree-l2-extended Part 7: v3 → v3.1
631
+ // migration. Legacy records have no `isolationStartedAt`; default
632
+ // to `null`. v3.1 readers can treat the field as opt-in.
633
+ isolationStartedAt: typeof obj.isolationStartedAt === 'string' && obj.isolationStartedAt.length > 0
634
+ ? obj.isolationStartedAt
635
+ : null
415
636
  };
416
637
  }
417
638
  function isObject(v) {
@@ -434,12 +655,21 @@ function isValidHeartbeat(v) {
434
655
  }
435
656
  function isHeartbeatStatus(v) {
436
657
  return (v === 'queued' || v === 'running' || v === 'finalizing' ||
437
- v === 'done' || v === 'failed' || v === 'stale');
658
+ v === 'done' || v === 'failed' || v === 'stale' ||
659
+ // Slice 2026-07-29-dispatch-stall-governance / S2 — accept the
660
+ // S1 terminal members so a sub-agent can report `cancelled`,
661
+ // `no-execution`, `never-started`, or `unreadable` through the
662
+ // heartbeat CLI.
663
+ v === 'cancelled' || v === 'no-execution' ||
664
+ v === 'never-started' || v === 'unreadable');
438
665
  }
439
666
  function isDispatchStatus(v) {
440
667
  return (v === 'queued' || v === 'running' || v === 'finalizing' ||
441
668
  v === 'done' || v === 'failed' || v === 'cancelled' ||
442
- v === 'no-execution' || v === 'stale');
669
+ v === 'no-execution' || v === 'stale' ||
670
+ // Slice 2026-07-29-dispatch-stall-governance / S1 — accept the two
671
+ // new terminal members from the startup-timeout service.
672
+ v === 'never-started' || v === 'unreadable');
443
673
  }
444
674
  function isOutcome(v) {
445
675
  return (v === 'success' || v === 'failed' || v === 'timeout' ||
@@ -79,3 +79,49 @@ export declare function sliceReadyToRun(dag: SliceDag, completed: ReadonlySet<st
79
79
  export declare function serializeDag(dag: SliceDag): string;
80
80
  /** SHA-256 hash of the serialized DAG. Stable across runs. */
81
81
  export declare function hashDag(dag: SliceDag): string;
82
+ /**
83
+ * Knobs for wave planning + artifact-pass behaviour.
84
+ *
85
+ * - `maxConcurrency`: hard cap on how many slices a single Wave can hold.
86
+ * Each topological level is chunked into Waves of at most this many
87
+ * slice IDs (default 6 per `2026-07-28-24h-loop-audit.md` E direction).
88
+ * - `passArtifacts`: when true, each Wave's prompt is augmented with a
89
+ * `WaveArtifact` envelope (contracts of preceding Waves). Default
90
+ * false — the existing `runDag` ancestor-injection path already covers
91
+ * per-slice contract coverage.
92
+ */
93
+ export interface WaveOptions {
94
+ readonly maxConcurrency: number;
95
+ readonly passArtifacts: boolean;
96
+ }
97
+ /** Default wave options: 6 leaves per wave; artifact-pass off. */
98
+ export declare const DEFAULT_MAX_CONCURRENCY = 6;
99
+ export declare const DEFAULT_WAVE_OPTIONS: WaveOptions;
100
+ /**
101
+ * Artifact envelope emitted when a Wave completes successfully.
102
+ *
103
+ * - `waveIndex`: sequential, 0-based across the whole plan.
104
+ * - `completedLeaves`: slice IDs that finished (`status: 'done'`). Failed
105
+ * or cancelled leaves are NOT included.
106
+ * - `contracts`: per-slice public contract snapshot (sliceId → record).
107
+ * Stored verbatim so a downstream Wave can re-inject this without
108
+ * re-reading the disk-side contract store.
109
+ * - `passedAt`: ISO timestamp of Wave completion (caller-supplied to keep
110
+ * the surface pure).
111
+ */
112
+ export interface WaveArtifact {
113
+ readonly waveIndex: number;
114
+ readonly completedLeaves: readonly string[];
115
+ readonly contracts: Readonly<Record<string, unknown>>;
116
+ readonly passedAt: string;
117
+ }
118
+ /**
119
+ * A single dispatch Wave. Holds the slice IDs that must execute together,
120
+ * respecting `WaveOptions.maxConcurrency`. Waves are emitted in
121
+ * topological order; downstream consumers may treat `waveIndex` as a
122
+ * monotonic cursor.
123
+ */
124
+ export interface Wave {
125
+ readonly waveIndex: number;
126
+ readonly slices: readonly string[];
127
+ }
@@ -236,3 +236,9 @@ export function serializeDag(dag) {
236
236
  export function hashDag(dag) {
237
237
  return createHash('sha256').update(serializeDag(dag)).digest('hex');
238
238
  }
239
+ /** Default wave options: 6 leaves per wave; artifact-pass off. */
240
+ export const DEFAULT_MAX_CONCURRENCY = 6;
241
+ export const DEFAULT_WAVE_OPTIONS = {
242
+ maxConcurrency: DEFAULT_MAX_CONCURRENCY,
243
+ passArtifacts: false
244
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Slice 2026-07-29-dispatch-stall-governance / S5 — bounded stage
3
+ * vocabulary.
4
+ *
5
+ * Why a bounded enum (not a free-form string):
6
+ * - a free-form `stage` recreates the `note` field, which already
7
+ * exists and did not solve visibility.
8
+ * - the watch surface renders a stage label inline (`role 30%
9
+ * (5s ago) [planning]`); an unbounded vocabulary would let typos
10
+ * and near-duplicates spread across the swarm.
11
+ * - the LLM-side runner can validate the stage at write time
12
+ * (`setStage` rejects unknown values with `INVALID_STAGE`).
13
+ *
14
+ * The enum is intentionally small and stable. Adding a new stage is a
15
+ * deliberate code change (this file + the `setStage` validation) so a
16
+ * future user cannot accidentally flood the watch with `awaiting-coffee`
17
+ * or `idk`.
18
+ *
19
+ * `null` is NOT a stage — it is the absence of a stage. Records that
20
+ * have not yet been promoted carry `stage: null`; the watch surface
21
+ * renders no marker.
22
+ */
23
+ export declare const STAGE_LABELS: readonly ["intake", "planning", "gathering", "analyzing", "writing", "testing", "reviewing", "finalizing"];
24
+ export type StageLabel = (typeof STAGE_LABELS)[number];
25
+ export declare const DEFAULT_STAGE_LABELS: readonly StageLabel[];
26
+ export declare function isStageLabel(value: unknown): value is StageLabel;
27
+ export declare function normalizeStage(value: string | null | undefined): StageLabel | null;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Slice 2026-07-29-dispatch-stall-governance / S5 — bounded stage
3
+ * vocabulary.
4
+ *
5
+ * Why a bounded enum (not a free-form string):
6
+ * - a free-form `stage` recreates the `note` field, which already
7
+ * exists and did not solve visibility.
8
+ * - the watch surface renders a stage label inline (`role 30%
9
+ * (5s ago) [planning]`); an unbounded vocabulary would let typos
10
+ * and near-duplicates spread across the swarm.
11
+ * - the LLM-side runner can validate the stage at write time
12
+ * (`setStage` rejects unknown values with `INVALID_STAGE`).
13
+ *
14
+ * The enum is intentionally small and stable. Adding a new stage is a
15
+ * deliberate code change (this file + the `setStage` validation) so a
16
+ * future user cannot accidentally flood the watch with `awaiting-coffee`
17
+ * or `idk`.
18
+ *
19
+ * `null` is NOT a stage — it is the absence of a stage. Records that
20
+ * have not yet been promoted carry `stage: null`; the watch surface
21
+ * renders no marker.
22
+ */
23
+ export const STAGE_LABELS = [
24
+ 'intake',
25
+ 'planning',
26
+ 'gathering',
27
+ 'analyzing',
28
+ 'writing',
29
+ 'testing',
30
+ 'reviewing',
31
+ 'finalizing'
32
+ ];
33
+ export const DEFAULT_STAGE_LABELS = STAGE_LABELS;
34
+ export function isStageLabel(value) {
35
+ return typeof value === 'string' && STAGE_LABELS.includes(value);
36
+ }
37
+ export function normalizeStage(value) {
38
+ if (value === null || value === undefined)
39
+ return null;
40
+ if (typeof value !== 'string')
41
+ return null;
42
+ const trimmed = value.trim();
43
+ if (trimmed.length === 0)
44
+ return null;
45
+ if (isStageLabel(trimmed))
46
+ return trimmed;
47
+ return null;
48
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Slice 2026-07-29-dispatch-stall-governance / S1 — startup-timeout service.
3
+ *
4
+ * Why a separate module (vs adding the logic inline to
5
+ * `dispatch-record-writer.ts`):
6
+ * - the writer is the on-disk format owner; the eval logic is a small
7
+ * pure function over a `DispatchRecord` snapshot.
8
+ * - keeps the writer surface unchanged (no extra `markStartupTimeout`
9
+ * method) so other consumers (heartbeat, watch, batch poller) do not
10
+ * have to learn a new mutation API.
11
+ * - a future `markStartupTimeout` writer helper, if added, would import
12
+ * this module's STARTUP_OUTCOME / DEFAULT_STARTUP_BUDGET_MS so the
13
+ * CLI help text and the eval share a single source of truth.
14
+ *
15
+ * Contract (see tests/unit/dispatch/startup-timeout.test.ts for the
16
+ * pinned assertions):
17
+ *
18
+ * evaluateStartupTimeout(record, now, opts) → StartupTimeoutEvaluation
19
+ *
20
+ * - `outcome: 'within-budget' | 'never-started' | 'unreadable'`
21
+ * - `targetStatus: DispatchRecordStatus` — the status to write when
22
+ * `marked === true`. Distinct from `stale` (heartbeat seen, gone
23
+ * quiet) and from `no-execution` (the pre-slice silent default).
24
+ * - `marked: boolean` — whether the caller should write
25
+ * `targetStatus` to the record.
26
+ * - `reason: string` — short human-readable rationale, rendered in
27
+ * the watcher text line and in the dispatch envelope's
28
+ * `notes[]`.
29
+ *
30
+ * DEFAULT_STARTUP_BUDGET_MS = 60_000
31
+ * - 1 order of magnitude above the measured 4–6s cold-start figure
32
+ * from .peaks/memory/2026-07-28-sub-agent-visibility-issue.md
33
+ * - well below the 5-minute heartbeat stale threshold so this
34
+ * fires first
35
+ * - configurable via opts.budgetMs
36
+ *
37
+ * STARTUP_OUTCOME = { NEVER_STARTED: 'never-started', UNREADABLE:
38
+ * 'unreadable' }
39
+ * - exported so the CLI help text, the watch command, and the
40
+ * reader's legacy fallback all reference the same strings.
41
+ */
42
+ import type { DispatchRecord, DispatchRecordStatus } from './dispatch-record-writer.js';
43
+ /**
44
+ * Default budget: 60s. 1 order of magnitude above the measured 4–6s
45
+ * cold-start figure from .peaks/memory/2026-07-28-sub-agent-visibility-
46
+ * issue.md; well below the 5-min heartbeat stale threshold so this
47
+ * fires first.
48
+ */
49
+ export declare const DEFAULT_STARTUP_BUDGET_MS = 60000;
50
+ /**
51
+ * String constants for the new terminal statuses. Distinct from the
52
+ * pre-slice `stale` (heartbeat seen, then quiet) and `no-execution`
53
+ * (legacy silent fallback). These are added to the writer's
54
+ * `DispatchRecordStatus` union in the same slice; the constants here
55
+ * are the canonical source so the CLI help / watch / writer all
56
+ * reference the same strings.
57
+ */
58
+ export declare const STARTUP_OUTCOME: {
59
+ readonly NEVER_STARTED: "never-started";
60
+ readonly UNREADABLE: "unreadable";
61
+ };
62
+ export type StartupTimeoutOutcome = 'within-budget' | 'never-started' | 'unreadable';
63
+ export interface StartupTimeoutOptions {
64
+ /** Override the default 60s budget. */
65
+ readonly budgetMs?: number;
66
+ /**
67
+ * Test seam: when true, the record is treated as if its body is
68
+ * corrupt (status field unparseable). The function returns
69
+ * `{ outcome: 'unreadable', ... }` and recommends writing the
70
+ * `unreadable` status. The CLI never sets this; the read path does.
71
+ */
72
+ readonly corrupt?: boolean;
73
+ }
74
+ export interface StartupTimeoutEvaluation {
75
+ readonly outcome: StartupTimeoutOutcome;
76
+ readonly marked: boolean;
77
+ readonly targetStatus: DispatchRecordStatus;
78
+ readonly reason: string;
79
+ readonly ageMs: number;
80
+ readonly budgetMs: number;
81
+ }
82
+ /**
83
+ * Pure eval. Returns a typed triple; the caller decides whether to
84
+ * write `targetStatus` to the record.
85
+ */
86
+ export declare function evaluateStartupTimeout(record: DispatchRecord, now?: () => Date, options?: StartupTimeoutOptions): StartupTimeoutEvaluation;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Default budget: 60s. 1 order of magnitude above the measured 4–6s
3
+ * cold-start figure from .peaks/memory/2026-07-28-sub-agent-visibility-
4
+ * issue.md; well below the 5-min heartbeat stale threshold so this
5
+ * fires first.
6
+ */
7
+ export const DEFAULT_STARTUP_BUDGET_MS = 60_000;
8
+ /**
9
+ * String constants for the new terminal statuses. Distinct from the
10
+ * pre-slice `stale` (heartbeat seen, then quiet) and `no-execution`
11
+ * (legacy silent fallback). These are added to the writer's
12
+ * `DispatchRecordStatus` union in the same slice; the constants here
13
+ * are the canonical source so the CLI help / watch / writer all
14
+ * reference the same strings.
15
+ */
16
+ export const STARTUP_OUTCOME = {
17
+ NEVER_STARTED: 'never-started',
18
+ UNREADABLE: 'unreadable'
19
+ };
20
+ /**
21
+ * Pure eval. Returns a typed triple; the caller decides whether to
22
+ * write `targetStatus` to the record.
23
+ */
24
+ export function evaluateStartupTimeout(record, now = () => new Date(), options = {}) {
25
+ const budgetMs = options.budgetMs ?? DEFAULT_STARTUP_BUDGET_MS;
26
+ const safeBudget = Number.isFinite(budgetMs) && budgetMs > 0 ? budgetMs : DEFAULT_STARTUP_BUDGET_MS;
27
+ const createdAt = parseIsoOrFallback(record.createdAt, now);
28
+ const ageMs = Math.max(0, now().getTime() - createdAt.getTime());
29
+ if (options.corrupt === true) {
30
+ return {
31
+ outcome: 'unreadable',
32
+ marked: true,
33
+ targetStatus: 'unreadable',
34
+ reason: `record body is corrupt (status field unparseable) at age ${ageMs}ms`,
35
+ ageMs,
36
+ budgetMs: safeBudget
37
+ };
38
+ }
39
+ // A record that already reached `running` (or beyond) is by definition
40
+ // not a startup-timeout candidate. `stale` (heartbeat seen, then
41
+ // quiet) is its own ladder; we do not reclassify it.
42
+ if (record.status === 'running' || record.status === 'finalizing') {
43
+ return {
44
+ outcome: 'within-budget',
45
+ marked: false,
46
+ targetStatus: record.status,
47
+ reason: `record is ${record.status} and not eligible for startup timeout`,
48
+ ageMs,
49
+ budgetMs: safeBudget
50
+ };
51
+ }
52
+ // A terminal record is not eligible either (the marker functions own
53
+ // the terminal transition; this evaluator is a read-only gate).
54
+ const TERMINAL = [
55
+ 'done',
56
+ 'failed',
57
+ 'cancelled',
58
+ 'no-execution',
59
+ 'stale',
60
+ 'never-started',
61
+ 'unreadable'
62
+ ];
63
+ if (TERMINAL.includes(record.status)) {
64
+ return {
65
+ outcome: 'within-budget',
66
+ marked: false,
67
+ targetStatus: record.status,
68
+ reason: `record is terminal (${record.status}) and not eligible for startup timeout`,
69
+ ageMs,
70
+ budgetMs: safeBudget
71
+ };
72
+ }
73
+ if (ageMs < safeBudget) {
74
+ return {
75
+ outcome: 'within-budget',
76
+ marked: false,
77
+ targetStatus: record.status,
78
+ reason: `record age ${ageMs}ms is within ${safeBudget}ms startup budget`,
79
+ ageMs,
80
+ budgetMs: safeBudget
81
+ };
82
+ }
83
+ return {
84
+ outcome: 'never-started',
85
+ marked: true,
86
+ targetStatus: 'never-started',
87
+ reason: `record stayed ${record.status} for ${ageMs}ms (budget ${safeBudget}ms) without a first heartbeat`,
88
+ ageMs,
89
+ budgetMs: safeBudget
90
+ };
91
+ }
92
+ function parseIsoOrFallback(iso, now) {
93
+ const d = new Date(iso);
94
+ if (!Number.isNaN(d.getTime()))
95
+ return d;
96
+ return new Date(now().getTime());
97
+ }