@matteeh/osq 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (619) hide show
  1. package/README.md +415 -72
  2. package/dist/cli/approve.d.ts +13 -3
  3. package/dist/cli/approve.d.ts.map +1 -1
  4. package/dist/cli/approve.js +59 -4
  5. package/dist/cli/approve.js.map +1 -1
  6. package/dist/cli/bin.js +0 -0
  7. package/dist/cli/confirm.d.ts +21 -0
  8. package/dist/cli/confirm.d.ts.map +1 -0
  9. package/dist/cli/confirm.js +28 -0
  10. package/dist/cli/confirm.js.map +1 -0
  11. package/dist/cli/doctor.d.ts +13 -0
  12. package/dist/cli/doctor.d.ts.map +1 -0
  13. package/dist/cli/doctor.js +23 -0
  14. package/dist/cli/doctor.js.map +1 -0
  15. package/dist/cli/done.d.ts +12 -0
  16. package/dist/cli/done.d.ts.map +1 -0
  17. package/dist/cli/done.js +26 -0
  18. package/dist/cli/done.js.map +1 -0
  19. package/dist/cli/inbox.d.ts +22 -0
  20. package/dist/cli/inbox.d.ts.map +1 -0
  21. package/dist/cli/inbox.js +41 -0
  22. package/dist/cli/inbox.js.map +1 -0
  23. package/dist/cli/index.d.ts.map +1 -1
  24. package/dist/cli/index.js +127 -8
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/init.d.ts +1 -0
  27. package/dist/cli/init.d.ts.map +1 -1
  28. package/dist/cli/init.js +9 -3
  29. package/dist/cli/init.js.map +1 -1
  30. package/dist/cli/lint.d.ts +26 -0
  31. package/dist/cli/lint.d.ts.map +1 -0
  32. package/dist/cli/lint.js +60 -0
  33. package/dist/cli/lint.js.map +1 -0
  34. package/dist/cli/migrate.d.ts +18 -0
  35. package/dist/cli/migrate.d.ts.map +1 -0
  36. package/dist/cli/migrate.js +42 -0
  37. package/dist/cli/migrate.js.map +1 -0
  38. package/dist/cli/new.js +1 -1
  39. package/dist/cli/new.js.map +1 -1
  40. package/dist/cli/plan-queue.d.ts +50 -0
  41. package/dist/cli/plan-queue.d.ts.map +1 -0
  42. package/dist/cli/plan-queue.js +167 -0
  43. package/dist/cli/plan-queue.js.map +1 -0
  44. package/dist/cli/plan.d.ts +35 -0
  45. package/dist/cli/plan.d.ts.map +1 -0
  46. package/dist/cli/plan.js +153 -0
  47. package/dist/cli/plan.js.map +1 -0
  48. package/dist/cli/queue.d.ts +9 -0
  49. package/dist/cli/queue.d.ts.map +1 -0
  50. package/dist/cli/queue.js +24 -0
  51. package/dist/cli/queue.js.map +1 -0
  52. package/dist/cli/reject.d.ts +8 -0
  53. package/dist/cli/reject.d.ts.map +1 -0
  54. package/dist/cli/reject.js +18 -0
  55. package/dist/cli/reject.js.map +1 -0
  56. package/dist/cli/report.d.ts +1 -1
  57. package/dist/cli/report.d.ts.map +1 -1
  58. package/dist/cli/report.js +141 -14
  59. package/dist/cli/report.js.map +1 -1
  60. package/dist/cli/retry.d.ts +7 -0
  61. package/dist/cli/retry.d.ts.map +1 -0
  62. package/dist/cli/retry.js +29 -0
  63. package/dist/cli/retry.js.map +1 -0
  64. package/dist/cli/serve.d.ts +30 -0
  65. package/dist/cli/serve.d.ts.map +1 -0
  66. package/dist/cli/serve.js +136 -0
  67. package/dist/cli/serve.js.map +1 -0
  68. package/dist/cli/setup.d.ts.map +1 -1
  69. package/dist/cli/setup.js +7 -1
  70. package/dist/cli/setup.js.map +1 -1
  71. package/dist/cli/show.d.ts +2 -1
  72. package/dist/cli/show.d.ts.map +1 -1
  73. package/dist/cli/show.js +20 -3
  74. package/dist/cli/show.js.map +1 -1
  75. package/dist/cli/status.d.ts +1 -1
  76. package/dist/cli/status.d.ts.map +1 -1
  77. package/dist/cli/status.js +2 -2
  78. package/dist/cli/status.js.map +1 -1
  79. package/dist/cli/watch.d.ts +9 -6
  80. package/dist/cli/watch.d.ts.map +1 -1
  81. package/dist/cli/watch.js +15 -2
  82. package/dist/cli/watch.js.map +1 -1
  83. package/dist/core/foundation/config-codex.d.ts +22 -0
  84. package/dist/core/foundation/config-codex.d.ts.map +1 -0
  85. package/dist/core/foundation/config-codex.js +58 -0
  86. package/dist/core/foundation/config-codex.js.map +1 -0
  87. package/dist/core/foundation/config-doctor.d.ts +14 -0
  88. package/dist/core/foundation/config-doctor.d.ts.map +1 -0
  89. package/dist/core/foundation/config-doctor.js +29 -0
  90. package/dist/core/foundation/config-doctor.js.map +1 -0
  91. package/dist/core/foundation/config-env.d.ts +3 -0
  92. package/dist/core/foundation/config-env.d.ts.map +1 -0
  93. package/dist/core/foundation/config-env.js +22 -0
  94. package/dist/core/foundation/config-env.js.map +1 -0
  95. package/dist/core/foundation/config-gates.d.ts +22 -0
  96. package/dist/core/foundation/config-gates.d.ts.map +1 -0
  97. package/dist/core/foundation/config-gates.js +43 -0
  98. package/dist/core/foundation/config-gates.js.map +1 -0
  99. package/dist/core/foundation/config-pi.d.ts +64 -0
  100. package/dist/core/foundation/config-pi.d.ts.map +1 -0
  101. package/dist/core/foundation/config-pi.js +131 -0
  102. package/dist/core/foundation/config-pi.js.map +1 -0
  103. package/dist/core/foundation/config-planning.d.ts +24 -0
  104. package/dist/core/foundation/config-planning.d.ts.map +1 -0
  105. package/dist/core/foundation/config-planning.js +60 -0
  106. package/dist/core/foundation/config-planning.js.map +1 -0
  107. package/dist/core/foundation/config-queue.d.ts +15 -0
  108. package/dist/core/foundation/config-queue.d.ts.map +1 -0
  109. package/dist/core/foundation/config-queue.js +24 -0
  110. package/dist/core/foundation/config-queue.js.map +1 -0
  111. package/dist/core/foundation/config-serve.d.ts +20 -0
  112. package/dist/core/foundation/config-serve.d.ts.map +1 -0
  113. package/dist/core/foundation/config-serve.js +35 -0
  114. package/dist/core/foundation/config-serve.js.map +1 -0
  115. package/dist/core/{config.d.ts → foundation/config.d.ts} +34 -3
  116. package/dist/core/foundation/config.d.ts.map +1 -0
  117. package/dist/core/{config.js → foundation/config.js} +35 -18
  118. package/dist/core/foundation/config.js.map +1 -0
  119. package/dist/core/foundation/doctor-managed.d.ts +13 -0
  120. package/dist/core/foundation/doctor-managed.d.ts.map +1 -0
  121. package/dist/core/foundation/doctor-managed.js +77 -0
  122. package/dist/core/foundation/doctor-managed.js.map +1 -0
  123. package/dist/core/foundation/doctor.d.ts +19 -0
  124. package/dist/core/foundation/doctor.d.ts.map +1 -0
  125. package/dist/core/foundation/doctor.js +187 -0
  126. package/dist/core/foundation/doctor.js.map +1 -0
  127. package/dist/core/foundation/harness-catalog.d.ts +96 -0
  128. package/dist/core/foundation/harness-catalog.d.ts.map +1 -0
  129. package/dist/core/foundation/harness-catalog.js +182 -0
  130. package/dist/core/foundation/harness-catalog.js.map +1 -0
  131. package/dist/core/foundation/init-blocks.d.ts +33 -0
  132. package/dist/core/foundation/init-blocks.d.ts.map +1 -0
  133. package/dist/core/foundation/init-blocks.js +165 -0
  134. package/dist/core/foundation/init-blocks.js.map +1 -0
  135. package/dist/core/foundation/init-managed.d.ts +10 -0
  136. package/dist/core/foundation/init-managed.d.ts.map +1 -0
  137. package/dist/core/foundation/init-managed.js +115 -0
  138. package/dist/core/foundation/init-managed.js.map +1 -0
  139. package/dist/core/foundation/init.d.ts +18 -0
  140. package/dist/core/foundation/init.d.ts.map +1 -0
  141. package/dist/core/foundation/init.js +113 -0
  142. package/dist/core/foundation/init.js.map +1 -0
  143. package/dist/core/{logger.d.ts → foundation/logger.d.ts} +1 -0
  144. package/dist/core/foundation/logger.d.ts.map +1 -0
  145. package/dist/core/{logger.js → foundation/logger.js} +18 -2
  146. package/dist/core/foundation/logger.js.map +1 -0
  147. package/dist/core/{new.d.ts → foundation/new.d.ts} +3 -0
  148. package/dist/core/foundation/new.d.ts.map +1 -0
  149. package/dist/core/foundation/new.js +206 -0
  150. package/dist/core/foundation/new.js.map +1 -0
  151. package/dist/core/foundation/package-root.d.ts +9 -0
  152. package/dist/core/foundation/package-root.d.ts.map +1 -0
  153. package/dist/core/foundation/package-root.js +11 -0
  154. package/dist/core/foundation/package-root.js.map +1 -0
  155. package/dist/core/lifecycle/done.d.ts +17 -0
  156. package/dist/core/lifecycle/done.d.ts.map +1 -0
  157. package/dist/core/lifecycle/done.js +97 -0
  158. package/dist/core/lifecycle/done.js.map +1 -0
  159. package/dist/core/lifecycle/reject.d.ts +26 -0
  160. package/dist/core/lifecycle/reject.d.ts.map +1 -0
  161. package/dist/core/lifecycle/reject.js +83 -0
  162. package/dist/core/lifecycle/reject.js.map +1 -0
  163. package/dist/core/lifecycle/retry-transition.d.ts +23 -0
  164. package/dist/core/lifecycle/retry-transition.d.ts.map +1 -0
  165. package/dist/core/lifecycle/retry-transition.js +41 -0
  166. package/dist/core/lifecycle/retry-transition.js.map +1 -0
  167. package/dist/core/lifecycle/retry.d.ts +18 -0
  168. package/dist/core/lifecycle/retry.d.ts.map +1 -0
  169. package/dist/core/lifecycle/retry.js +179 -0
  170. package/dist/core/lifecycle/retry.js.map +1 -0
  171. package/dist/core/report/approval-flags.d.ts +29 -0
  172. package/dist/core/report/approval-flags.d.ts.map +1 -0
  173. package/dist/core/report/approval-flags.js +138 -0
  174. package/dist/core/report/approval-flags.js.map +1 -0
  175. package/dist/core/report/planning-economics.d.ts +39 -0
  176. package/dist/core/report/planning-economics.d.ts.map +1 -0
  177. package/dist/core/report/planning-economics.js +168 -0
  178. package/dist/core/report/planning-economics.js.map +1 -0
  179. package/dist/core/report/planning-observed.d.ts +59 -0
  180. package/dist/core/report/planning-observed.d.ts.map +1 -0
  181. package/dist/core/report/planning-observed.js +135 -0
  182. package/dist/core/report/planning-observed.js.map +1 -0
  183. package/dist/core/report/planning-records.d.ts +69 -0
  184. package/dist/core/report/planning-records.d.ts.map +1 -0
  185. package/dist/core/report/planning-records.js +149 -0
  186. package/dist/core/report/planning-records.js.map +1 -0
  187. package/dist/core/report/planning-slice-lookup.d.ts +13 -0
  188. package/dist/core/report/planning-slice-lookup.d.ts.map +1 -0
  189. package/dist/core/report/planning-slice-lookup.js +146 -0
  190. package/dist/core/report/planning-slice-lookup.js.map +1 -0
  191. package/dist/core/report/planning-slice-measures.d.ts +17 -0
  192. package/dist/core/report/planning-slice-measures.d.ts.map +1 -0
  193. package/dist/core/report/planning-slice-measures.js +85 -0
  194. package/dist/core/report/planning-slice-measures.js.map +1 -0
  195. package/dist/core/report/planning-slice-record.d.ts +4 -0
  196. package/dist/core/report/planning-slice-record.d.ts.map +1 -0
  197. package/dist/core/report/planning-slice-record.js +66 -0
  198. package/dist/core/report/planning-slice-record.js.map +1 -0
  199. package/dist/core/report/planning-slice-turns.d.ts +13 -0
  200. package/dist/core/report/planning-slice-turns.d.ts.map +1 -0
  201. package/dist/core/report/planning-slice-turns.js +41 -0
  202. package/dist/core/report/planning-slice-turns.js.map +1 -0
  203. package/dist/core/report/planning-slice.d.ts +70 -0
  204. package/dist/core/report/planning-slice.d.ts.map +1 -0
  205. package/dist/core/report/planning-slice.js +147 -0
  206. package/dist/core/report/planning-slice.js.map +1 -0
  207. package/dist/core/report/planning.d.ts +31 -0
  208. package/dist/core/report/planning.d.ts.map +1 -0
  209. package/dist/core/report/planning.js +75 -0
  210. package/dist/core/report/planning.js.map +1 -0
  211. package/dist/core/report/report-events.d.ts +52 -0
  212. package/dist/core/report/report-events.d.ts.map +1 -0
  213. package/dist/core/report/report-events.js +198 -0
  214. package/dist/core/report/report-events.js.map +1 -0
  215. package/dist/core/report/report-pre-spawn.d.ts +25 -0
  216. package/dist/core/report/report-pre-spawn.d.ts.map +1 -0
  217. package/dist/core/report/report-pre-spawn.js +40 -0
  218. package/dist/core/report/report-pre-spawn.js.map +1 -0
  219. package/dist/core/report/report-retries.d.ts +30 -0
  220. package/dist/core/report/report-retries.d.ts.map +1 -0
  221. package/dist/core/report/report-retries.js +100 -0
  222. package/dist/core/report/report-retries.js.map +1 -0
  223. package/dist/core/report/report.d.ts +276 -0
  224. package/dist/core/report/report.d.ts.map +1 -0
  225. package/dist/core/report/report.js +1421 -0
  226. package/dist/core/report/report.js.map +1 -0
  227. package/dist/core/{lock.d.ts → run/lock.d.ts} +6 -0
  228. package/dist/core/run/lock.d.ts.map +1 -0
  229. package/dist/core/{lock.js → run/lock.js} +7 -15
  230. package/dist/core/run/lock.js.map +1 -0
  231. package/dist/core/run/manifest.d.ts +39 -0
  232. package/dist/core/run/manifest.d.ts.map +1 -0
  233. package/dist/core/run/manifest.js +137 -0
  234. package/dist/core/run/manifest.js.map +1 -0
  235. package/dist/core/run/scope-hash.d.ts +71 -0
  236. package/dist/core/run/scope-hash.d.ts.map +1 -0
  237. package/dist/core/run/scope-hash.js +177 -0
  238. package/dist/core/run/scope-hash.js.map +1 -0
  239. package/dist/core/run/scope.d.ts +30 -0
  240. package/dist/core/run/scope.d.ts.map +1 -0
  241. package/dist/core/run/scope.js +193 -0
  242. package/dist/core/run/scope.js.map +1 -0
  243. package/dist/core/run/summary.d.ts +8 -0
  244. package/dist/core/run/summary.d.ts.map +1 -0
  245. package/dist/core/run/summary.js +25 -0
  246. package/dist/core/run/summary.js.map +1 -0
  247. package/dist/core/run/verification.d.ts +23 -0
  248. package/dist/core/run/verification.d.ts.map +1 -0
  249. package/dist/core/run/verification.js +78 -0
  250. package/dist/core/run/verification.js.map +1 -0
  251. package/dist/core/spec/approve.d.ts +31 -0
  252. package/dist/core/spec/approve.d.ts.map +1 -0
  253. package/dist/core/spec/approve.js +111 -0
  254. package/dist/core/spec/approve.js.map +1 -0
  255. package/dist/core/spec/delta.d.ts +77 -0
  256. package/dist/core/spec/delta.d.ts.map +1 -0
  257. package/dist/core/spec/delta.js +581 -0
  258. package/dist/core/spec/delta.js.map +1 -0
  259. package/dist/core/spec/digest-flags.d.ts +21 -0
  260. package/dist/core/spec/digest-flags.d.ts.map +1 -0
  261. package/dist/core/spec/digest-flags.js +194 -0
  262. package/dist/core/spec/digest-flags.js.map +1 -0
  263. package/dist/core/spec/digest-verify-starts.d.ts +5 -0
  264. package/dist/core/spec/digest-verify-starts.d.ts.map +1 -0
  265. package/dist/core/spec/digest-verify-starts.js +31 -0
  266. package/dist/core/spec/digest-verify-starts.js.map +1 -0
  267. package/dist/core/spec/digest.d.ts +42 -0
  268. package/dist/core/spec/digest.d.ts.map +1 -0
  269. package/dist/core/spec/digest.js +170 -0
  270. package/dist/core/spec/digest.js.map +1 -0
  271. package/dist/core/spec/hasher.d.ts +11 -0
  272. package/dist/core/spec/hasher.d.ts.map +1 -0
  273. package/dist/core/{hasher.js → spec/hasher.js} +27 -3
  274. package/dist/core/spec/hasher.js.map +1 -0
  275. package/dist/core/spec/linter.d.ts +79 -0
  276. package/dist/core/spec/linter.d.ts.map +1 -0
  277. package/dist/core/spec/linter.js +826 -0
  278. package/dist/core/spec/linter.js.map +1 -0
  279. package/dist/core/spec/migrate.d.ts +54 -0
  280. package/dist/core/spec/migrate.d.ts.map +1 -0
  281. package/dist/core/spec/migrate.js +297 -0
  282. package/dist/core/spec/migrate.js.map +1 -0
  283. package/dist/core/spec/openspec-version.d.ts +30 -0
  284. package/dist/core/spec/openspec-version.d.ts.map +1 -0
  285. package/dist/core/spec/openspec-version.js +118 -0
  286. package/dist/core/spec/openspec-version.js.map +1 -0
  287. package/dist/core/spec/parser.d.ts +82 -0
  288. package/dist/core/spec/parser.d.ts.map +1 -0
  289. package/dist/core/spec/parser.js +221 -0
  290. package/dist/core/spec/parser.js.map +1 -0
  291. package/dist/core/spec/verify-paths.d.ts +18 -0
  292. package/dist/core/spec/verify-paths.d.ts.map +1 -0
  293. package/dist/core/spec/verify-paths.js +139 -0
  294. package/dist/core/spec/verify-paths.js.map +1 -0
  295. package/dist/core/spec/verify-starts.d.ts +45 -0
  296. package/dist/core/spec/verify-starts.d.ts.map +1 -0
  297. package/dist/core/spec/verify-starts.js +61 -0
  298. package/dist/core/spec/verify-starts.js.map +1 -0
  299. package/dist/core/status/inbox-cursor.d.ts +10 -0
  300. package/dist/core/status/inbox-cursor.d.ts.map +1 -0
  301. package/dist/core/status/inbox-cursor.js +33 -0
  302. package/dist/core/status/inbox-cursor.js.map +1 -0
  303. package/dist/core/status/inbox-projection.d.ts +15 -0
  304. package/dist/core/status/inbox-projection.d.ts.map +1 -0
  305. package/dist/core/status/inbox-projection.js +20 -0
  306. package/dist/core/status/inbox-projection.js.map +1 -0
  307. package/dist/core/status/inbox-text.d.ts +4 -0
  308. package/dist/core/status/inbox-text.d.ts.map +1 -0
  309. package/dist/core/status/inbox-text.js +48 -0
  310. package/dist/core/status/inbox-text.js.map +1 -0
  311. package/dist/core/status/inbox.d.ts +53 -0
  312. package/dist/core/status/inbox.d.ts.map +1 -0
  313. package/dist/core/status/inbox.js +167 -0
  314. package/dist/core/status/inbox.js.map +1 -0
  315. package/dist/core/status/layout.d.ts +29 -0
  316. package/dist/core/status/layout.d.ts.map +1 -0
  317. package/dist/core/status/layout.js +77 -0
  318. package/dist/core/status/layout.js.map +1 -0
  319. package/dist/core/status/queue-parser.d.ts +13 -0
  320. package/dist/core/status/queue-parser.d.ts.map +1 -0
  321. package/dist/core/status/queue-parser.js +88 -0
  322. package/dist/core/status/queue-parser.js.map +1 -0
  323. package/dist/core/status/queue-planning.d.ts +62 -0
  324. package/dist/core/status/queue-planning.d.ts.map +1 -0
  325. package/dist/core/status/queue-planning.js +158 -0
  326. package/dist/core/status/queue-planning.js.map +1 -0
  327. package/dist/core/status/queue-report-detail.d.ts +50 -0
  328. package/dist/core/status/queue-report-detail.d.ts.map +1 -0
  329. package/dist/core/status/queue-report-detail.js +140 -0
  330. package/dist/core/status/queue-report-detail.js.map +1 -0
  331. package/dist/core/status/queue-report.d.ts +14 -0
  332. package/dist/core/status/queue-report.d.ts.map +1 -0
  333. package/dist/core/status/queue-report.js +41 -0
  334. package/dist/core/status/queue-report.js.map +1 -0
  335. package/dist/core/status/queue-state.d.ts +53 -0
  336. package/dist/core/status/queue-state.d.ts.map +1 -0
  337. package/dist/core/status/queue-state.js +167 -0
  338. package/dist/core/status/queue-state.js.map +1 -0
  339. package/dist/core/status/queue.d.ts +7 -0
  340. package/dist/core/status/queue.d.ts.map +1 -0
  341. package/dist/core/status/queue.js +4 -0
  342. package/dist/core/status/queue.js.map +1 -0
  343. package/dist/core/status/show.d.ts +102 -0
  344. package/dist/core/status/show.d.ts.map +1 -0
  345. package/dist/core/status/show.js +704 -0
  346. package/dist/core/status/show.js.map +1 -0
  347. package/dist/core/status/state.d.ts +56 -0
  348. package/dist/core/status/state.d.ts.map +1 -0
  349. package/dist/core/status/state.js +187 -0
  350. package/dist/core/status/state.js.map +1 -0
  351. package/dist/core/status/status.d.ts +23 -0
  352. package/dist/core/status/status.d.ts.map +1 -0
  353. package/dist/core/status/status.js +173 -0
  354. package/dist/core/status/status.js.map +1 -0
  355. package/dist/core/web/web-data-change.d.ts +10 -0
  356. package/dist/core/web/web-data-change.d.ts.map +1 -0
  357. package/dist/core/web/web-data-change.js +106 -0
  358. package/dist/core/web/web-data-change.js.map +1 -0
  359. package/dist/core/web/web-data-folders.d.ts +39 -0
  360. package/dist/core/web/web-data-folders.d.ts.map +1 -0
  361. package/dist/core/web/web-data-folders.js +125 -0
  362. package/dist/core/web/web-data-folders.js.map +1 -0
  363. package/dist/core/web/web-data-graph.d.ts +8 -0
  364. package/dist/core/web/web-data-graph.d.ts.map +1 -0
  365. package/dist/core/web/web-data-graph.js +113 -0
  366. package/dist/core/web/web-data-graph.js.map +1 -0
  367. package/dist/core/web/web-data-lifecycle.d.ts +43 -0
  368. package/dist/core/web/web-data-lifecycle.d.ts.map +1 -0
  369. package/dist/core/web/web-data-lifecycle.js +141 -0
  370. package/dist/core/web/web-data-lifecycle.js.map +1 -0
  371. package/dist/core/web/web-data-observations.d.ts +30 -0
  372. package/dist/core/web/web-data-observations.d.ts.map +1 -0
  373. package/dist/core/web/web-data-observations.js +181 -0
  374. package/dist/core/web/web-data-observations.js.map +1 -0
  375. package/dist/core/web/web-data-tokens.d.ts +29 -0
  376. package/dist/core/web/web-data-tokens.d.ts.map +1 -0
  377. package/dist/core/web/web-data-tokens.js +62 -0
  378. package/dist/core/web/web-data-tokens.js.map +1 -0
  379. package/dist/core/web/web-data-types.d.ts +156 -0
  380. package/dist/core/web/web-data-types.d.ts.map +1 -0
  381. package/dist/core/web/web-data-types.js +15 -0
  382. package/dist/core/web/web-data-types.js.map +1 -0
  383. package/dist/core/web/web-data.d.ts +10 -0
  384. package/dist/core/web/web-data.d.ts.map +1 -0
  385. package/dist/core/web/web-data.js +8 -0
  386. package/dist/core/web/web-data.js.map +1 -0
  387. package/dist/core/web/web-events.d.ts +54 -0
  388. package/dist/core/web/web-events.d.ts.map +1 -0
  389. package/dist/core/web/web-events.js +162 -0
  390. package/dist/core/web/web-events.js.map +1 -0
  391. package/dist/core/web/web-export.d.ts +18 -0
  392. package/dist/core/web/web-export.d.ts.map +1 -0
  393. package/dist/core/web/web-export.js +112 -0
  394. package/dist/core/web/web-export.js.map +1 -0
  395. package/dist/core/web/web-server.d.ts +34 -0
  396. package/dist/core/web/web-server.d.ts.map +1 -0
  397. package/dist/core/web/web-server.js +182 -0
  398. package/dist/core/web/web-server.js.map +1 -0
  399. package/dist/core/web/web-static.d.ts +20 -0
  400. package/dist/core/web/web-static.d.ts.map +1 -0
  401. package/dist/core/web/web-static.js +104 -0
  402. package/dist/core/web/web-static.js.map +1 -0
  403. package/dist/harness/{agy.d.ts → agy/agy.d.ts} +8 -6
  404. package/dist/harness/agy/agy.d.ts.map +1 -0
  405. package/dist/harness/{agy.js → agy/agy.js} +49 -34
  406. package/dist/harness/agy/agy.js.map +1 -0
  407. package/dist/harness/claude/claude-turns.d.ts +29 -0
  408. package/dist/harness/claude/claude-turns.d.ts.map +1 -0
  409. package/dist/harness/claude/claude-turns.js +162 -0
  410. package/dist/harness/claude/claude-turns.js.map +1 -0
  411. package/dist/harness/claude/claude-usage.d.ts +12 -0
  412. package/dist/harness/claude/claude-usage.d.ts.map +1 -0
  413. package/dist/harness/claude/claude-usage.js +144 -0
  414. package/dist/harness/claude/claude-usage.js.map +1 -0
  415. package/dist/harness/codex/codex-observe-usage.d.ts +6 -0
  416. package/dist/harness/codex/codex-observe-usage.d.ts.map +1 -0
  417. package/dist/harness/codex/codex-observe-usage.js +215 -0
  418. package/dist/harness/codex/codex-observe-usage.js.map +1 -0
  419. package/dist/harness/codex/codex-prompt.d.ts +17 -0
  420. package/dist/harness/codex/codex-prompt.d.ts.map +1 -0
  421. package/dist/harness/codex/codex-prompt.js +43 -0
  422. package/dist/harness/codex/codex-prompt.js.map +1 -0
  423. package/dist/harness/codex/codex-stream.d.ts +23 -0
  424. package/dist/harness/codex/codex-stream.d.ts.map +1 -0
  425. package/dist/harness/codex/codex-stream.js +182 -0
  426. package/dist/harness/codex/codex-stream.js.map +1 -0
  427. package/dist/harness/codex/codex-usage.d.ts +26 -0
  428. package/dist/harness/codex/codex-usage.d.ts.map +1 -0
  429. package/dist/harness/codex/codex-usage.js +122 -0
  430. package/dist/harness/codex/codex-usage.js.map +1 -0
  431. package/dist/harness/codex/codex.d.ts +16 -0
  432. package/dist/harness/codex/codex.d.ts.map +1 -0
  433. package/dist/harness/codex/codex.js +92 -0
  434. package/dist/harness/codex/codex.js.map +1 -0
  435. package/dist/harness/index.d.ts +11 -2
  436. package/dist/harness/index.d.ts.map +1 -1
  437. package/dist/harness/index.js +24 -9
  438. package/dist/harness/index.js.map +1 -1
  439. package/dist/harness/mock.d.ts +5 -2
  440. package/dist/harness/mock.d.ts.map +1 -1
  441. package/dist/harness/mock.js +10 -11
  442. package/dist/harness/mock.js.map +1 -1
  443. package/dist/harness/opencode/opencode-observe-usage.d.ts +4 -0
  444. package/dist/harness/opencode/opencode-observe-usage.d.ts.map +1 -0
  445. package/dist/harness/opencode/opencode-observe-usage.js +100 -0
  446. package/dist/harness/opencode/opencode-observe-usage.js.map +1 -0
  447. package/dist/harness/opencode/opencode-usage.d.ts +24 -0
  448. package/dist/harness/opencode/opencode-usage.d.ts.map +1 -0
  449. package/dist/harness/opencode/opencode-usage.js +181 -0
  450. package/dist/harness/opencode/opencode-usage.js.map +1 -0
  451. package/dist/harness/{opencode.d.ts → opencode/opencode.d.ts} +10 -7
  452. package/dist/harness/opencode/opencode.d.ts.map +1 -0
  453. package/dist/harness/{opencode.js → opencode/opencode.js} +159 -70
  454. package/dist/harness/opencode/opencode.js.map +1 -0
  455. package/dist/harness/pi/pi-args.d.ts +9 -0
  456. package/dist/harness/pi/pi-args.d.ts.map +1 -0
  457. package/dist/harness/pi/pi-args.js +33 -0
  458. package/dist/harness/pi/pi-args.js.map +1 -0
  459. package/dist/harness/pi/pi-stream.d.ts +27 -0
  460. package/dist/harness/pi/pi-stream.d.ts.map +1 -0
  461. package/dist/harness/pi/pi-stream.js +176 -0
  462. package/dist/harness/pi/pi-stream.js.map +1 -0
  463. package/dist/harness/pi/pi-tools.d.ts +5 -0
  464. package/dist/harness/pi/pi-tools.d.ts.map +1 -0
  465. package/dist/harness/pi/pi-tools.js +31 -0
  466. package/dist/harness/pi/pi-tools.js.map +1 -0
  467. package/dist/harness/pi/pi.d.ts +11 -0
  468. package/dist/harness/pi/pi.d.ts.map +1 -0
  469. package/dist/harness/pi/pi.js +109 -0
  470. package/dist/harness/pi/pi.js.map +1 -0
  471. package/dist/harness/prompt.d.ts +11 -0
  472. package/dist/harness/prompt.d.ts.map +1 -0
  473. package/dist/harness/prompt.js +105 -0
  474. package/dist/harness/prompt.js.map +1 -0
  475. package/dist/harness/types.d.ts +287 -8
  476. package/dist/harness/types.d.ts.map +1 -1
  477. package/dist/harness/types.js +125 -0
  478. package/dist/harness/types.js.map +1 -1
  479. package/dist/index.d.ts +13 -2
  480. package/dist/index.d.ts.map +1 -1
  481. package/dist/index.js +8 -1
  482. package/dist/index.js.map +1 -1
  483. package/dist/watcher/archive-verify.d.ts +9 -0
  484. package/dist/watcher/archive-verify.d.ts.map +1 -0
  485. package/dist/watcher/archive-verify.js +80 -0
  486. package/dist/watcher/archive-verify.js.map +1 -0
  487. package/dist/watcher/archiver.d.ts +14 -2
  488. package/dist/watcher/archiver.d.ts.map +1 -1
  489. package/dist/watcher/archiver.js +112 -33
  490. package/dist/watcher/archiver.js.map +1 -1
  491. package/dist/watcher/attempt.d.ts +19 -0
  492. package/dist/watcher/attempt.d.ts.map +1 -0
  493. package/dist/watcher/attempt.js +94 -0
  494. package/dist/watcher/attempt.js.map +1 -0
  495. package/dist/watcher/auto-retry.d.ts +11 -0
  496. package/dist/watcher/auto-retry.d.ts.map +1 -0
  497. package/dist/watcher/auto-retry.js +180 -0
  498. package/dist/watcher/auto-retry.js.map +1 -0
  499. package/dist/watcher/build.d.ts +24 -0
  500. package/dist/watcher/build.d.ts.map +1 -0
  501. package/dist/watcher/build.js +169 -0
  502. package/dist/watcher/build.js.map +1 -0
  503. package/dist/watcher/change-verify.d.ts +25 -0
  504. package/dist/watcher/change-verify.d.ts.map +1 -0
  505. package/dist/watcher/change-verify.js +57 -0
  506. package/dist/watcher/change-verify.js.map +1 -0
  507. package/dist/watcher/dev.d.ts +51 -0
  508. package/dist/watcher/dev.d.ts.map +1 -0
  509. package/dist/watcher/dev.js +124 -0
  510. package/dist/watcher/dev.js.map +1 -0
  511. package/dist/watcher/failure-reason.d.ts +7 -0
  512. package/dist/watcher/failure-reason.d.ts.map +1 -0
  513. package/dist/watcher/failure-reason.js +2 -0
  514. package/dist/watcher/failure-reason.js.map +1 -0
  515. package/dist/watcher/fingerprint.d.ts +19 -0
  516. package/dist/watcher/fingerprint.d.ts.map +1 -0
  517. package/dist/watcher/fingerprint.js +53 -0
  518. package/dist/watcher/fingerprint.js.map +1 -0
  519. package/dist/watcher/heartbeat.d.ts +33 -0
  520. package/dist/watcher/heartbeat.d.ts.map +1 -0
  521. package/dist/watcher/heartbeat.js +135 -0
  522. package/dist/watcher/heartbeat.js.map +1 -0
  523. package/dist/watcher/lock.d.ts +10 -0
  524. package/dist/watcher/lock.d.ts.map +1 -0
  525. package/dist/watcher/lock.js +14 -0
  526. package/dist/watcher/lock.js.map +1 -0
  527. package/dist/watcher/loop.d.ts +26 -6
  528. package/dist/watcher/loop.d.ts.map +1 -1
  529. package/dist/watcher/loop.js +154 -37
  530. package/dist/watcher/loop.js.map +1 -1
  531. package/dist/watcher/measures.d.ts +46 -0
  532. package/dist/watcher/measures.d.ts.map +1 -0
  533. package/dist/watcher/measures.js +203 -0
  534. package/dist/watcher/measures.js.map +1 -0
  535. package/dist/watcher/outcome.d.ts +32 -0
  536. package/dist/watcher/outcome.d.ts.map +1 -0
  537. package/dist/watcher/outcome.js +127 -0
  538. package/dist/watcher/outcome.js.map +1 -0
  539. package/dist/watcher/regression.d.ts +43 -0
  540. package/dist/watcher/regression.d.ts.map +1 -0
  541. package/dist/watcher/regression.js +175 -0
  542. package/dist/watcher/regression.js.map +1 -0
  543. package/dist/watcher/runner.d.ts +6 -68
  544. package/dist/watcher/runner.d.ts.map +1 -1
  545. package/dist/watcher/runner.js +74 -523
  546. package/dist/watcher/runner.js.map +1 -1
  547. package/dist/watcher/spawn.d.ts +48 -0
  548. package/dist/watcher/spawn.d.ts.map +1 -0
  549. package/dist/watcher/spawn.js +130 -0
  550. package/dist/watcher/spawn.js.map +1 -0
  551. package/dist/watcher/task-verify.d.ts +59 -0
  552. package/dist/watcher/task-verify.d.ts.map +1 -0
  553. package/dist/watcher/task-verify.js +108 -0
  554. package/dist/watcher/task-verify.js.map +1 -0
  555. package/dist/watcher/verify.d.ts +44 -0
  556. package/dist/watcher/verify.d.ts.map +1 -0
  557. package/dist/watcher/verify.js +156 -0
  558. package/dist/watcher/verify.js.map +1 -0
  559. package/package.json +21 -9
  560. package/templates/PLANNER.md +77 -0
  561. package/templates/openspec/config.yaml +24 -0
  562. package/templates/openspec/schemas/osq/README.md +30 -0
  563. package/templates/openspec/schemas/osq/schema.yaml +133 -0
  564. package/templates/openspec/schemas/osq/templates/proposal.md +66 -0
  565. package/templates/openspec/schemas/osq/templates/spec.md +13 -0
  566. package/templates/openspec/schemas/osq/templates/tasks.md +11 -0
  567. package/templates/proposal.md +66 -0
  568. package/templates/tasks.md +5 -0
  569. package/ui/dist/assets/index-CZYeQ8la.js +9 -0
  570. package/ui/dist/assets/index-D6zVSjO7.css +1 -0
  571. package/ui/dist/index.html +14 -0
  572. package/dist/core/approve.d.ts +0 -11
  573. package/dist/core/approve.d.ts.map +0 -1
  574. package/dist/core/approve.js +0 -52
  575. package/dist/core/approve.js.map +0 -1
  576. package/dist/core/config.d.ts.map +0 -1
  577. package/dist/core/config.js.map +0 -1
  578. package/dist/core/hasher.d.ts +0 -4
  579. package/dist/core/hasher.d.ts.map +0 -1
  580. package/dist/core/hasher.js.map +0 -1
  581. package/dist/core/init.d.ts +0 -12
  582. package/dist/core/init.d.ts.map +0 -1
  583. package/dist/core/init.js +0 -151
  584. package/dist/core/init.js.map +0 -1
  585. package/dist/core/linter.d.ts +0 -8
  586. package/dist/core/linter.d.ts.map +0 -1
  587. package/dist/core/linter.js +0 -100
  588. package/dist/core/linter.js.map +0 -1
  589. package/dist/core/lock.d.ts.map +0 -1
  590. package/dist/core/lock.js.map +0 -1
  591. package/dist/core/logger.d.ts.map +0 -1
  592. package/dist/core/logger.js.map +0 -1
  593. package/dist/core/new.d.ts.map +0 -1
  594. package/dist/core/new.js +0 -79
  595. package/dist/core/new.js.map +0 -1
  596. package/dist/core/parser.d.ts +0 -32
  597. package/dist/core/parser.d.ts.map +0 -1
  598. package/dist/core/parser.js +0 -87
  599. package/dist/core/parser.js.map +0 -1
  600. package/dist/core/report.d.ts +0 -54
  601. package/dist/core/report.d.ts.map +0 -1
  602. package/dist/core/report.js +0 -475
  603. package/dist/core/report.js.map +0 -1
  604. package/dist/core/show.d.ts +0 -50
  605. package/dist/core/show.d.ts.map +0 -1
  606. package/dist/core/show.js +0 -374
  607. package/dist/core/show.js.map +0 -1
  608. package/dist/core/state.d.ts +0 -25
  609. package/dist/core/state.d.ts.map +0 -1
  610. package/dist/core/state.js +0 -180
  611. package/dist/core/state.js.map +0 -1
  612. package/dist/core/status.d.ts +0 -10
  613. package/dist/core/status.d.ts.map +0 -1
  614. package/dist/core/status.js +0 -106
  615. package/dist/core/status.js.map +0 -1
  616. package/dist/harness/agy.d.ts.map +0 -1
  617. package/dist/harness/agy.js.map +0 -1
  618. package/dist/harness/opencode.d.ts.map +0 -1
  619. package/dist/harness/opencode.js.map +0 -1
@@ -0,0 +1,704 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { DEFAULT_CONFIG } from '../foundation/config.js';
4
+ import { readPlanningSessions } from '../report/planning.js';
5
+ import { formatDuration } from '../report/report.js';
6
+ import { parseFrontmatter, parseSpecMdFromFolder, parseTaskMd } from '../spec/parser.js';
7
+ import { getArchiveDir, getChangesDir, getRejectedDir } from './layout.js';
8
+ import { deriveSpecState } from './state.js';
9
+ function matchesFolder(folderName, query) {
10
+ const trimmed = query.trim();
11
+ const num = Number.parseInt(trimmed, 10);
12
+ const padded = !Number.isNaN(num) ? String(num).padStart(3, '0') : trimmed;
13
+ if (folderName === trimmed || folderName === padded)
14
+ return true;
15
+ if (folderName.startsWith(`${trimmed}-`) || folderName.startsWith(`${padded}-`))
16
+ return true;
17
+ if (folderName.endsWith(`-${trimmed}`))
18
+ return true;
19
+ return false;
20
+ }
21
+ function numericTaskTarget(value) {
22
+ if (typeof value === 'number' && Number.isInteger(value) && value >= 0) {
23
+ return String(value);
24
+ }
25
+ if (typeof value === 'string' && /^\d+$/.test(value.trim())) {
26
+ return value.trim();
27
+ }
28
+ return null;
29
+ }
30
+ function stringList(value) {
31
+ if (!Array.isArray(value))
32
+ return [];
33
+ return value
34
+ .filter((entry) => typeof entry === 'string' && entry.trim() !== '')
35
+ .map((entry) => entry.trim());
36
+ }
37
+ function attributionEntries(value) {
38
+ if (!Array.isArray(value))
39
+ return [];
40
+ const entries = [];
41
+ for (const entry of value) {
42
+ if (entry === null || typeof entry !== 'object' || Array.isArray(entry))
43
+ continue;
44
+ const { path: rawPath, attribution: rawAttribution } = entry;
45
+ if (typeof rawPath !== 'string' || rawPath.trim() === '')
46
+ continue;
47
+ const attribution = typeof rawAttribution === 'string' && rawAttribution.trim() !== ''
48
+ ? rawAttribution.trim()
49
+ : typeof rawAttribution === 'number' && Number.isFinite(rawAttribution)
50
+ ? String(rawAttribution)
51
+ : 'unknown';
52
+ entries.push({ path: rawPath.trim(), attribution });
53
+ }
54
+ return entries;
55
+ }
56
+ /**
57
+ * Projects one typed `recertification` event into a display row. Only explicit,
58
+ * well-formed values are surfaced; everything else is unavailable. The row is
59
+ * built solely from the already parsed event, never from marker files.
60
+ */
61
+ function buildRecertification(taskNumber, event) {
62
+ const data = event.data ?? {};
63
+ const differingPaths = [...new Set(stringList(data.differingPaths))].sort();
64
+ const recorded = attributionEntries(data.attribution);
65
+ const byPath = new Map();
66
+ for (const entry of recorded) {
67
+ if (!byPath.has(entry.path))
68
+ byPath.set(entry.path, entry.attribution);
69
+ }
70
+ const allPaths = [...new Set([...differingPaths, ...recorded.map((entry) => entry.path)])].sort();
71
+ const attribution = allPaths.map((path) => ({
72
+ path,
73
+ attribution: byPath.get(path) ?? 'unknown',
74
+ }));
75
+ const rawTimestamp = typeof event.timestamp === 'string' ? event.timestamp.trim() : '';
76
+ const timestamp = rawTimestamp && !Number.isNaN(new Date(rawTimestamp).getTime()) ? rawTimestamp : null;
77
+ const outcome = data.outcome === 'passed' ? 'passed' : data.outcome === 'requeued' ? 'requeued' : null;
78
+ const verify = typeof data.command === 'string' && data.command.trim() !== '' ? data.command.trim() : null;
79
+ const exitCode = typeof data.exitCode === 'number' && Number.isFinite(data.exitCode) ? data.exitCode : null;
80
+ const timedOut = typeof data.timedOut === 'boolean' ? data.timedOut : null;
81
+ return {
82
+ taskNumber,
83
+ timestamp,
84
+ outcome,
85
+ differingPaths,
86
+ attribution,
87
+ verify,
88
+ exitCode,
89
+ timedOut,
90
+ };
91
+ }
92
+ export async function resolveSpecFolder(projectRoot, idOrPrefix, config = DEFAULT_CONFIG) {
93
+ const trimmed = idOrPrefix.trim();
94
+ if (!trimmed) {
95
+ throw new Error('Spec ID or prefix cannot be empty');
96
+ }
97
+ const specsDir = getChangesDir(config.paths.openspecRoot, projectRoot);
98
+ const archiveDir = getArchiveDir(config.paths.openspecRoot, projectRoot);
99
+ const rejectedDir = getRejectedDir(config.paths.openspecRoot, projectRoot);
100
+ // If directly pointing to an existing folder
101
+ if (path.isAbsolute(trimmed) || trimmed.includes(path.sep)) {
102
+ const candidatePath = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed);
103
+ const stat = await fs.stat(candidatePath).catch(() => null);
104
+ if (stat?.isDirectory()) {
105
+ const location = candidatePath === archiveDir || candidatePath.startsWith(`${archiveDir}${path.sep}`)
106
+ ? 'archived'
107
+ : candidatePath === rejectedDir || candidatePath.startsWith(`${rejectedDir}${path.sep}`)
108
+ ? 'rejected'
109
+ : 'active';
110
+ return { folderPath: candidatePath, isArchived: location === 'archived', location };
111
+ }
112
+ }
113
+ // 1. Search active specs
114
+ let activeEntries = [];
115
+ try {
116
+ activeEntries = await fs.readdir(specsDir);
117
+ }
118
+ catch {
119
+ activeEntries = [];
120
+ }
121
+ const archiveRel = path.relative(specsDir, archiveDir);
122
+ const archiveFolder = !archiveRel.startsWith('..') && !path.isAbsolute(archiveRel)
123
+ ? archiveRel.split(path.sep)[0]
124
+ : 'archive';
125
+ const rejectedRel = path.relative(specsDir, rejectedDir);
126
+ const rejectedFolder = !rejectedRel.startsWith('..') && !path.isAbsolute(rejectedRel)
127
+ ? rejectedRel.split(path.sep)[0]
128
+ : 'rejected';
129
+ for (const entry of activeEntries) {
130
+ if (entry.startsWith('.') ||
131
+ entry.startsWith('_') ||
132
+ entry === archiveFolder ||
133
+ entry === rejectedFolder) {
134
+ continue;
135
+ }
136
+ if (matchesFolder(entry, trimmed)) {
137
+ const fullPath = path.join(specsDir, entry);
138
+ const stat = await fs.stat(fullPath).catch(() => null);
139
+ if (stat?.isDirectory()) {
140
+ return { folderPath: fullPath, isArchived: false, location: 'active' };
141
+ }
142
+ }
143
+ }
144
+ // 2. Search archive directory
145
+ const archived = await searchFolder(archiveDir, trimmed, 'archived');
146
+ if (archived)
147
+ return archived;
148
+ // 3. Search rejected directory
149
+ const rejected = await searchFolder(rejectedDir, trimmed, 'rejected');
150
+ if (rejected)
151
+ return rejected;
152
+ throw new Error(`Spec "${idOrPrefix}" not found in specs or archive`);
153
+ }
154
+ /** Search one canonical location directory for a folder matching the query. */
155
+ async function searchFolder(dir, query, location) {
156
+ let entries = [];
157
+ try {
158
+ entries = await fs.readdir(dir);
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ for (const entry of entries) {
164
+ if (entry.startsWith('.') || entry.startsWith('_')) {
165
+ continue;
166
+ }
167
+ if (matchesFolder(entry, query)) {
168
+ const fullPath = path.join(dir, entry);
169
+ const stat = await fs.stat(fullPath).catch(() => null);
170
+ if (stat?.isDirectory()) {
171
+ return { folderPath: fullPath, isArchived: location === 'archived', location };
172
+ }
173
+ }
174
+ }
175
+ return null;
176
+ }
177
+ export async function getSpecDetails(projectRoot, specIdOrPrefix, config = DEFAULT_CONFIG) {
178
+ const { folderPath, location } = await resolveSpecFolder(projectRoot, specIdOrPrefix, config);
179
+ return buildSpecDetails(projectRoot, folderPath, location, config);
180
+ }
181
+ /**
182
+ * Builds the complete change detail for an already resolved folder in any of
183
+ * the three canonical locations. Selector discovery stays with the caller.
184
+ */
185
+ export async function getSpecDetailsFromFolder(projectRoot, folderPath, location, config = DEFAULT_CONFIG) {
186
+ return buildSpecDetails(projectRoot, folderPath, location, config);
187
+ }
188
+ async function buildSpecDetails(projectRoot, folderPath, location, _config) {
189
+ const isArchived = location === 'archived';
190
+ const folderName = path.basename(folderPath);
191
+ const idMatch = folderName.match(/^(\d+)/);
192
+ const id = idMatch ? idMatch[1] : folderName;
193
+ const specData = await parseSpecMdFromFolder(folderPath);
194
+ if (!specData) {
195
+ throw new Error(`Neither proposal.md nor spec.md found in ${folderPath}`);
196
+ }
197
+ // Capability writes are declared solely by delta spec folders under `specs/`.
198
+ const deltasDir = path.join(folderPath, 'specs');
199
+ const writtenCapabilities = (await fs.readdir(deltasDir, { withFileTypes: true }).catch(() => []))
200
+ .filter((entry) => entry.isDirectory())
201
+ .map((entry) => entry.name)
202
+ .sort();
203
+ const runDir = path.join(folderPath, '.run');
204
+ const approvedPath = path.join(runDir, 'approved');
205
+ let approvedHash = null;
206
+ try {
207
+ const hashContent = await fs.readFile(approvedPath, 'utf8');
208
+ approvedHash = hashContent.trim() || null;
209
+ }
210
+ catch { }
211
+ // Correlated planning lifecycle pairs in start order. A malformed or missing
212
+ // log yields an empty list and never blocks the remaining details.
213
+ const planningSessions = (await readPlanningSessions(folderPath)).flatMap((session) => {
214
+ const started = session.started;
215
+ if (!started)
216
+ return [];
217
+ return [
218
+ {
219
+ sessionId: session.sessionId,
220
+ startTime: started.timestamp,
221
+ harness: started.data.harness,
222
+ model: started.data.model,
223
+ ...(started.data.agent ? { agent: started.data.agent } : {}),
224
+ exitCode: session.exited?.data.exitCode ?? null,
225
+ wallSeconds: session.exited?.data.wallSeconds ?? null,
226
+ },
227
+ ];
228
+ });
229
+ const tasksDir = path.join(folderPath, 'tasks');
230
+ let taskEntries = [];
231
+ try {
232
+ taskEntries = (await fs.readdir(tasksDir))
233
+ .filter((e) => e.endsWith('.md'))
234
+ .sort((a, b) => {
235
+ const numA = Number.parseInt(a, 10);
236
+ const numB = Number.parseInt(b, 10);
237
+ if (!Number.isNaN(numA) && !Number.isNaN(numB)) {
238
+ return numA - numB;
239
+ }
240
+ return a.localeCompare(b);
241
+ });
242
+ }
243
+ catch { }
244
+ // Parse events
245
+ const eventsDir = path.join(runDir, 'events');
246
+ let eventFiles = [];
247
+ try {
248
+ eventFiles = (await fs.readdir(eventsDir))
249
+ .filter((e) => e.endsWith('.jsonl'))
250
+ .sort((a, b) => {
251
+ const numA = Number.parseInt(a, 10);
252
+ const numB = Number.parseInt(b, 10);
253
+ if (!Number.isNaN(numA) && !Number.isNaN(numB)) {
254
+ return numA - numB;
255
+ }
256
+ return a.localeCompare(b);
257
+ });
258
+ }
259
+ catch { }
260
+ const taskEventsMap = new Map();
261
+ const timeline = [];
262
+ // Typed recertification decisions from numbered task streams only, kept with
263
+ // their original stream order so ties break deterministically.
264
+ const recertificationEvents = [];
265
+ let eventSeq = 0;
266
+ for (const eventFile of eventFiles) {
267
+ const taskNum = path.basename(eventFile, '.jsonl');
268
+ const eventFilePath = path.join(eventsDir, eventFile);
269
+ try {
270
+ const fileContent = await fs.readFile(eventFilePath, 'utf8');
271
+ const lines = fileContent.split('\n');
272
+ const taskEvents = [];
273
+ for (const line of lines) {
274
+ const trimmed = line.trim();
275
+ if (!trimmed)
276
+ continue;
277
+ try {
278
+ const parsed = JSON.parse(trimmed);
279
+ const event = {
280
+ taskNumber: String(parsed.taskNumber || taskNum),
281
+ type: String(parsed.type || 'unknown'),
282
+ timestamp: String(parsed.timestamp || ''),
283
+ data: typeof parsed.data === 'object' && parsed.data !== null
284
+ ? parsed.data
285
+ : undefined,
286
+ };
287
+ taskEvents.push(event);
288
+ timeline.push(event);
289
+ if (event.type === 'recertification' && /^\d+$/.test(taskNum)) {
290
+ recertificationEvents.push({ seq: eventSeq, streamTask: taskNum, event });
291
+ }
292
+ eventSeq++;
293
+ }
294
+ catch { }
295
+ }
296
+ taskEventsMap.set(taskNum, taskEvents);
297
+ }
298
+ catch { }
299
+ }
300
+ // Sort overall timeline chronologically
301
+ timeline.sort((a, b) => {
302
+ const timeA = new Date(a.timestamp).getTime();
303
+ const timeB = new Date(b.timestamp).getTime();
304
+ if (!Number.isNaN(timeA) && !Number.isNaN(timeB) && timeA !== timeB) {
305
+ return timeA - timeB;
306
+ }
307
+ return a.timestamp.localeCompare(b.timestamp);
308
+ });
309
+ const recertifications = recertificationEvents
310
+ .map(({ seq, streamTask, event }) => ({
311
+ seq,
312
+ row: buildRecertification(numericTaskTarget(event.data?.task) ?? streamTask, event),
313
+ }))
314
+ .sort((a, b) => {
315
+ const timeA = a.row.timestamp ? new Date(a.row.timestamp).getTime() : null;
316
+ const timeB = b.row.timestamp ? new Date(b.row.timestamp).getTime() : null;
317
+ if (timeA !== null && timeB !== null && timeA !== timeB) {
318
+ return timeA - timeB;
319
+ }
320
+ const numA = Number.parseInt(a.row.taskNumber, 10);
321
+ const numB = Number.parseInt(b.row.taskNumber, 10);
322
+ if (numA !== numB) {
323
+ return numA - numB;
324
+ }
325
+ return a.seq - b.seq;
326
+ })
327
+ .map((entry) => entry.row);
328
+ const tasks = [];
329
+ for (const taskFileName of taskEntries) {
330
+ const taskNumber = taskFileName.replace(/\.md$/, '');
331
+ const taskPath = path.join(tasksDir, taskFileName);
332
+ const taskContent = await fs.readFile(taskPath, 'utf8');
333
+ const taskData = parseTaskMd(taskContent);
334
+ // Derive task status
335
+ let status = 'pending';
336
+ const donePath = path.join(runDir, 'done', taskNumber);
337
+ const isDone = await fs
338
+ .stat(donePath)
339
+ .then(() => true)
340
+ .catch(() => false);
341
+ const deadPath = path.join(runDir, 'dead', `${taskNumber}.md`);
342
+ let deadReason;
343
+ let deadDiagnostic;
344
+ let regressedReason;
345
+ let regressedDiagnostic;
346
+ const regressedPath = path.join(runDir, 'regressed', `${taskNumber}.md`);
347
+ const regressedContent = await fs.readFile(regressedPath, 'utf8').catch(() => null);
348
+ const deadContent = await fs.readFile(deadPath, 'utf8').catch(() => null);
349
+ if (regressedContent !== null) {
350
+ status = 'regressed';
351
+ const parsedRegressed = parseFrontmatter(regressedContent);
352
+ regressedReason =
353
+ typeof parsedRegressed.data.reason === 'string' ? parsedRegressed.data.reason : undefined;
354
+ regressedDiagnostic = parsedRegressed.body.trim() || undefined;
355
+ }
356
+ else if (deadContent !== null) {
357
+ status = 'dead';
358
+ const parsedDead = parseFrontmatter(deadContent);
359
+ deadReason = typeof parsedDead.data.reason === 'string' ? parsedDead.data.reason : undefined;
360
+ deadDiagnostic = parsedDead.body.trim() || undefined;
361
+ }
362
+ else if (isDone) {
363
+ status = 'done';
364
+ }
365
+ else {
366
+ const runningPath = path.join(runDir, 'running', `${taskNumber}.pid`);
367
+ const isRunning = await fs
368
+ .stat(runningPath)
369
+ .then(() => true)
370
+ .catch(() => false);
371
+ if (isRunning) {
372
+ status = 'running';
373
+ }
374
+ else {
375
+ status = 'pending';
376
+ }
377
+ }
378
+ // Read result file if present
379
+ const resultPath = path.join(runDir, 'results', `${taskNumber}.md`);
380
+ let resultContent;
381
+ const rawResult = await fs.readFile(resultPath, 'utf8').catch(() => null);
382
+ if (rawResult !== null) {
383
+ resultContent = rawResult.trim() || undefined;
384
+ }
385
+ const taskEvents = taskEventsMap.get(taskNumber) || [];
386
+ tasks.push({
387
+ taskNumber,
388
+ fileName: taskFileName,
389
+ title: taskData.title,
390
+ status,
391
+ verify: taskData.verify,
392
+ scope: taskData.scope,
393
+ entry: taskData.entry,
394
+ skills: taskData.skills,
395
+ acceptance: taskData.acceptance,
396
+ deadReason,
397
+ deadDiagnostic,
398
+ regressedReason,
399
+ regressedDiagnostic,
400
+ resultContent,
401
+ events: taskEvents,
402
+ });
403
+ }
404
+ // Derive spec status
405
+ let status = 'pending';
406
+ if (isArchived) {
407
+ status = 'done';
408
+ }
409
+ else if (!approvedHash) {
410
+ status = 'unapproved';
411
+ }
412
+ else if (tasks.some((t) => t.status === 'regressed')) {
413
+ status = 'regressed';
414
+ }
415
+ else if (tasks.some((t) => t.status === 'dead')) {
416
+ status = 'dead';
417
+ }
418
+ else if (tasks.some((t) => t.status === 'running')) {
419
+ status = 'running';
420
+ }
421
+ else if (tasks.length > 0 && tasks.every((t) => t.status === 'done')) {
422
+ status = 'done';
423
+ }
424
+ else {
425
+ try {
426
+ const derived = await deriveSpecState(projectRoot, folderPath);
427
+ status = derived.status;
428
+ }
429
+ catch {
430
+ status = 'pending';
431
+ }
432
+ }
433
+ return {
434
+ id,
435
+ folderName,
436
+ folderPath,
437
+ isArchived,
438
+ location,
439
+ title: specData.title,
440
+ status,
441
+ approvedHash,
442
+ dependsOn: specData.dependsOn,
443
+ features: { reads: specData.features.reads, writes: writtenCapabilities },
444
+ goal: specData.goal,
445
+ contract: specData.contract,
446
+ nonGoals: specData.nonGoals,
447
+ delta: specData.delta,
448
+ tasks,
449
+ planningSessions,
450
+ recertifications,
451
+ timeline,
452
+ };
453
+ }
454
+ /**
455
+ * Projects the latest pre-spawn `verify_ran` event of one task into the
456
+ * `Pre-spawn verify:` show line. Returns null when the task recorded no
457
+ * pre-spawn result, so output for every other task stays unchanged. Only the
458
+ * already parsed event stream is read; missing or malformed values render as
459
+ * unavailable rather than being guessed.
460
+ */
461
+ function formatPreSpawnVerify(events) {
462
+ let latest;
463
+ for (const event of events) {
464
+ if (event.type === 'verify_ran' && event.data?.phase === 'pre_spawn') {
465
+ latest = event;
466
+ }
467
+ }
468
+ if (!latest)
469
+ return null;
470
+ const data = latest.data ?? {};
471
+ const exitCode = typeof data.exitCode === 'number' && Number.isFinite(data.exitCode)
472
+ ? String(data.exitCode)
473
+ : 'unavailable';
474
+ const expected = typeof data.expected === 'string' && data.expected.trim() !== ''
475
+ ? data.expected.trim()
476
+ : 'unavailable';
477
+ const outcome = data.mismatch === true ? 'mismatch' : 'matched';
478
+ const missing = formatMissingPaths(data.missingPaths);
479
+ return ` Pre-spawn verify: exit ${exitCode}, expected ${expected}, ${outcome}${missing ?? ''}`;
480
+ }
481
+ /**
482
+ * Renders the `missing <path>, <path>` suffix for a pre-spawn event's recorded
483
+ * missing named paths. Only a non-empty array whose every entry is a non-empty
484
+ * string qualifies, so an empty, absent, or malformed value contributes nothing
485
+ * and leaves the pre-spawn line exactly as it was.
486
+ */
487
+ function formatMissingPaths(value) {
488
+ if (!Array.isArray(value) || value.length === 0)
489
+ return null;
490
+ if (!value.every((entry) => typeof entry === 'string' && entry.trim() !== '')) {
491
+ return null;
492
+ }
493
+ return `, missing ${value.map((entry) => entry.trim()).join(', ')}`;
494
+ }
495
+ /**
496
+ * Counts a task's `retry` events split into total and automatic. Automatic
497
+ * retries are exactly those whose event data carries `automatic: true`.
498
+ * Returns null when the task recorded no retry, so every other task's output
499
+ * stays unchanged.
500
+ */
501
+ function retryCounts(events) {
502
+ let total = 0;
503
+ let automatic = 0;
504
+ for (const event of events) {
505
+ if (event.type !== 'retry')
506
+ continue;
507
+ total += 1;
508
+ if (event.data?.automatic === true)
509
+ automatic += 1;
510
+ }
511
+ return total > 0 ? { total, automatic } : null;
512
+ }
513
+ /** Projects a task's `retry` events into the `Retries:` line, or null. */
514
+ function formatRetries(events) {
515
+ const counts = retryCounts(events);
516
+ if (!counts)
517
+ return null;
518
+ return ` Retries: ${counts.total} (${counts.automatic} automatic)`;
519
+ }
520
+ /**
521
+ * Projects the task's latest `stuck` event into the `Stuck:` line, but only
522
+ * while it is still the task's current state. A later `retry` event means a
523
+ * human already retried the task, so the line disappears. Returns null when
524
+ * the task recorded no stuck event or is no longer stuck.
525
+ */
526
+ function formatStuck(events) {
527
+ let stuck;
528
+ let stuckIndex = -1;
529
+ let lastRetry = -1;
530
+ for (let index = 0; index < events.length; index += 1) {
531
+ const event = events[index];
532
+ if (event.type === 'retry') {
533
+ lastRetry = index;
534
+ }
535
+ else if (event.type === 'stuck') {
536
+ stuck = event;
537
+ stuckIndex = index;
538
+ }
539
+ }
540
+ if (!stuck || lastRetry > stuckIndex)
541
+ return null;
542
+ const fingerprint = typeof stuck.data?.fingerprint === 'string' && stuck.data.fingerprint.trim() !== ''
543
+ ? stuck.data.fingerprint.trim()
544
+ : 'unavailable';
545
+ return ` Stuck: same failure twice (${fingerprint})`;
546
+ }
547
+ function formatEventData(data) {
548
+ if (!data || Object.keys(data).length === 0)
549
+ return '';
550
+ const entries = Object.entries(data).map(([k, v]) => `${k}: ${v}`);
551
+ return ` (${entries.join(', ')})`;
552
+ }
553
+ export function formatSpecDetails(details) {
554
+ const lines = [];
555
+ const location = details.isArchived ? 'archived' : 'active';
556
+ const approval = details.approvedHash ? `approved (${details.approvedHash})` : 'unapproved';
557
+ lines.push(`Spec: ${details.folderName} (${details.id})`);
558
+ lines.push(`Title: ${details.title}`);
559
+ lines.push(`Status: [${details.status}]`);
560
+ lines.push(`Location: ${location}`);
561
+ lines.push(`Approval: ${approval}`);
562
+ const dependsOnStr = details.dependsOn.length > 0 ? details.dependsOn.join(', ') : 'none';
563
+ lines.push(`Depends on: ${dependsOnStr}`);
564
+ lines.push('Features:');
565
+ const readsStr = details.features.reads.length > 0 ? details.features.reads.join(', ') : 'none';
566
+ const writesStr = details.features.writes.length > 0 ? details.features.writes.join(', ') : 'none';
567
+ lines.push(` Reads: ${readsStr}`);
568
+ lines.push(` Writes: ${writesStr}`);
569
+ if (details.goal) {
570
+ lines.push('');
571
+ lines.push('Goal:');
572
+ const goalLines = details.goal.split('\n');
573
+ for (const gLine of goalLines) {
574
+ lines.push(` ${gLine}`);
575
+ }
576
+ }
577
+ if (details.contract) {
578
+ lines.push('');
579
+ lines.push('Contract:');
580
+ const contractLines = details.contract.split('\n');
581
+ for (const cLine of contractLines) {
582
+ lines.push(` ${cLine}`);
583
+ }
584
+ }
585
+ lines.push('');
586
+ lines.push('Tasks:');
587
+ if (details.tasks.length === 0) {
588
+ lines.push(' (no tasks)');
589
+ }
590
+ else {
591
+ for (const task of details.tasks) {
592
+ let indicator = '[ ]';
593
+ if (task.status === 'done') {
594
+ indicator = '[x]';
595
+ }
596
+ else if (task.status === 'running') {
597
+ indicator = '[>]';
598
+ }
599
+ else if (task.status === 'dead') {
600
+ indicator = '[!]';
601
+ }
602
+ const deadTag = task.deadReason ? ` (reason: ${task.deadReason})` : '';
603
+ lines.push(` ${indicator} ${task.taskNumber}. ${task.title} [${task.status}]${deadTag}`);
604
+ if (task.verify) {
605
+ lines.push(` Verify: ${task.verify}`);
606
+ }
607
+ const preSpawnVerify = formatPreSpawnVerify(task.events);
608
+ if (preSpawnVerify) {
609
+ lines.push(preSpawnVerify);
610
+ }
611
+ const retries = formatRetries(task.events);
612
+ if (retries) {
613
+ lines.push(retries);
614
+ }
615
+ const stuck = formatStuck(task.events);
616
+ if (stuck) {
617
+ lines.push(stuck);
618
+ }
619
+ if (task.scope.length > 0) {
620
+ lines.push(` Scope: ${task.scope.join(', ')}`);
621
+ }
622
+ if (task.acceptance.length > 0) {
623
+ lines.push(' Acceptance:');
624
+ for (const item of task.acceptance) {
625
+ const itemIndicator = task.status === 'done' ? '[x]' : '[ ]';
626
+ lines.push(` - ${itemIndicator} ${item}`);
627
+ }
628
+ }
629
+ if (task.deadDiagnostic) {
630
+ lines.push(' Failure diagnostic:');
631
+ const diagLines = task.deadDiagnostic.split('\n');
632
+ for (const dLine of diagLines) {
633
+ lines.push(` ${dLine}`);
634
+ }
635
+ }
636
+ if (task.resultContent) {
637
+ lines.push(' Result:');
638
+ const resLines = task.resultContent.split('\n');
639
+ for (const rLine of resLines) {
640
+ lines.push(` ${rLine}`);
641
+ }
642
+ }
643
+ }
644
+ }
645
+ lines.push('');
646
+ lines.push('Planning Sessions:');
647
+ if (details.planningSessions.length === 0) {
648
+ lines.push(' (no planning sessions)');
649
+ }
650
+ else {
651
+ for (const session of details.planningSessions) {
652
+ const agent = session.agent ? ` agent: ${session.agent}` : '';
653
+ const model = session.model ?? 'unavailable';
654
+ const exit = session.exitCode === null ? 'unavailable' : String(session.exitCode);
655
+ const wall = session.wallSeconds === null ? 'unavailable' : formatDuration(session.wallSeconds * 1000);
656
+ lines.push(` ${session.startTime} ${session.harness}/${model}${agent} exit: ${exit} wall: ${wall}`);
657
+ }
658
+ }
659
+ // Derived, append-only recertification view. It is rendered only when typed
660
+ // decisions exist and never replaces the raw event timeline below.
661
+ if (details.recertifications.length > 0) {
662
+ lines.push('');
663
+ lines.push('Recertifications:');
664
+ for (const row of details.recertifications) {
665
+ const label = row.outcome === 'passed'
666
+ ? 'recertified'
667
+ : row.outcome === 'requeued'
668
+ ? 'requeued for agent work'
669
+ : 'unavailable';
670
+ lines.push(` Task ${row.taskNumber} ${row.timestamp ?? 'unavailable'} [${label}]`);
671
+ lines.push(` Verify: ${row.verify ?? 'unavailable'}`);
672
+ lines.push(` Exit code: ${row.exitCode ?? 'unavailable'}`);
673
+ lines.push(` Timed out: ${row.timedOut === null ? 'unavailable' : row.timedOut ? 'yes' : 'no'}`);
674
+ if (row.attribution.length > 0) {
675
+ lines.push(' Differing paths:');
676
+ for (const entry of row.attribution) {
677
+ const attribution = entry.attribution === 'ambiguous' || entry.attribution === 'unknown'
678
+ ? entry.attribution
679
+ : `attributed to task ${entry.attribution}`;
680
+ lines.push(` - ${entry.path} — ${attribution}`);
681
+ }
682
+ }
683
+ }
684
+ }
685
+ lines.push('');
686
+ lines.push('Event Timeline:');
687
+ if (details.timeline.length === 0) {
688
+ lines.push(' (no events recorded)');
689
+ }
690
+ else {
691
+ for (const event of details.timeline) {
692
+ const eventData = formatEventData(event.data);
693
+ lines.push(` ${event.timestamp} [Task ${event.taskNumber}] ${event.type}${eventData}`);
694
+ }
695
+ }
696
+ return lines.join('\n');
697
+ }
698
+ /**
699
+ * Alias for {@link formatSpecDetails} matching the show-output name used by
700
+ * the status-inspection spec. Displays the dead reason (including
701
+ * `undeclared_test_change`) and its failure diagnostic.
702
+ */
703
+ export const formatShowOutput = formatSpecDetails;
704
+ //# sourceMappingURL=show.js.map