spexcode 0.6.2 → 0.6.6

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 (495) hide show
  1. package/README.md +3 -1
  2. package/bin/spex.mjs +4 -0
  3. package/node_modules/@spexcode/session-core/dist/delivery-queue.d.ts +23 -0
  4. package/node_modules/@spexcode/session-core/dist/delivery-queue.js +195 -0
  5. package/node_modules/@spexcode/session-core/dist/index.d.ts +5 -0
  6. package/node_modules/@spexcode/session-core/dist/index.js +5 -0
  7. package/node_modules/@spexcode/session-core/dist/internal.d.ts +3 -0
  8. package/node_modules/@spexcode/session-core/dist/internal.js +3 -0
  9. package/node_modules/@spexcode/session-core/dist/message.d.ts +22 -0
  10. package/node_modules/@spexcode/session-core/dist/message.js +52 -0
  11. package/node_modules/@spexcode/session-core/dist/record-lock.d.ts +7 -0
  12. package/node_modules/@spexcode/session-core/dist/record-lock.js +152 -0
  13. package/node_modules/@spexcode/session-core/dist/runtime-session.d.ts +50 -0
  14. package/node_modules/@spexcode/session-core/dist/runtime-session.js +286 -0
  15. package/node_modules/@spexcode/session-core/dist/session-cursors.d.ts +14 -0
  16. package/node_modules/@spexcode/session-core/dist/session-cursors.js +82 -0
  17. package/node_modules/@spexcode/session-core/dist/session-timeline.d.ts +46 -0
  18. package/node_modules/@spexcode/session-core/dist/session-timeline.js +216 -0
  19. package/node_modules/@spexcode/session-core/package.json +33 -0
  20. package/node_modules/@spexcode/spec-cli/bin/spex.mjs +77 -0
  21. package/node_modules/@spexcode/spec-cli/dist/attach.d.ts +2 -0
  22. package/node_modules/@spexcode/spec-cli/dist/attach.js +48 -0
  23. package/node_modules/@spexcode/spec-cli/dist/claude-headless.d.ts +36 -0
  24. package/node_modules/@spexcode/spec-cli/dist/claude-headless.js +316 -0
  25. package/node_modules/@spexcode/spec-cli/dist/cli.d.ts +1 -0
  26. package/node_modules/@spexcode/spec-cli/dist/cli.js +1908 -0
  27. package/node_modules/@spexcode/spec-cli/dist/client.d.ts +112 -0
  28. package/node_modules/@spexcode/spec-cli/dist/client.js +481 -0
  29. package/node_modules/@spexcode/spec-cli/dist/cockpit.d.ts +7 -0
  30. package/node_modules/@spexcode/spec-cli/dist/cockpit.js +26 -0
  31. package/node_modules/@spexcode/spec-cli/dist/codex-headless.d.ts +1 -0
  32. package/{spec-cli/src/codex-headless.ts → node_modules/@spexcode/spec-cli/dist/codex-headless.js} +3 -9
  33. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.d.ts +58 -0
  34. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.js +798 -0
  35. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.d.ts +1 -0
  36. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.js +90 -0
  37. package/node_modules/@spexcode/spec-cli/dist/contract-filter.d.ts +14 -0
  38. package/node_modules/@spexcode/spec-cli/dist/contract-filter.js +219 -0
  39. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.d.ts +6 -0
  40. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.js +50 -0
  41. package/node_modules/@spexcode/spec-cli/dist/doctor.d.ts +9 -0
  42. package/node_modules/@spexcode/spec-cli/dist/doctor.js +553 -0
  43. package/node_modules/@spexcode/spec-cli/dist/eval-host.d.ts +1 -0
  44. package/node_modules/@spexcode/spec-cli/dist/eval-host.js +19 -0
  45. package/node_modules/@spexcode/spec-cli/dist/execution-trace.d.ts +26 -0
  46. package/node_modules/@spexcode/spec-cli/dist/execution-trace.js +475 -0
  47. package/node_modules/@spexcode/spec-cli/dist/file-write.d.ts +2 -0
  48. package/node_modules/@spexcode/spec-cli/dist/file-write.js +26 -0
  49. package/node_modules/@spexcode/spec-cli/dist/flat.d.ts +89 -0
  50. package/node_modules/@spexcode/spec-cli/dist/flat.js +1076 -0
  51. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.d.ts +56 -0
  52. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.js +168 -0
  53. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.d.ts +28 -0
  54. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.js +363 -0
  55. package/node_modules/@spexcode/spec-cli/dist/gateway.d.ts +38 -0
  56. package/node_modules/@spexcode/spec-cli/dist/gateway.js +527 -0
  57. package/node_modules/@spexcode/spec-cli/dist/graphCache.d.ts +27 -0
  58. package/node_modules/@spexcode/spec-cli/dist/graphCache.js +717 -0
  59. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.d.ts +14 -0
  60. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.js +36 -0
  61. package/node_modules/@spexcode/spec-cli/dist/graphStream.d.ts +85 -0
  62. package/node_modules/@spexcode/spec-cli/dist/graphStream.js +1195 -0
  63. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.d.ts +64 -0
  64. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.js +166 -0
  65. package/node_modules/@spexcode/spec-cli/dist/guide.d.ts +8 -0
  66. package/{spec-cli/src/guide.ts → node_modules/@spexcode/spec-cli/dist/guide.js} +36 -32
  67. package/node_modules/@spexcode/spec-cli/dist/harness-select.d.ts +18 -0
  68. package/node_modules/@spexcode/spec-cli/dist/harness-select.js +62 -0
  69. package/node_modules/@spexcode/spec-cli/dist/harness.d.ts +338 -0
  70. package/node_modules/@spexcode/spec-cli/dist/harness.js +3146 -0
  71. package/node_modules/@spexcode/spec-cli/dist/headless-controller.d.ts +9 -0
  72. package/node_modules/@spexcode/spec-cli/dist/headless-controller.js +47 -0
  73. package/node_modules/@spexcode/spec-cli/dist/help.d.ts +15 -0
  74. package/node_modules/@spexcode/spec-cli/dist/help.js +594 -0
  75. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.d.ts +18 -0
  76. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.js +122 -0
  77. package/node_modules/@spexcode/spec-cli/dist/hooks.d.ts +1 -0
  78. package/{spec-cli/src/hooks.ts → node_modules/@spexcode/spec-cli/dist/hooks.js} +15 -15
  79. package/node_modules/@spexcode/spec-cli/dist/host-resources.d.ts +97 -0
  80. package/node_modules/@spexcode/spec-cli/dist/host-resources.js +795 -0
  81. package/node_modules/@spexcode/spec-cli/dist/host.d.ts +88 -0
  82. package/node_modules/@spexcode/spec-cli/dist/host.js +663 -0
  83. package/node_modules/@spexcode/spec-cli/dist/index.d.ts +1 -0
  84. package/node_modules/@spexcode/spec-cli/dist/index.js +899 -0
  85. package/node_modules/@spexcode/spec-cli/dist/init.d.ts +1 -0
  86. package/node_modules/@spexcode/spec-cli/dist/init.js +284 -0
  87. package/node_modules/@spexcode/spec-cli/dist/issues-cli.d.ts +6 -0
  88. package/node_modules/@spexcode/spec-cli/dist/issues-cli.js +334 -0
  89. package/node_modules/@spexcode/spec-cli/dist/issues.d.ts +69 -0
  90. package/node_modules/@spexcode/spec-cli/dist/issues.js +189 -0
  91. package/node_modules/@spexcode/spec-cli/dist/lint.d.ts +34 -0
  92. package/node_modules/@spexcode/spec-cli/dist/lint.js +476 -0
  93. package/node_modules/@spexcode/spec-cli/dist/listen.d.ts +8 -0
  94. package/node_modules/@spexcode/spec-cli/dist/listen.js +24 -0
  95. package/node_modules/@spexcode/spec-cli/dist/localIssues.d.ts +65 -0
  96. package/node_modules/@spexcode/spec-cli/dist/localIssues.js +582 -0
  97. package/node_modules/@spexcode/spec-cli/dist/login-page.d.ts +5 -0
  98. package/{spec-cli/src/login-page.ts → node_modules/@spexcode/spec-cli/dist/login-page.js} +7 -7
  99. package/node_modules/@spexcode/spec-cli/dist/loop-in.d.ts +23 -0
  100. package/{spec-cli/src/loop-in.ts → node_modules/@spexcode/spec-cli/dist/loop-in.js} +35 -45
  101. package/node_modules/@spexcode/spec-cli/dist/machine-peer.d.ts +69 -0
  102. package/node_modules/@spexcode/spec-cli/dist/machine-peer.js +603 -0
  103. package/node_modules/@spexcode/spec-cli/dist/materialize.d.ts +18 -0
  104. package/node_modules/@spexcode/spec-cli/dist/materialize.js +468 -0
  105. package/node_modules/@spexcode/spec-cli/dist/mentions.d.ts +50 -0
  106. package/node_modules/@spexcode/spec-cli/dist/mentions.js +117 -0
  107. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.d.ts +5 -0
  108. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.js +215 -0
  109. package/node_modules/@spexcode/spec-cli/dist/opencode.d.ts +3 -0
  110. package/{spec-cli/src/opencode.ts → node_modules/@spexcode/spec-cli/dist/opencode.js} +9 -13
  111. package/node_modules/@spexcode/spec-cli/dist/pi-harness.d.ts +3 -0
  112. package/{spec-cli/src/pi-harness.ts → node_modules/@spexcode/spec-cli/dist/pi-harness.js} +45 -40
  113. package/node_modules/@spexcode/spec-cli/dist/pi-headless.d.ts +25 -0
  114. package/node_modules/@spexcode/spec-cli/dist/pi-headless.js +196 -0
  115. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.d.ts +21 -0
  116. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.js +146 -0
  117. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.d.ts +10 -0
  118. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.js +404 -0
  119. package/node_modules/@spexcode/spec-cli/dist/pty-helper.d.mts +1 -0
  120. package/node_modules/@spexcode/spec-cli/dist/pty-helper.mjs +101 -0
  121. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.d.mts +2 -0
  122. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.mjs +23 -0
  123. package/node_modules/@spexcode/spec-cli/dist/public-graph.d.ts +46 -0
  124. package/node_modules/@spexcode/spec-cli/dist/public-graph.js +56 -0
  125. package/node_modules/@spexcode/spec-cli/dist/ranker.d.ts +15 -0
  126. package/node_modules/@spexcode/spec-cli/dist/ranker.js +188 -0
  127. package/node_modules/@spexcode/spec-cli/dist/reaper.d.ts +6 -0
  128. package/node_modules/@spexcode/spec-cli/dist/reaper.js +81 -0
  129. package/node_modules/@spexcode/spec-cli/dist/reviews.d.ts +189 -0
  130. package/node_modules/@spexcode/spec-cli/dist/reviews.js +350 -0
  131. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.d.ts +6 -0
  132. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.js +37 -0
  133. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.d.ts +21 -0
  134. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.js +84 -0
  135. package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.d.ts +1 -0
  136. package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.js +58 -0
  137. package/node_modules/@spexcode/spec-cli/dist/search.bench.d.mts +1 -0
  138. package/node_modules/@spexcode/spec-cli/dist/search.bench.mjs +75 -0
  139. package/node_modules/@spexcode/spec-cli/dist/search.d.ts +20 -0
  140. package/node_modules/@spexcode/spec-cli/dist/search.js +61 -0
  141. package/node_modules/@spexcode/spec-cli/dist/session-declarations.d.ts +13 -0
  142. package/node_modules/@spexcode/spec-cli/dist/session-declarations.js +126 -0
  143. package/node_modules/@spexcode/spec-cli/dist/session-execution.d.ts +10 -0
  144. package/node_modules/@spexcode/spec-cli/dist/session-execution.js +70 -0
  145. package/node_modules/@spexcode/spec-cli/dist/session-files.d.ts +28 -0
  146. package/node_modules/@spexcode/spec-cli/dist/session-files.js +130 -0
  147. package/node_modules/@spexcode/spec-cli/dist/session-follow.d.ts +31 -0
  148. package/node_modules/@spexcode/spec-cli/dist/session-follow.js +179 -0
  149. package/node_modules/@spexcode/spec-cli/dist/session-reparent.d.ts +10 -0
  150. package/node_modules/@spexcode/spec-cli/dist/session-reparent.js +33 -0
  151. package/node_modules/@spexcode/spec-cli/dist/session-timeline.d.ts +11 -0
  152. package/node_modules/@spexcode/spec-cli/dist/session-timeline.js +20 -0
  153. package/node_modules/@spexcode/spec-cli/dist/session-web.d.ts +24 -0
  154. package/node_modules/@spexcode/spec-cli/dist/session-web.js +141 -0
  155. package/node_modules/@spexcode/spec-cli/dist/sessions.d.ts +433 -0
  156. package/node_modules/@spexcode/spec-cli/dist/sessions.js +4667 -0
  157. package/node_modules/@spexcode/spec-cli/dist/sh.d.ts +1 -0
  158. package/node_modules/@spexcode/spec-cli/dist/sh.js +3 -0
  159. package/node_modules/@spexcode/spec-cli/dist/shim-runtime.d.ts +1 -0
  160. package/{spec-cli/src/shim-runtime.ts → node_modules/@spexcode/spec-cli/dist/shim-runtime.js} +3 -4
  161. package/node_modules/@spexcode/spec-cli/dist/slash-commands.d.ts +9 -0
  162. package/node_modules/@spexcode/spec-cli/dist/slash-commands.js +307 -0
  163. package/node_modules/@spexcode/spec-cli/dist/source-files.d.ts +9 -0
  164. package/node_modules/@spexcode/spec-cli/dist/source-files.js +113 -0
  165. package/node_modules/@spexcode/spec-cli/dist/supervise.d.ts +1 -0
  166. package/node_modules/@spexcode/spec-cli/dist/supervise.js +308 -0
  167. package/node_modules/@spexcode/spec-cli/dist/tree.d.ts +25 -0
  168. package/node_modules/@spexcode/spec-cli/dist/tree.js +98 -0
  169. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.d.ts +3 -0
  170. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.js +41 -0
  171. package/node_modules/@spexcode/spec-cli/dist/uninstall.d.ts +3 -0
  172. package/node_modules/@spexcode/spec-cli/dist/uninstall.js +177 -0
  173. package/node_modules/@spexcode/spec-cli/dist/uploads.d.ts +36 -0
  174. package/node_modules/@spexcode/spec-cli/dist/uploads.js +243 -0
  175. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.d.ts +1 -0
  176. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.js +47 -0
  177. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/dispatch.sh +5 -5
  178. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/harness.sh +1 -1
  179. package/node_modules/@spexcode/spec-cli/package.json +49 -0
  180. package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -0
  181. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec-first.sh +1 -1
  182. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec-of-file.sh +1 -0
  183. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/spec.md +2 -2
  184. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/stop-gate.sh +31 -29
  185. package/node_modules/@spexcode/spec-core/dist/anchors.d.ts +94 -0
  186. package/node_modules/@spexcode/spec-core/dist/anchors.js +730 -0
  187. package/node_modules/@spexcode/spec-core/dist/git.d.ts +170 -0
  188. package/node_modules/@spexcode/spec-core/dist/git.js +2768 -0
  189. package/node_modules/@spexcode/spec-core/dist/graph-delta.d.ts +44 -0
  190. package/node_modules/@spexcode/spec-core/dist/graph-delta.js +72 -0
  191. package/node_modules/@spexcode/spec-core/dist/graph.d.ts +34 -0
  192. package/node_modules/@spexcode/spec-core/dist/graph.js +237 -0
  193. package/node_modules/@spexcode/spec-core/dist/graphDelta.d.ts +3 -0
  194. package/node_modules/@spexcode/spec-core/dist/graphDelta.js +13 -0
  195. package/node_modules/@spexcode/spec-core/dist/harness-identity.d.ts +31 -0
  196. package/node_modules/@spexcode/spec-core/dist/harness-identity.js +20 -0
  197. package/node_modules/@spexcode/spec-core/dist/identity-presets.d.ts +152 -0
  198. package/node_modules/@spexcode/spec-core/dist/identity-presets.js +132 -0
  199. package/node_modules/@spexcode/spec-core/dist/index.d.ts +45 -0
  200. package/node_modules/@spexcode/spec-core/dist/index.js +19 -0
  201. package/node_modules/@spexcode/spec-core/dist/layout.d.ts +187 -0
  202. package/node_modules/@spexcode/spec-core/dist/layout.js +548 -0
  203. package/node_modules/@spexcode/spec-core/dist/process-identity.d.ts +37 -0
  204. package/node_modules/@spexcode/spec-core/dist/process-identity.js +214 -0
  205. package/node_modules/@spexcode/spec-core/dist/project-identity.d.ts +12 -0
  206. package/node_modules/@spexcode/spec-core/dist/project-identity.js +71 -0
  207. package/node_modules/@spexcode/spec-core/dist/project-store.d.ts +3 -0
  208. package/node_modules/@spexcode/spec-core/dist/project-store.js +14 -0
  209. package/node_modules/@spexcode/spec-core/dist/resilience.d.ts +2 -0
  210. package/node_modules/@spexcode/spec-core/dist/resilience.js +40 -0
  211. package/node_modules/@spexcode/spec-core/dist/review/index.d.ts +3 -0
  212. package/node_modules/@spexcode/spec-core/dist/review/index.js +5 -0
  213. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.d.ts +77 -0
  214. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.js +308 -0
  215. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.d.ts +66 -0
  216. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.js +180 -0
  217. package/node_modules/@spexcode/spec-core/dist/review/session.d.ts +4 -0
  218. package/node_modules/@spexcode/spec-core/dist/review/session.js +8 -0
  219. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.d.ts +15 -0
  220. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.js +12 -0
  221. package/node_modules/@spexcode/spec-core/dist/root-lru.d.ts +4 -0
  222. package/{spec-cli/src/root-lru.ts → node_modules/@spexcode/spec-core/dist/root-lru.js} +26 -30
  223. package/node_modules/@spexcode/spec-core/dist/specs.d.ts +117 -0
  224. package/node_modules/@spexcode/spec-core/dist/specs.js +489 -0
  225. package/node_modules/@spexcode/spec-core/package.json +28 -0
  226. package/node_modules/@spexcode/spec-eval/dist/cache.d.ts +10 -0
  227. package/node_modules/@spexcode/spec-eval/dist/cache.js +50 -0
  228. package/node_modules/@spexcode/spec-eval/dist/cli.d.ts +22 -0
  229. package/node_modules/@spexcode/spec-eval/dist/cli.js +981 -0
  230. package/node_modules/@spexcode/spec-eval/dist/evaltab.d.ts +98 -0
  231. package/node_modules/@spexcode/spec-eval/dist/evaltab.js +176 -0
  232. package/node_modules/@spexcode/spec-eval/dist/filing.d.ts +16 -0
  233. package/node_modules/@spexcode/spec-eval/dist/filing.js +36 -0
  234. package/node_modules/@spexcode/spec-eval/dist/freshness.d.ts +48 -0
  235. package/node_modules/@spexcode/spec-eval/dist/freshness.js +799 -0
  236. package/node_modules/@spexcode/spec-eval/dist/host.d.ts +46 -0
  237. package/node_modules/@spexcode/spec-eval/dist/host.js +53 -0
  238. package/node_modules/@spexcode/spec-eval/dist/humanok.d.ts +11 -0
  239. package/node_modules/@spexcode/spec-eval/dist/humanok.js +27 -0
  240. package/node_modules/@spexcode/spec-eval/dist/index.d.ts +4 -0
  241. package/node_modules/@spexcode/spec-eval/dist/index.js +4 -0
  242. package/node_modules/@spexcode/spec-eval/dist/remarks.d.ts +31 -0
  243. package/node_modules/@spexcode/spec-eval/dist/remarks.js +1 -0
  244. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.d.ts +13 -0
  245. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.js +303 -0
  246. package/node_modules/@spexcode/spec-eval/dist/scenarios.d.ts +99 -0
  247. package/node_modules/@spexcode/spec-eval/dist/scenarios.js +650 -0
  248. package/node_modules/@spexcode/spec-eval/dist/sessioneval.d.ts +307 -0
  249. package/node_modules/@spexcode/spec-eval/dist/sessioneval.js +1883 -0
  250. package/node_modules/@spexcode/spec-eval/dist/sidecar.d.ts +55 -0
  251. package/node_modules/@spexcode/spec-eval/dist/sidecar.js +82 -0
  252. package/node_modules/@spexcode/spec-eval/dist/timeline.d.ts +25 -0
  253. package/node_modules/@spexcode/spec-eval/dist/timeline.js +65 -0
  254. package/node_modules/@spexcode/spec-eval/dist/ui-path.d.ts +1 -0
  255. package/node_modules/@spexcode/spec-eval/dist/ui-path.js +2 -0
  256. package/node_modules/@spexcode/spec-eval/package.json +36 -0
  257. package/node_modules/@spexcode/spec-forge/dist/cache.d.ts +29 -0
  258. package/node_modules/@spexcode/spec-forge/dist/cache.js +59 -0
  259. package/node_modules/@spexcode/spec-forge/dist/cli.d.ts +1 -0
  260. package/node_modules/@spexcode/spec-forge/dist/cli.js +100 -0
  261. package/node_modules/@spexcode/spec-forge/dist/drivers/github.d.ts +2 -0
  262. package/node_modules/@spexcode/spec-forge/dist/drivers/github.js +116 -0
  263. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.d.ts +7 -0
  264. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.js +144 -0
  265. package/node_modules/@spexcode/spec-forge/dist/drivers.d.ts +10 -0
  266. package/node_modules/@spexcode/spec-forge/dist/drivers.js +83 -0
  267. package/node_modules/@spexcode/spec-forge/dist/index.d.ts +4 -0
  268. package/node_modules/@spexcode/spec-forge/dist/index.js +4 -0
  269. package/node_modules/@spexcode/spec-forge/dist/links.d.ts +15 -0
  270. package/node_modules/@spexcode/spec-forge/dist/links.js +65 -0
  271. package/node_modules/@spexcode/spec-forge/dist/needs-eval.d.ts +10 -0
  272. package/node_modules/@spexcode/spec-forge/dist/needs-eval.js +20 -0
  273. package/node_modules/@spexcode/spec-forge/dist/port.d.ts +53 -0
  274. package/node_modules/@spexcode/spec-forge/dist/port.js +1 -0
  275. package/node_modules/@spexcode/spec-forge/dist/resident.d.ts +7 -0
  276. package/node_modules/@spexcode/spec-forge/dist/resident.js +43 -0
  277. package/node_modules/@spexcode/spec-forge/package.json +32 -0
  278. package/package.json +33 -19
  279. package/spec-cli/bin/spex.mjs +0 -69
  280. package/spec-cli/src/anchors.ts +0 -728
  281. package/spec-cli/src/attach.ts +0 -43
  282. package/spec-cli/src/claude-headless.ts +0 -321
  283. package/spec-cli/src/cli.ts +0 -1258
  284. package/spec-cli/src/client.ts +0 -414
  285. package/spec-cli/src/cockpit.ts +0 -43
  286. package/spec-cli/src/codex-runtime-generations.ts +0 -646
  287. package/spec-cli/src/commit-surgery.ts +0 -68
  288. package/spec-cli/src/contract-filter.ts +0 -202
  289. package/spec-cli/src/delivery-queue.ts +0 -165
  290. package/spec-cli/src/doctor.ts +0 -516
  291. package/spec-cli/src/execution-trace.ts +0 -444
  292. package/spec-cli/src/file-write.ts +0 -22
  293. package/spec-cli/src/gateway-auth.ts +0 -181
  294. package/spec-cli/src/gateway-hub.ts +0 -358
  295. package/spec-cli/src/gateway.ts +0 -461
  296. package/spec-cli/src/git.ts +0 -2556
  297. package/spec-cli/src/graph.ts +0 -271
  298. package/spec-cli/src/graphCache.ts +0 -710
  299. package/spec-cli/src/graphDelta.ts +0 -77
  300. package/spec-cli/src/graphStream.ts +0 -1019
  301. package/spec-cli/src/harness-select.ts +0 -77
  302. package/spec-cli/src/harness.ts +0 -3025
  303. package/spec-cli/src/headless-controller.ts +0 -63
  304. package/spec-cli/src/help.ts +0 -492
  305. package/spec-cli/src/host-resources.ts +0 -762
  306. package/spec-cli/src/host.ts +0 -611
  307. package/spec-cli/src/identity-presets.d.ts +0 -13
  308. package/spec-cli/src/identity-presets.js +0 -138
  309. package/spec-cli/src/index.ts +0 -818
  310. package/spec-cli/src/init.ts +0 -258
  311. package/spec-cli/src/issues-cli.ts +0 -276
  312. package/spec-cli/src/issues.ts +0 -237
  313. package/spec-cli/src/layout.ts +0 -640
  314. package/spec-cli/src/lint.ts +0 -488
  315. package/spec-cli/src/listen.ts +0 -28
  316. package/spec-cli/src/localIssues.ts +0 -538
  317. package/spec-cli/src/materialize.ts +0 -417
  318. package/spec-cli/src/mentions.ts +0 -81
  319. package/spec-cli/src/opencode-headless.ts +0 -205
  320. package/spec-cli/src/pi-headless.ts +0 -153
  321. package/spec-cli/src/plugin-harness.ts +0 -157
  322. package/spec-cli/src/process-identity.ts +0 -207
  323. package/spec-cli/src/project-identity.ts +0 -73
  324. package/spec-cli/src/project-store.ts +0 -17
  325. package/spec-cli/src/pty-bridge.ts +0 -396
  326. package/spec-cli/src/pty-helper.mjs +0 -96
  327. package/spec-cli/src/pty-native-helper.mjs +0 -22
  328. package/spec-cli/src/ranker.ts +0 -191
  329. package/spec-cli/src/reaper.ts +0 -125
  330. package/spec-cli/src/resilience.ts +0 -41
  331. package/spec-cli/src/reviewSnapshot.ts +0 -28
  332. package/spec-cli/src/reviews.ts +0 -434
  333. package/spec-cli/src/runtime-guard.ts +0 -35
  334. package/spec-cli/src/runtime-ownership.ts +0 -88
  335. package/spec-cli/src/search.bench.mjs +0 -80
  336. package/spec-cli/src/search.ts +0 -63
  337. package/spec-cli/src/session-cursors.ts +0 -91
  338. package/spec-cli/src/session-execution.ts +0 -68
  339. package/spec-cli/src/session-files.ts +0 -121
  340. package/spec-cli/src/session-follow.ts +0 -182
  341. package/spec-cli/src/session-reparent.ts +0 -33
  342. package/spec-cli/src/session-timeline.ts +0 -247
  343. package/spec-cli/src/session-web.ts +0 -135
  344. package/spec-cli/src/sessions.ts +0 -3883
  345. package/spec-cli/src/sh.ts +0 -3
  346. package/spec-cli/src/slash-commands.ts +0 -318
  347. package/spec-cli/src/source-files.ts +0 -104
  348. package/spec-cli/src/specs.ts +0 -498
  349. package/spec-cli/src/supervise.ts +0 -245
  350. package/spec-cli/src/tree.ts +0 -118
  351. package/spec-cli/src/tsx-bin.ts +0 -18
  352. package/spec-cli/src/uninstall.ts +0 -171
  353. package/spec-cli/src/uploads.ts +0 -253
  354. package/spec-cli/src/worktree-sources.ts +0 -42
  355. package/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +0 -8
  356. package/spec-dashboard/dist/assets/App-B6IbFbGu.js +0 -2
  357. package/spec-dashboard/dist/assets/Dashboard-C5ap-Sga.css +0 -1
  358. package/spec-dashboard/dist/assets/Dashboard-_sDk7Rcg.js +0 -27
  359. package/spec-dashboard/dist/assets/EvalsPage-BT357Lyt.js +0 -2
  360. package/spec-dashboard/dist/assets/IssuesPage-BG9rNOgV.js +0 -1
  361. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  362. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  363. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  364. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  365. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  366. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  367. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  368. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  369. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  370. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  371. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  372. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  373. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  374. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  375. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  376. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  377. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  378. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  379. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  380. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  381. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  382. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  383. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  384. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  385. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  386. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  387. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  388. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  389. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  390. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  391. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  392. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  393. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  394. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  395. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  396. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  397. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  398. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  399. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  400. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  401. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  402. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  403. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  404. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  405. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  406. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  407. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  408. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  409. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  410. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  411. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  412. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  413. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  414. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  415. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  416. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  417. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  418. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  419. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  420. package/spec-dashboard/dist/assets/MobileApp-D9yPMR3A.js +0 -2
  421. package/spec-dashboard/dist/assets/Modal-B3EcgeA3.js +0 -1
  422. package/spec-dashboard/dist/assets/PageScroll-CNZOugWV.js +0 -1
  423. package/spec-dashboard/dist/assets/ProjectsPage-C2CRHmvs.js +0 -1
  424. package/spec-dashboard/dist/assets/SessionInterface-6GBZ9nXN.css +0 -32
  425. package/spec-dashboard/dist/assets/SessionInterface-DOEjuT3l.js +0 -40
  426. package/spec-dashboard/dist/assets/SessionWindow-1nYgZ4CL.js +0 -1
  427. package/spec-dashboard/dist/assets/Settings-7WeTJn0V.js +0 -1
  428. package/spec-dashboard/dist/assets/Thread-CEbzAFQn.js +0 -13
  429. package/spec-dashboard/dist/assets/bindings-BC9vqpYU.js +0 -1
  430. package/spec-dashboard/dist/assets/data-SlvxNA2r.js +0 -1
  431. package/spec-dashboard/dist/assets/index-DLVeOHL-.js +0 -41
  432. package/spec-dashboard/dist/assets/index-DYLGfPjx.css +0 -1
  433. package/spec-dashboard/dist/assets/launch-Cp579UoJ.css +0 -1
  434. package/spec-dashboard/dist/assets/launch-yxCYr64x.js +0 -276
  435. package/spec-dashboard/dist/assets/sessionSurface--7l69h4F.js +0 -1
  436. package/spec-dashboard/dist/index.html +0 -29
  437. package/spec-dashboard/src/reviewFilters.js +0 -322
  438. package/spec-dashboard/src/reviewQuery.js +0 -174
  439. package/spec-dashboard/src/session.js +0 -199
  440. package/spec-eval/src/cache.ts +0 -57
  441. package/spec-eval/src/cli.ts +0 -894
  442. package/spec-eval/src/evaltab.ts +0 -264
  443. package/spec-eval/src/filing.ts +0 -39
  444. package/spec-eval/src/freshness.ts +0 -836
  445. package/spec-eval/src/humanok.ts +0 -28
  446. package/spec-eval/src/scenariofresh.ts +0 -244
  447. package/spec-eval/src/scenarios.ts +0 -672
  448. package/spec-eval/src/sessioneval.ts +0 -2220
  449. package/spec-eval/src/sidecar.ts +0 -93
  450. package/spec-eval/src/timeline.ts +0 -54
  451. package/spec-forge/src/__fixtures__/github-forge.json +0 -63
  452. package/spec-forge/src/cache.ts +0 -66
  453. package/spec-forge/src/cli.ts +0 -99
  454. package/spec-forge/src/drivers/github.ts +0 -132
  455. package/spec-forge/src/drivers/gitlab.ts +0 -153
  456. package/spec-forge/src/drivers.ts +0 -73
  457. package/spec-forge/src/links.ts +0 -72
  458. package/spec-forge/src/needs-eval.ts +0 -29
  459. package/spec-forge/src/port.ts +0 -36
  460. package/spec-forge/src/resident.ts +0 -46
  461. /package/{spec-cli → node_modules/@spexcode/spec-cli}/README.md +0 -0
  462. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-0.5.2-eef1.fixture +0 -0
  463. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-sed-v0.fixture +0 -0
  464. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/commit-msg +0 -0
  465. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-checkout +0 -0
  466. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-merge +0 -0
  467. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/pre-commit +0 -0
  468. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/prepare-commit-msg +0 -0
  469. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/reference-transaction +0 -0
  470. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/extract/spec.md +0 -0
  471. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/regroup/spec.md +0 -0
  472. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/rename/spec.md +0 -0
  473. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/spec.md +0 -0
  474. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/tidy/spec.md +0 -0
  475. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/comment-altitude/spec.md +0 -0
  476. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/idle.sh +0 -0
  477. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/spec.md +0 -0
  478. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/mark-active.sh +0 -0
  479. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/spec.md +0 -0
  480. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/fail.sh +0 -0
  481. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/spec.md +0 -0
  482. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec.md +0 -0
  483. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec.md +0 -0
  484. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec.md +0 -0
  485. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +0 -0
  486. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/forge-link/spec.md +0 -0
  487. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +0 -0
  488. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +0 -0
  489. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/spec.md +0 -0
  490. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/digest.mjs +0 -0
  491. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/spec.md +0 -0
  492. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/spec.md +0 -0
  493. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/spec.md +0 -0
  494. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/spec.md +0 -0
  495. /package/{spec-cli → node_modules/@spexcode/spec-core}/templates/spexcode.json +0 -0
@@ -1,414 +0,0 @@
1
- import { existsSync } from 'node:fs'
2
- import { platform } from 'node:os'
3
- import { repoRoot } from './git.js'
4
- import { resourceBudgets, type ResourceReport } from './host-resources.js'
5
- import { envSessionId, listSessionIds, readPublicRecordEntry } from './layout.js'
6
- import { cockpitReview, type CockpitReview } from './cockpit.js'
7
- import { apiBaseInfo, assertProjectMatch, fromRaw, optionArgv, resolveSession, toSession, type DisplayStatus, type Session, type Resolved, type DispatchResult, type ReviewPayload } from './sessions.js'
8
-
9
- export class BackendError extends Error {
10
- constructor(message: string, readonly status?: number, readonly transport?: unknown) {
11
- super(message)
12
- this.name = 'BackendError' // cli.ts's top-level handler matches on the NAME, so it needs no import of this class
13
- }
14
- }
15
-
16
- const usageError = (message: string): Error => {
17
- const error = new Error(message)
18
- error.name = 'UsageError'
19
- return error
20
- }
21
-
22
- const hasFlag = (name: string): boolean => optionArgv().includes(`--${name}`)
23
- function flagValue(name: string): string | null {
24
- const argv = optionArgv()
25
- const index = argv.indexOf(`--${name}`)
26
- if (index < 0) return null
27
- const value = argv[index + 1]
28
- if (value === undefined || value.startsWith('--')) throw usageError(`--${name} expects a value`)
29
- return value
30
- }
31
-
32
- let gatewayCookie: { base: string; value: string } | null = null
33
-
34
- function prepareTls(base: string): void {
35
- if (!hasFlag('insecure')) return
36
- if (new URL(base).protocol !== 'https:') throw usageError('--insecure requires an https --api endpoint')
37
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
38
- }
39
-
40
- function passwordFor(target: Awaited<ReturnType<typeof apiBaseInfo>>): string | null {
41
- const password = flagValue('password') ?? process.env.SPEXCODE_PASSWORD ?? null
42
- if (!password) return null
43
- if (target.source !== 'flag') throw usageError('--password and SPEXCODE_PASSWORD require explicit --api routing')
44
- return password
45
- }
46
-
47
- function withCookie(init: RequestInit | undefined, cookie: string): RequestInit {
48
- const headers = new Headers(init?.headers)
49
- headers.set('cookie', cookie)
50
- return { ...init, headers }
51
- }
52
-
53
- async function loginGateway(base: string, password: string): Promise<string> {
54
- let response: Response
55
- try {
56
- response = await fetch(`${base}/login`, {
57
- method: 'POST',
58
- headers: { 'content-type': 'application/x-www-form-urlencoded' },
59
- body: new URLSearchParams({ password }).toString(),
60
- redirect: 'manual',
61
- })
62
- } catch (error) {
63
- throw new BackendError(`gateway login could not reach ${base}: ${(error as Error).message}`, undefined, error)
64
- }
65
- if (response.status < 200 || response.status >= 400) throw new BackendError(`gateway login rejected credentials at ${base}`, response.status)
66
- const headers = response.headers as Headers & { getSetCookie?: () => string[] }
67
- const cookies = headers.getSetCookie?.() ?? [response.headers.get('set-cookie') ?? '']
68
- const cookie = cookies.map((value) => value.split(';', 1)[0]).find(Boolean)
69
- if (!cookie) throw new BackendError(`gateway login at ${base} did not return an authorization cookie`, response.status)
70
- return cookie
71
- }
72
-
73
- // the ONE seam where "no backend" becomes loud. A network failure (nothing listening at the resolved base)
74
- // is the only thing thrown; an HTTP Response of any status is returned for the caller to interpret.
75
- async function apiFetch(path: string, init?: RequestInit): Promise<Response> {
76
- const target = await apiBaseInfo()
77
- const base = target.url
78
- prepareTls(base)
79
- const request = async (cookie?: string): Promise<Response> => {
80
- try {
81
- return await fetch(`${base}${path}`, cookie ? withCookie(init, cookie) : init)
82
- } catch (error) {
83
- throw new BackendError(`no backend reachable at ${base} — run \`spex serve\` in the project, or name one with --api <url> (${(error as Error).message})`, undefined, error)
84
- }
85
- }
86
- const existing = gatewayCookie?.base === base ? gatewayCookie.value : undefined
87
- const response = await request(existing)
88
- if (response.status !== 401) return response
89
- if (existing) throw new BackendError(`gateway rejected the authenticated request at ${base}`, 401)
90
- const password = passwordFor(target)
91
- if (!password) throw new BackendError(`authentication required at ${base} — pass --password <pw> or set SPEXCODE_PASSWORD`, 401)
92
- const cookie = await loginGateway(base, password)
93
- gatewayCookie = { base, value: cookie }
94
- const retried = await request(cookie)
95
- if (retried.status === 401) throw new BackendError(`gateway rejected the authenticated request at ${base}`, 401)
96
- return retried
97
- }
98
-
99
- export function backendConnectionRefused(error: unknown): boolean {
100
- if (!(error instanceof BackendError)) return false
101
- let current = error.transport
102
- let sawRefusal = false
103
- const seen = new Set<unknown>()
104
- while (current && typeof current === 'object' && !seen.has(current)) {
105
- seen.add(current)
106
- const code = (current as NodeJS.ErrnoException).code
107
- if (code && code !== 'ECONNREFUSED') return false
108
- if (code === 'ECONNREFUSED') sawRefusal = true
109
- current = (current as { cause?: unknown }).cause
110
- }
111
- return sawRefusal
112
- }
113
- // every MUTATING verb is project-bound ([[remote-client]]'s write guard): resolve the backend, compare its
114
- // served root to the cwd project, refuse loudly on a same-host mismatch — an explicit --api/--port skips it.
115
- // Reads stay unguarded (viewer-points-anywhere). Guarding HERE (not per cli.ts branch) covers every caller.
116
- const guarded = (verb: string) => assertProjectMatch(`spex ${verb}`)
117
- const post = (body: unknown): RequestInit => ({ method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) })
118
- const seg = (id: string) => encodeURIComponent(id)
119
-
120
- // A rendezvous liveness probe can displace the real delivery client.
121
- function cachedStatus(rec: ReturnType<typeof fromRaw>): DisplayStatus {
122
- if (!rec.worktreePath || !existsSync(rec.worktreePath)) return 'retired'
123
- if (rec.archived) return 'offline'
124
- if (rec.status === 'awaiting') return rec.proposal === 'merge' ? 'review' : rec.proposal === 'close' ? 'close-pending' : 'done'
125
- return rec.status === 'active' || rec.status === 'idle' ? 'unknown' : rec.status
126
- }
127
-
128
- function corruptCachedSession(id: string, reason: string): Session {
129
- const label = `${id.slice(0, 8)} (unreadable record)`
130
- return {
131
- id, node: null, branch: null, path: '', label, title: label, raw: { name: null, title: null },
132
- parent: null, harness: 'unknown', capabilities: { headless: false }, launcher: null,
133
- lifecycle: 'active', proposal: null, merges: 0, status: 'corrupt', liveness: 'unknown',
134
- note: `session record is unreadable: ${reason}`, archived: false, archiveHazard: null,
135
- prompt: null, promptPreview: null, created: 0, activity: null, sortKey: null,
136
- }
137
- }
138
-
139
- // Also the board a FOLLOW resolves its selectors against ([[session-follow]]): following must work with no
140
- // `spex serve` running, and asking a backend for the board would cost exactly the tmux/rendezvous probes the
141
- // follow exists to eliminate. Every field here comes from the store — nothing is probed.
142
- export function localCachedSessions(includeArchived = false): Session[] {
143
- const rows: Session[] = []
144
- for (const id of listSessionIds()) {
145
- const entry = readPublicRecordEntry(id)
146
- if (entry.kind === 'corrupt') {
147
- rows.push(corruptCachedSession(id, entry.error))
148
- continue
149
- }
150
- if (entry.kind !== 'ok') continue
151
- const rec = fromRaw(entry.raw)
152
- if (!rec.governed) continue
153
- rows.push(toSession(rec, cachedStatus(rec), 'unknown'))
154
- }
155
- return rows.filter((session) => includeArchived || !session.archived)
156
- .sort((a, b) => (a.sortKey ?? a.created) - (b.sortKey ?? b.created) || a.id.localeCompare(b.id))
157
- }
158
-
159
- function localCachedResources(): ResourceReport {
160
- const projectRoot = repoRoot()
161
- const budgets = resourceBudgets(projectRoot)
162
- const owners = localCachedSessions(true).map((session) => ({
163
- kind: 'session' as const,
164
- id: session.id,
165
- label: session.label,
166
- status: session.lifecycle,
167
- liveness: 'unknown' as const,
168
- proposal: session.proposal,
169
- note: session.note,
170
- worktreePath: session.path,
171
- branch: session.branch,
172
- archived: session.archived,
173
- processes: [],
174
- rssMiB: 0,
175
- pssMiB: null,
176
- cpuPercent: 0,
177
- budget: { rssMiB: budgets.sessionRssMiB, idleCpuPercent: budgets.idleCpuPercent },
178
- findings: ['local-store-only: runtime liveness and process measurements are unavailable'],
179
- reclaim: { eligible: false, reason: 'local store read cannot prove runtime ownership or liveness' },
180
- }))
181
- return {
182
- version: 1,
183
- measuredAt: new Date().toISOString(),
184
- projectRoot,
185
- platform: platform(),
186
- available: false,
187
- unavailableReason: 'backend unavailable; local session store has no runtime resource measurements',
188
- host: { memoryTotalMiB: null, memoryUsedMiB: null, memoryAvailableMiB: null, swapTotalMiB: null, swapUsedMiB: null, cpuPercent: null },
189
- budgets,
190
- owners,
191
- totals: { rssMiB: 0, pssMiB: null, cpuPercent: 0 },
192
- findings: owners.reduce((total, owner) => total + owner.findings.length, 0),
193
- }
194
- }
195
-
196
- async function cachedRead<T>(remote: () => Promise<T>, local: () => T | Promise<T>): Promise<T> {
197
- try {
198
- return await remote()
199
- } catch (error) {
200
- if (!(error instanceof BackendError) || error.status !== undefined || (await apiBaseInfo()).source === 'flag') throw error
201
- console.error('spex session: backend unreachable; source: local session store (liveness unknown)')
202
- return await local()
203
- }
204
- }
205
-
206
- // GET /api/sessions — the board, used by `spex session ls`, and by `spex session watch`/`wait` as their poll source.
207
- export async function clientListSessions(includeArchived = false): Promise<Session[]> {
208
- return cachedRead(async () => {
209
- const r = await apiFetch(includeArchived ? '/api/sessions?all=1' : '/api/sessions')
210
- if (!r.ok) throw new BackendError(`backend error ${r.status} listing sessions`, r.status)
211
- return await r.json() as Session[]
212
- }, () => localCachedSessions(includeArchived))
213
- }
214
-
215
- export async function clientResources(): Promise<import('./host-resources.js').ResourceReport> {
216
- return cachedRead(async () => {
217
- const r = await apiFetch('/api/resources')
218
- if (!r.ok) throw new BackendError(`backend error ${r.status} loading resources: ${await r.text()}`, r.status)
219
- return await r.json() as import('./host-resources.js').ResourceReport
220
- }, localCachedResources)
221
- }
222
-
223
- // resolve a selector (full id, id-prefix, node, or branch) against the live board, then call with the full id.
224
- export async function resolveClientSession(selector: string, includeArchived = true): Promise<Resolved> {
225
- return resolveSession(selector, await clientListSessions(includeArchived))
226
- }
227
-
228
- // GET /api/sessions/:id/capture — the live pane as text. The discriminated result keeps the three failure
229
- // modes (404 unknown / 409 offline / 502 capture-failed) distinct from a legitimately empty pane (200, '').
230
- export type CaptureResult = { ok: true; pane: string } | { ok: false; status: number; reason: string }
231
- export async function clientCapture(id: string): Promise<CaptureResult> {
232
- const r = await apiFetch(`/api/sessions/${seg(id)}/capture`)
233
- if (r.ok) return { ok: true, pane: await r.text() }
234
- return { ok: false, status: r.status, reason: (await r.text().catch(() => '')) || `status ${r.status}` }
235
- }
236
-
237
- // POST /api/sessions/:id/input {kind:"text"} appends the prompt to the durable timeline, then best-effort
238
- // pokes the resolved adapter. HTTP failure means the append itself was refused.
239
- export async function clientSend(id: string, text: string, from?: string): Promise<DispatchResult> {
240
- await guarded('session send')
241
- // `from` = the sending agent's own session id; the recipient's log records the sender ([[session-timeline]]) only when
242
- // it's present (an agent send), so a human-shell send stays unrecorded.
243
- const r = await apiFetch(`/api/sessions/${seg(id)}/input`, post({ kind: 'text', text, ...(from ? { from } : {}) }))
244
- return await r.json().catch(() => ({ ok: false, error: `bad backend response (${r.status})` })) as DispatchResult
245
- }
246
-
247
- // GET /api/sessions/:id/review — the manager cockpit review bundle (null on 404).
248
- export async function clientReview(id: string): Promise<CockpitReview | null> {
249
- return cachedRead(async () => {
250
- const r = await apiFetch(`/api/sessions/${seg(id)}/review`)
251
- if (r.status === 404) return null
252
- if (!r.ok) throw new BackendError(`backend error ${r.status} reviewing ${id}`, r.status)
253
- return await r.json() as CockpitReview
254
- }, () => cockpitReview(id))
255
- }
256
-
257
- // GET /api/sessions/:id/evals?format=html — the rendered EXPORT artifact ([[session-eval]]): the
258
- // self-contained HTML the backend builds. The engine runs on the backend, so the CLI is a thin fetcher
259
- // that writes/opens these bytes — works against a remote backend unchanged. 404 → no such session.
260
- export type ExportResult = { ok: true; body: string } | { ok: false; status: number }
261
- export async function clientEvalExport(id: string): Promise<ExportResult> {
262
- const r = await apiFetch(`/api/sessions/${seg(id)}/evals?format=html`)
263
- if (r.ok) return { ok: true, body: await r.text() }
264
- return { ok: false, status: r.status }
265
- }
266
-
267
- // The CLI's explicit aggregate walks the same 25-row pages as the dashboard. No server response contains
268
- // the full session model; aggregation exists only for this one-shot terminal rendering.
269
- type SessionEvalPage = {
270
- items: any[]
271
- page: number
272
- pageCount: number
273
- total: number
274
- gates: any[]
275
- unknown: number
276
- revision: string
277
- summary?: any
278
- evalRevision?: any
279
- }
280
- export type EvalsResult = { ok: true; model: SessionEvalPage & { id: string } } | { ok: false; status: number }
281
- export async function clientEvals(id: string): Promise<EvalsResult> {
282
- const q = encodeURIComponent(`is:eval scope:${id}`)
283
- for (let attempt = 0; attempt < 2; attempt++) {
284
- const items: any[] = []
285
- let first: SessionEvalPage | null = null
286
- let changed = false
287
- for (let page = 1;; page++) {
288
- const r = await apiFetch(`/api/evals?q=${q}&page=${page}`)
289
- if (!r.ok) return { ok: false, status: r.status }
290
- const current = await r.json() as SessionEvalPage
291
- first ??= current
292
- if (current.revision !== first.revision) { changed = true; break }
293
- items.push(...current.items)
294
- if (page >= current.pageCount) break
295
- }
296
- if (!changed) return { ok: true, model: { ...first!, id, items } }
297
- }
298
- throw new BackendError(`session eval pages changed while fetching ${id}; retry the command`)
299
- }
300
-
301
- // POST /api/sessions/:id/merge — the cockpit's merge DISPATCH. The caller returns the exact pair it just
302
- // reviewed and one durable request key; the backend accepts that decision once before ensuring the agent live.
303
- export async function clientMerge(id: string, options: { expectedBranchHead: string; expectedBaseHead: string; requestKey: string }): Promise<{ dispatched: boolean; replayed?: boolean; expectedBranchHead?: string; expectedBaseHead?: string; reason?: string; code?: string }> {
304
- await guarded('merge')
305
- const headers: Record<string, string> = { 'content-type': 'application/json', 'Idempotency-Key': options.requestKey }
306
- const r = await apiFetch(`/api/sessions/${seg(id)}/merge`, {
307
- method: 'POST', headers, body: JSON.stringify({ expectedBranchHead: options.expectedBranchHead, expectedBaseHead: options.expectedBaseHead }),
308
- })
309
- return await r.json().catch(() => ({ dispatched: false, reason: `bad backend response (${r.status})` }))
310
- }
311
-
312
- // POST /api/sessions/:id/resume — bring the agent back (relaunch ONLY if confirmed offline); demotes
313
- // working→idle, keeps any declaration. The RESUME GUARD REFUSES (409 {refused:true}) on a live/unproven agent;
314
- // `force` overrides for a wedged-but-alive process. {ok:false} otherwise = no such session (404). `info`
315
- // carries a non-error advisory.
316
- export async function clientResume(id: string, force = false): Promise<{ ok: boolean; error?: string; refused?: boolean; info?: string }> {
317
- await guarded('session resume')
318
- const r = await apiFetch(`/api/sessions/${seg(id)}/resume`, post({ force }))
319
- return await r.json().catch(() => ({ ok: false, error: `bad backend response (${r.status})` }))
320
- }
321
-
322
- // POST /api/sessions/:id/stop — the soft stop: kill tmux + socket, KEEP the worktree (session goes offline,
323
- // resumable). Distinct from close. {ok:false} = no such session.
324
- export async function clientStop(id: string): Promise<boolean> {
325
- await guarded('session stop')
326
- const r = await apiFetch(`/api/sessions/${seg(id)}/stop`, post({}))
327
- if (!r.ok) throw new BackendError(`backend refused to stop ${id}: ${await r.text()}`, r.status)
328
- return !!(await r.json().catch(() => ({ ok: false })))?.ok
329
- }
330
-
331
- // POST /api/sessions/:id/interrupt - native hard interrupt of the current turn. Unsupported harnesses and
332
- // unreachable control planes return the backend's loud DispatchResult; no signal/raw-key fallback exists.
333
- export async function clientInterrupt(id: string): Promise<DispatchResult> {
334
- await guarded('session interrupt')
335
- const r = await apiFetch(`/api/sessions/${seg(id)}/interrupt`, post({}))
336
- return await r.json().catch(() => ({ ok: false, error: `bad backend response (${r.status})` })) as DispatchResult
337
- }
338
-
339
- // POST /api/sessions/:id/close — terminal worktree removal. A client-side session id is only an unverified claim.
340
- export async function clientClose(id: string): Promise<boolean> {
341
- await guarded('session close')
342
- const source = envSessionId()
343
- const r = await apiFetch(`/api/sessions/${seg(id)}/close`, post({ source: source ? { kind: 'unverified-session-claim', id: source } : { kind: 'user' } }))
344
- if (!r.ok) throw new BackendError(`backend refused to close ${id}: ${await r.text()}`, r.status)
345
- return !!(await r.json().catch(() => ({ ok: false })))?.ok
346
- }
347
-
348
- export async function clientQuarantine(
349
- id: string,
350
- witness: { adapter: string; thread: string | null; tmux: string; worktree: string; branch: string },
351
- ): Promise<{ id: string; bundle: string; sha256: string; observedAt: string }> {
352
- await guarded('session quarantine')
353
- const r = await apiFetch(`/api/sessions/${seg(id)}/quarantine`, post(witness))
354
- if (!r.ok) throw new BackendError(`backend refused to quarantine ${id}: ${await r.text()}`, r.status)
355
- const body = await r.json() as { ok?: boolean; id?: string; bundle?: string; sha256?: string; observedAt?: string }
356
- if (!body.ok || !body.id || !body.bundle || !body.sha256 || !body.observedAt) throw new BackendError(`backend returned an invalid quarantine result for ${id}`, r.status)
357
- return { id: body.id, bundle: body.bundle, sha256: body.sha256, observedAt: body.observedAt }
358
- }
359
-
360
- export async function clientRestoreQuarantine(id: string): Promise<{ id: string; bundle: string; sha256: string; observedAt: string }> {
361
- await guarded('session quarantine')
362
- const r = await apiFetch(`/api/sessions/${seg(id)}/quarantine/restore`, post({}))
363
- if (!r.ok) throw new BackendError(`backend refused to restore ${id}: ${await r.text()}`, r.status)
364
- const body = await r.json() as { ok?: boolean; id?: string; bundle?: string; sha256?: string; observedAt?: string }
365
- if (!body.ok || !body.id || !body.bundle || !body.sha256 || !body.observedAt) throw new BackendError(`backend returned an invalid quarantine restore for ${id}`, r.status)
366
- return { id: body.id, bundle: body.bundle, sha256: body.sha256, observedAt: body.observedAt }
367
- }
368
-
369
- // POST /api/sessions/:id/archive — cold-archive the session ([[archive]]). The legacy on=false spelling is a
370
- // signpost to the same resume transition; it never performs a record-only unarchive.
371
- export async function clientArchive(id: string, on = true): Promise<boolean> {
372
- await guarded(on ? 'session archive' : 'session unarchive')
373
- const r = await apiFetch(`/api/sessions/${seg(id)}/archive`, post({ on }))
374
- if (!r.ok) throw new BackendError(`backend refused to ${on ? 'archive' : 'unarchive'} ${id}: ${await r.text()}`, r.status)
375
- return !!(await r.json().catch(() => ({ ok: false })))?.ok
376
- }
377
-
378
- // POST /api/sessions/:id/rename — set (or clear, with a blank) the session's display-name override
379
- // ([[session-rename]] as a CLI verb). {ok:false} = no such session (404).
380
- export async function clientRename(id: string, name: string): Promise<boolean> {
381
- await guarded('session rename')
382
- const r = await apiFetch(`/api/sessions/${seg(id)}/rename`, post({ name }))
383
- return !!(await r.json().catch(() => ({ ok: false })))?.ok
384
- }
385
-
386
- export async function clientReparent(children: string[], parent: string): Promise<import('./sessions.js').SessionReparentResult> {
387
- await guarded('session reparent')
388
- const r = await apiFetch('/api/sessions/reparent', post({ children, parent }))
389
- if (!r.ok) throw new BackendError(`backend refused to reparent sessions: ${await r.text()}`, r.status)
390
- return await r.json() as import('./sessions.js').SessionReparentResult
391
- }
392
-
393
- // POST /api/sessions/:id/input {kind:"keys"} — the LAST-RESORT raw nav-key face of send (tmux send-keys,
394
- // NEVER the prompt socket): an ordered token batch drives an interactive TUI menu
395
- // ([[nav-mode-key-ordering]]). {ok:false} = unknown session, no live pane, or no valid token delivered.
396
- export async function clientSendRawKeys(id: string, keys: string[]): Promise<boolean> {
397
- await guarded('session send')
398
- const r = await apiFetch(`/api/sessions/${seg(id)}/input`, post({ kind: 'keys', keys }))
399
- return !!(await r.json().catch(() => ({ ok: false })))?.ok
400
- }
401
-
402
- // GET /api/sessions/:id — the session RECORD detail (`spex session show`): the board row plus the full
403
- // originating prompt. 404 → no such session.
404
- export type ShowResult = { ok: true; session: Session & { prompt: string | null } } | { ok: false; status: number }
405
- export async function clientShow(id: string): Promise<ShowResult> {
406
- return cachedRead(async () => {
407
- const r = await apiFetch(`/api/sessions/${seg(id)}`)
408
- if (r.ok) return { ok: true, session: await r.json() as Session & { prompt: string | null } }
409
- return { ok: false, status: r.status }
410
- }, () => {
411
- const session = localCachedSessions(true).find((item) => item.id === id)
412
- return session ? { ok: true, session } : { ok: false, status: 404 }
413
- })
414
- }
@@ -1,43 +0,0 @@
1
- import { reviewPayload, type ReviewEvalGate, type ReviewPayload } from './sessions.js'
2
- import { sessionEvalProjection } from '../../spec-eval/src/sessioneval.js'
3
-
4
- // @@@ cockpit - where the manager's review answer is ASSEMBLED ([[manager-cockpit]]). It sits above both the
5
- // session layer and the eval layer and may import either; that is what makes it the only honest home for a
6
- // value composed from both. `sessions.ts` cannot be that home — the eval package imports it, so reaching the
7
- // other way from there is a cycle, and the cycle used to be paid for with a deferred `await import()` whose
8
- // comment explained why it had to be wrong. `reviews.ts` cannot be it either: that file is [[paged-review]]'s
9
- // Issues/Evals paging server, and parking a session-cockpit concern under a node about paging would make that
10
- // node's body false. It imports the eval package for its own reasons — the same direction, a different one.
11
-
12
- // @@@ ONE composition, every entry point - `gates.evals` has exactly one producer, and it is this function.
13
- // The cockpit review is reachable two ways: the HTTP route, and `clientReview`'s local answer when no backend
14
- // resolves. If each composed its own gates, the same verb would report different shapes depending on whether a
15
- // backend happened to be running — the very asymmetry the remote-client role split exists to remove — and a
16
- // drift between the two readouts would be caught by no gate we have. So both call HERE.
17
- export type CockpitReview = Omit<ReviewPayload, 'gates'> & {
18
- gates: ReviewPayload['gates'] & { evals: ReviewEvalGate }
19
- }
20
-
21
- // @@@ evalGate - the measured-loss readout, taken from [[session-eval]]'s EXISTING projection. This is a cache
22
- // READ and must stay one: `buildSessionEvals()` calls `reviewPayload()` itself, so BUILDING the model from here
23
- // would recurse. That hazard used to be held off by a comment; now it is structural — `reviewPayload` no longer
24
- // carries this field, so the eval side cannot re-enter through it. (It never read the field anyway: `gateRows`
25
- // consumes lint/conflict/ahead/dirty only. The payload was carrying a value for a caller that ignored it.)
26
- async function evalGate(id: string): Promise<ReviewEvalGate> {
27
- const projection = sessionEvalProjection(id)
28
- if (!projection) return { phase: 'unavailable' }
29
- // only a `ready` projection carries a CURRENT value; last-known is deliberately not reported as current.
30
- if (projection.phase !== 'ready' || !projection.value) {
31
- return { phase: projection.phase === 'ready' ? 'unavailable' : projection.phase }
32
- }
33
- const summary = projection.value
34
- return { phase: 'ready', freshPass: summary.pass, freshFail: summary.fail, needReview: summary.review, blind: summary.blind }
35
- }
36
-
37
- // the cockpit's whole answer for one session: the session-side review plus the eval readout, composed once.
38
- // The two run in parallel — the eval half is a projection read, independent of every git read in the payload.
39
- export async function cockpitReview(id: string): Promise<CockpitReview | null> {
40
- const [payload, evals] = await Promise.all([reviewPayload(id), evalGate(id)])
41
- if (!payload) return null
42
- return { ...payload, gates: { ...payload.gates, evals } }
43
- }