spexcode 0.6.2 → 0.6.5

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 (479) hide show
  1. package/README.md +3 -1
  2. package/bin/spex.mjs +4 -0
  3. package/node_modules/@spexcode/spec-cli/bin/spex.mjs +76 -0
  4. package/node_modules/@spexcode/spec-cli/dist/attach.d.ts +2 -0
  5. package/node_modules/@spexcode/spec-cli/dist/attach.js +48 -0
  6. package/node_modules/@spexcode/spec-cli/dist/claude-headless.d.ts +33 -0
  7. package/node_modules/@spexcode/spec-cli/dist/claude-headless.js +307 -0
  8. package/node_modules/@spexcode/spec-cli/dist/cli.d.ts +1 -0
  9. package/node_modules/@spexcode/spec-cli/dist/cli.js +1859 -0
  10. package/node_modules/@spexcode/spec-cli/dist/client.d.ts +111 -0
  11. package/node_modules/@spexcode/spec-cli/dist/client.js +476 -0
  12. package/node_modules/@spexcode/spec-cli/dist/cockpit.d.ts +7 -0
  13. package/node_modules/@spexcode/spec-cli/dist/cockpit.js +26 -0
  14. package/node_modules/@spexcode/spec-cli/dist/codex-headless.d.ts +1 -0
  15. package/{spec-cli/src/codex-headless.ts → node_modules/@spexcode/spec-cli/dist/codex-headless.js} +3 -9
  16. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.d.ts +53 -0
  17. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.js +686 -0
  18. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.d.ts +1 -0
  19. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.js +90 -0
  20. package/node_modules/@spexcode/spec-cli/dist/contract-filter.d.ts +14 -0
  21. package/node_modules/@spexcode/spec-cli/dist/contract-filter.js +219 -0
  22. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.d.ts +6 -0
  23. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.js +50 -0
  24. package/node_modules/@spexcode/spec-cli/dist/delivery-queue.d.ts +23 -0
  25. package/node_modules/@spexcode/spec-cli/dist/delivery-queue.js +179 -0
  26. package/node_modules/@spexcode/spec-cli/dist/doctor.d.ts +9 -0
  27. package/node_modules/@spexcode/spec-cli/dist/doctor.js +547 -0
  28. package/node_modules/@spexcode/spec-cli/dist/eval-host.d.ts +1 -0
  29. package/node_modules/@spexcode/spec-cli/dist/eval-host.js +19 -0
  30. package/node_modules/@spexcode/spec-cli/dist/execution-trace.d.ts +26 -0
  31. package/node_modules/@spexcode/spec-cli/dist/execution-trace.js +475 -0
  32. package/node_modules/@spexcode/spec-cli/dist/file-write.d.ts +2 -0
  33. package/node_modules/@spexcode/spec-cli/dist/file-write.js +26 -0
  34. package/node_modules/@spexcode/spec-cli/dist/flat.d.ts +89 -0
  35. package/node_modules/@spexcode/spec-cli/dist/flat.js +1076 -0
  36. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.d.ts +56 -0
  37. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.js +168 -0
  38. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.d.ts +28 -0
  39. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.js +361 -0
  40. package/node_modules/@spexcode/spec-cli/dist/gateway.d.ts +37 -0
  41. package/node_modules/@spexcode/spec-cli/dist/gateway.js +503 -0
  42. package/node_modules/@spexcode/spec-cli/dist/graphCache.d.ts +27 -0
  43. package/node_modules/@spexcode/spec-cli/dist/graphCache.js +716 -0
  44. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.d.ts +14 -0
  45. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.js +35 -0
  46. package/node_modules/@spexcode/spec-cli/dist/graphStream.d.ts +85 -0
  47. package/node_modules/@spexcode/spec-cli/dist/graphStream.js +1195 -0
  48. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.d.ts +64 -0
  49. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.js +166 -0
  50. package/node_modules/@spexcode/spec-cli/dist/guide.d.ts +8 -0
  51. package/{spec-cli/src/guide.ts → node_modules/@spexcode/spec-cli/dist/guide.js} +36 -32
  52. package/node_modules/@spexcode/spec-cli/dist/harness-select.d.ts +18 -0
  53. package/node_modules/@spexcode/spec-cli/dist/harness-select.js +62 -0
  54. package/node_modules/@spexcode/spec-cli/dist/harness.d.ts +325 -0
  55. package/node_modules/@spexcode/spec-cli/dist/harness.js +3026 -0
  56. package/node_modules/@spexcode/spec-cli/dist/headless-controller.d.ts +9 -0
  57. package/node_modules/@spexcode/spec-cli/dist/headless-controller.js +47 -0
  58. package/node_modules/@spexcode/spec-cli/dist/help.d.ts +10 -0
  59. package/node_modules/@spexcode/spec-cli/dist/help.js +574 -0
  60. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.d.ts +18 -0
  61. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.js +122 -0
  62. package/node_modules/@spexcode/spec-cli/dist/hooks.d.ts +1 -0
  63. package/{spec-cli/src/hooks.ts → node_modules/@spexcode/spec-cli/dist/hooks.js} +15 -15
  64. package/node_modules/@spexcode/spec-cli/dist/host-resources.d.ts +97 -0
  65. package/node_modules/@spexcode/spec-cli/dist/host-resources.js +795 -0
  66. package/node_modules/@spexcode/spec-cli/dist/host.d.ts +88 -0
  67. package/node_modules/@spexcode/spec-cli/dist/host.js +663 -0
  68. package/node_modules/@spexcode/spec-cli/dist/index.d.ts +1 -0
  69. package/node_modules/@spexcode/spec-cli/dist/index.js +899 -0
  70. package/node_modules/@spexcode/spec-cli/dist/init.d.ts +1 -0
  71. package/node_modules/@spexcode/spec-cli/dist/init.js +284 -0
  72. package/node_modules/@spexcode/spec-cli/dist/issues-cli.d.ts +6 -0
  73. package/node_modules/@spexcode/spec-cli/dist/issues-cli.js +334 -0
  74. package/node_modules/@spexcode/spec-cli/dist/issues.d.ts +69 -0
  75. package/node_modules/@spexcode/spec-cli/dist/issues.js +189 -0
  76. package/node_modules/@spexcode/spec-cli/dist/lint.d.ts +34 -0
  77. package/node_modules/@spexcode/spec-cli/dist/lint.js +476 -0
  78. package/node_modules/@spexcode/spec-cli/dist/listen.d.ts +7 -0
  79. package/{spec-cli/src/listen.ts → node_modules/@spexcode/spec-cli/dist/listen.js} +13 -17
  80. package/node_modules/@spexcode/spec-cli/dist/localIssues.d.ts +65 -0
  81. package/node_modules/@spexcode/spec-cli/dist/localIssues.js +582 -0
  82. package/node_modules/@spexcode/spec-cli/dist/login-page.d.ts +5 -0
  83. package/{spec-cli/src/login-page.ts → node_modules/@spexcode/spec-cli/dist/login-page.js} +7 -7
  84. package/node_modules/@spexcode/spec-cli/dist/loop-in.d.ts +23 -0
  85. package/{spec-cli/src/loop-in.ts → node_modules/@spexcode/spec-cli/dist/loop-in.js} +35 -45
  86. package/node_modules/@spexcode/spec-cli/dist/machine-peer.d.ts +69 -0
  87. package/node_modules/@spexcode/spec-cli/dist/machine-peer.js +603 -0
  88. package/node_modules/@spexcode/spec-cli/dist/materialize.d.ts +18 -0
  89. package/node_modules/@spexcode/spec-cli/dist/materialize.js +468 -0
  90. package/node_modules/@spexcode/spec-cli/dist/mentions.d.ts +50 -0
  91. package/node_modules/@spexcode/spec-cli/dist/mentions.js +117 -0
  92. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.d.ts +4 -0
  93. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.js +208 -0
  94. package/node_modules/@spexcode/spec-cli/dist/opencode.d.ts +3 -0
  95. package/{spec-cli/src/opencode.ts → node_modules/@spexcode/spec-cli/dist/opencode.js} +9 -13
  96. package/node_modules/@spexcode/spec-cli/dist/pi-harness.d.ts +3 -0
  97. package/{spec-cli/src/pi-harness.ts → node_modules/@spexcode/spec-cli/dist/pi-harness.js} +45 -40
  98. package/node_modules/@spexcode/spec-cli/dist/pi-headless.d.ts +25 -0
  99. package/node_modules/@spexcode/spec-cli/dist/pi-headless.js +196 -0
  100. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.d.ts +21 -0
  101. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.js +146 -0
  102. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.d.ts +10 -0
  103. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.js +404 -0
  104. package/node_modules/@spexcode/spec-cli/dist/pty-helper.d.mts +1 -0
  105. package/node_modules/@spexcode/spec-cli/dist/pty-helper.mjs +101 -0
  106. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.d.mts +2 -0
  107. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.mjs +23 -0
  108. package/node_modules/@spexcode/spec-cli/dist/public-graph.d.ts +46 -0
  109. package/node_modules/@spexcode/spec-cli/dist/public-graph.js +56 -0
  110. package/node_modules/@spexcode/spec-cli/dist/ranker.d.ts +15 -0
  111. package/node_modules/@spexcode/spec-cli/dist/ranker.js +188 -0
  112. package/node_modules/@spexcode/spec-cli/dist/reaper.d.ts +6 -0
  113. package/node_modules/@spexcode/spec-cli/dist/reaper.js +81 -0
  114. package/node_modules/@spexcode/spec-cli/dist/reviews.d.ts +189 -0
  115. package/node_modules/@spexcode/spec-cli/dist/reviews.js +350 -0
  116. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.d.ts +6 -0
  117. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.js +37 -0
  118. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.d.ts +21 -0
  119. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.js +84 -0
  120. package/node_modules/@spexcode/spec-cli/dist/search.bench.d.mts +1 -0
  121. package/node_modules/@spexcode/spec-cli/dist/search.bench.mjs +75 -0
  122. package/node_modules/@spexcode/spec-cli/dist/search.d.ts +20 -0
  123. package/node_modules/@spexcode/spec-cli/dist/search.js +61 -0
  124. package/node_modules/@spexcode/spec-cli/dist/session-cursors.d.ts +14 -0
  125. package/node_modules/@spexcode/spec-cli/dist/session-cursors.js +82 -0
  126. package/node_modules/@spexcode/spec-cli/dist/session-declarations.d.ts +13 -0
  127. package/node_modules/@spexcode/spec-cli/dist/session-declarations.js +126 -0
  128. package/node_modules/@spexcode/spec-cli/dist/session-execution.d.ts +10 -0
  129. package/node_modules/@spexcode/spec-cli/dist/session-execution.js +70 -0
  130. package/node_modules/@spexcode/spec-cli/dist/session-files.d.ts +28 -0
  131. package/node_modules/@spexcode/spec-cli/dist/session-files.js +130 -0
  132. package/node_modules/@spexcode/spec-cli/dist/session-follow.d.ts +31 -0
  133. package/node_modules/@spexcode/spec-cli/dist/session-follow.js +179 -0
  134. package/node_modules/@spexcode/spec-cli/dist/session-reparent.d.ts +10 -0
  135. package/node_modules/@spexcode/spec-cli/dist/session-reparent.js +33 -0
  136. package/node_modules/@spexcode/spec-cli/dist/session-timeline.d.ts +51 -0
  137. package/node_modules/@spexcode/spec-cli/dist/session-timeline.js +233 -0
  138. package/node_modules/@spexcode/spec-cli/dist/session-web.d.ts +24 -0
  139. package/node_modules/@spexcode/spec-cli/dist/session-web.js +141 -0
  140. package/node_modules/@spexcode/spec-cli/dist/sessions.d.ts +412 -0
  141. package/node_modules/@spexcode/spec-cli/dist/sessions.js +4239 -0
  142. package/node_modules/@spexcode/spec-cli/dist/sh.d.ts +1 -0
  143. package/node_modules/@spexcode/spec-cli/dist/sh.js +3 -0
  144. package/node_modules/@spexcode/spec-cli/dist/shim-runtime.d.ts +1 -0
  145. package/{spec-cli/src/shim-runtime.ts → node_modules/@spexcode/spec-cli/dist/shim-runtime.js} +3 -4
  146. package/node_modules/@spexcode/spec-cli/dist/slash-commands.d.ts +9 -0
  147. package/node_modules/@spexcode/spec-cli/dist/slash-commands.js +307 -0
  148. package/node_modules/@spexcode/spec-cli/dist/source-files.d.ts +9 -0
  149. package/node_modules/@spexcode/spec-cli/dist/source-files.js +113 -0
  150. package/node_modules/@spexcode/spec-cli/dist/supervise.d.ts +1 -0
  151. package/node_modules/@spexcode/spec-cli/dist/supervise.js +308 -0
  152. package/node_modules/@spexcode/spec-cli/dist/tree.d.ts +25 -0
  153. package/node_modules/@spexcode/spec-cli/dist/tree.js +98 -0
  154. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.d.ts +3 -0
  155. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.js +41 -0
  156. package/node_modules/@spexcode/spec-cli/dist/uninstall.d.ts +3 -0
  157. package/node_modules/@spexcode/spec-cli/dist/uninstall.js +177 -0
  158. package/node_modules/@spexcode/spec-cli/dist/uploads.d.ts +36 -0
  159. package/node_modules/@spexcode/spec-cli/dist/uploads.js +243 -0
  160. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.d.ts +1 -0
  161. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.js +47 -0
  162. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/dispatch.sh +5 -5
  163. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/harness.sh +1 -1
  164. package/node_modules/@spexcode/spec-cli/package.json +47 -0
  165. package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -0
  166. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec-first.sh +1 -1
  167. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec-of-file.sh +1 -0
  168. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/spec.md +2 -2
  169. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/stop-gate.sh +31 -29
  170. package/node_modules/@spexcode/spec-core/dist/anchors.d.ts +94 -0
  171. package/node_modules/@spexcode/spec-core/dist/anchors.js +730 -0
  172. package/node_modules/@spexcode/spec-core/dist/git.d.ts +166 -0
  173. package/node_modules/@spexcode/spec-core/dist/git.js +2736 -0
  174. package/node_modules/@spexcode/spec-core/dist/graph-delta.d.ts +44 -0
  175. package/node_modules/@spexcode/spec-core/dist/graph-delta.js +72 -0
  176. package/node_modules/@spexcode/spec-core/dist/graph.d.ts +34 -0
  177. package/node_modules/@spexcode/spec-core/dist/graph.js +237 -0
  178. package/node_modules/@spexcode/spec-core/dist/graphDelta.d.ts +3 -0
  179. package/node_modules/@spexcode/spec-core/dist/graphDelta.js +13 -0
  180. package/node_modules/@spexcode/spec-core/dist/harness-identity.d.ts +31 -0
  181. package/node_modules/@spexcode/spec-core/dist/harness-identity.js +20 -0
  182. package/node_modules/@spexcode/spec-core/dist/identity-presets.d.ts +152 -0
  183. package/node_modules/@spexcode/spec-core/dist/identity-presets.js +132 -0
  184. package/node_modules/@spexcode/spec-core/dist/index.d.ts +45 -0
  185. package/node_modules/@spexcode/spec-core/dist/index.js +19 -0
  186. package/node_modules/@spexcode/spec-core/dist/layout.d.ts +183 -0
  187. package/node_modules/@spexcode/spec-core/dist/layout.js +548 -0
  188. package/node_modules/@spexcode/spec-core/dist/process-identity.d.ts +37 -0
  189. package/node_modules/@spexcode/spec-core/dist/process-identity.js +214 -0
  190. package/node_modules/@spexcode/spec-core/dist/project-identity.d.ts +12 -0
  191. package/node_modules/@spexcode/spec-core/dist/project-identity.js +71 -0
  192. package/node_modules/@spexcode/spec-core/dist/project-store.d.ts +3 -0
  193. package/node_modules/@spexcode/spec-core/dist/project-store.js +14 -0
  194. package/node_modules/@spexcode/spec-core/dist/resilience.d.ts +2 -0
  195. package/node_modules/@spexcode/spec-core/dist/resilience.js +40 -0
  196. package/node_modules/@spexcode/spec-core/dist/review/index.d.ts +3 -0
  197. package/node_modules/@spexcode/spec-core/dist/review/index.js +5 -0
  198. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.d.ts +77 -0
  199. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.js +308 -0
  200. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.d.ts +66 -0
  201. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.js +180 -0
  202. package/node_modules/@spexcode/spec-core/dist/review/session.d.ts +4 -0
  203. package/node_modules/@spexcode/spec-core/dist/review/session.js +8 -0
  204. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.d.ts +15 -0
  205. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.js +12 -0
  206. package/node_modules/@spexcode/spec-core/dist/root-lru.d.ts +4 -0
  207. package/{spec-cli/src/root-lru.ts → node_modules/@spexcode/spec-core/dist/root-lru.js} +26 -30
  208. package/node_modules/@spexcode/spec-core/dist/specs.d.ts +117 -0
  209. package/node_modules/@spexcode/spec-core/dist/specs.js +489 -0
  210. package/node_modules/@spexcode/spec-core/package.json +28 -0
  211. package/node_modules/@spexcode/spec-eval/dist/cache.d.ts +10 -0
  212. package/node_modules/@spexcode/spec-eval/dist/cache.js +50 -0
  213. package/node_modules/@spexcode/spec-eval/dist/cli.d.ts +22 -0
  214. package/node_modules/@spexcode/spec-eval/dist/cli.js +981 -0
  215. package/node_modules/@spexcode/spec-eval/dist/evaltab.d.ts +98 -0
  216. package/node_modules/@spexcode/spec-eval/dist/evaltab.js +176 -0
  217. package/node_modules/@spexcode/spec-eval/dist/filing.d.ts +16 -0
  218. package/node_modules/@spexcode/spec-eval/dist/filing.js +36 -0
  219. package/node_modules/@spexcode/spec-eval/dist/freshness.d.ts +48 -0
  220. package/node_modules/@spexcode/spec-eval/dist/freshness.js +799 -0
  221. package/node_modules/@spexcode/spec-eval/dist/host.d.ts +46 -0
  222. package/node_modules/@spexcode/spec-eval/dist/host.js +53 -0
  223. package/node_modules/@spexcode/spec-eval/dist/humanok.d.ts +11 -0
  224. package/node_modules/@spexcode/spec-eval/dist/humanok.js +27 -0
  225. package/node_modules/@spexcode/spec-eval/dist/index.d.ts +4 -0
  226. package/node_modules/@spexcode/spec-eval/dist/index.js +4 -0
  227. package/node_modules/@spexcode/spec-eval/dist/remarks.d.ts +31 -0
  228. package/node_modules/@spexcode/spec-eval/dist/remarks.js +1 -0
  229. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.d.ts +13 -0
  230. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.js +303 -0
  231. package/node_modules/@spexcode/spec-eval/dist/scenarios.d.ts +99 -0
  232. package/node_modules/@spexcode/spec-eval/dist/scenarios.js +650 -0
  233. package/node_modules/@spexcode/spec-eval/dist/sessioneval.d.ts +307 -0
  234. package/node_modules/@spexcode/spec-eval/dist/sessioneval.js +1883 -0
  235. package/node_modules/@spexcode/spec-eval/dist/sidecar.d.ts +55 -0
  236. package/node_modules/@spexcode/spec-eval/dist/sidecar.js +82 -0
  237. package/node_modules/@spexcode/spec-eval/dist/timeline.d.ts +25 -0
  238. package/node_modules/@spexcode/spec-eval/dist/timeline.js +65 -0
  239. package/node_modules/@spexcode/spec-eval/dist/ui-path.d.ts +1 -0
  240. package/node_modules/@spexcode/spec-eval/dist/ui-path.js +2 -0
  241. package/node_modules/@spexcode/spec-eval/package.json +36 -0
  242. package/node_modules/@spexcode/spec-forge/dist/cache.d.ts +29 -0
  243. package/node_modules/@spexcode/spec-forge/dist/cache.js +59 -0
  244. package/node_modules/@spexcode/spec-forge/dist/cli.d.ts +1 -0
  245. package/node_modules/@spexcode/spec-forge/dist/cli.js +100 -0
  246. package/node_modules/@spexcode/spec-forge/dist/drivers/github.d.ts +2 -0
  247. package/node_modules/@spexcode/spec-forge/dist/drivers/github.js +116 -0
  248. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.d.ts +7 -0
  249. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.js +144 -0
  250. package/node_modules/@spexcode/spec-forge/dist/drivers.d.ts +10 -0
  251. package/node_modules/@spexcode/spec-forge/dist/drivers.js +83 -0
  252. package/node_modules/@spexcode/spec-forge/dist/index.d.ts +4 -0
  253. package/node_modules/@spexcode/spec-forge/dist/index.js +4 -0
  254. package/node_modules/@spexcode/spec-forge/dist/links.d.ts +15 -0
  255. package/node_modules/@spexcode/spec-forge/dist/links.js +65 -0
  256. package/node_modules/@spexcode/spec-forge/dist/needs-eval.d.ts +10 -0
  257. package/node_modules/@spexcode/spec-forge/dist/needs-eval.js +20 -0
  258. package/node_modules/@spexcode/spec-forge/dist/port.d.ts +53 -0
  259. package/node_modules/@spexcode/spec-forge/dist/port.js +1 -0
  260. package/node_modules/@spexcode/spec-forge/dist/resident.d.ts +7 -0
  261. package/node_modules/@spexcode/spec-forge/dist/resident.js +43 -0
  262. package/node_modules/@spexcode/spec-forge/package.json +32 -0
  263. package/package.json +33 -19
  264. package/spec-cli/bin/spex.mjs +0 -69
  265. package/spec-cli/src/anchors.ts +0 -728
  266. package/spec-cli/src/attach.ts +0 -43
  267. package/spec-cli/src/claude-headless.ts +0 -321
  268. package/spec-cli/src/cli.ts +0 -1258
  269. package/spec-cli/src/client.ts +0 -414
  270. package/spec-cli/src/cockpit.ts +0 -43
  271. package/spec-cli/src/codex-runtime-generations.ts +0 -646
  272. package/spec-cli/src/commit-surgery.ts +0 -68
  273. package/spec-cli/src/contract-filter.ts +0 -202
  274. package/spec-cli/src/delivery-queue.ts +0 -165
  275. package/spec-cli/src/doctor.ts +0 -516
  276. package/spec-cli/src/execution-trace.ts +0 -444
  277. package/spec-cli/src/file-write.ts +0 -22
  278. package/spec-cli/src/gateway-auth.ts +0 -181
  279. package/spec-cli/src/gateway-hub.ts +0 -358
  280. package/spec-cli/src/gateway.ts +0 -461
  281. package/spec-cli/src/git.ts +0 -2556
  282. package/spec-cli/src/graph.ts +0 -271
  283. package/spec-cli/src/graphCache.ts +0 -710
  284. package/spec-cli/src/graphDelta.ts +0 -77
  285. package/spec-cli/src/graphStream.ts +0 -1019
  286. package/spec-cli/src/harness-select.ts +0 -77
  287. package/spec-cli/src/harness.ts +0 -3025
  288. package/spec-cli/src/headless-controller.ts +0 -63
  289. package/spec-cli/src/help.ts +0 -492
  290. package/spec-cli/src/host-resources.ts +0 -762
  291. package/spec-cli/src/host.ts +0 -611
  292. package/spec-cli/src/identity-presets.d.ts +0 -13
  293. package/spec-cli/src/identity-presets.js +0 -138
  294. package/spec-cli/src/index.ts +0 -818
  295. package/spec-cli/src/init.ts +0 -258
  296. package/spec-cli/src/issues-cli.ts +0 -276
  297. package/spec-cli/src/issues.ts +0 -237
  298. package/spec-cli/src/layout.ts +0 -640
  299. package/spec-cli/src/lint.ts +0 -488
  300. package/spec-cli/src/localIssues.ts +0 -538
  301. package/spec-cli/src/materialize.ts +0 -417
  302. package/spec-cli/src/mentions.ts +0 -81
  303. package/spec-cli/src/opencode-headless.ts +0 -205
  304. package/spec-cli/src/pi-headless.ts +0 -153
  305. package/spec-cli/src/plugin-harness.ts +0 -157
  306. package/spec-cli/src/process-identity.ts +0 -207
  307. package/spec-cli/src/project-identity.ts +0 -73
  308. package/spec-cli/src/project-store.ts +0 -17
  309. package/spec-cli/src/pty-bridge.ts +0 -396
  310. package/spec-cli/src/pty-helper.mjs +0 -96
  311. package/spec-cli/src/pty-native-helper.mjs +0 -22
  312. package/spec-cli/src/ranker.ts +0 -191
  313. package/spec-cli/src/reaper.ts +0 -125
  314. package/spec-cli/src/resilience.ts +0 -41
  315. package/spec-cli/src/reviewSnapshot.ts +0 -28
  316. package/spec-cli/src/reviews.ts +0 -434
  317. package/spec-cli/src/runtime-guard.ts +0 -35
  318. package/spec-cli/src/runtime-ownership.ts +0 -88
  319. package/spec-cli/src/search.bench.mjs +0 -80
  320. package/spec-cli/src/search.ts +0 -63
  321. package/spec-cli/src/session-cursors.ts +0 -91
  322. package/spec-cli/src/session-execution.ts +0 -68
  323. package/spec-cli/src/session-files.ts +0 -121
  324. package/spec-cli/src/session-follow.ts +0 -182
  325. package/spec-cli/src/session-reparent.ts +0 -33
  326. package/spec-cli/src/session-timeline.ts +0 -247
  327. package/spec-cli/src/session-web.ts +0 -135
  328. package/spec-cli/src/sessions.ts +0 -3883
  329. package/spec-cli/src/sh.ts +0 -3
  330. package/spec-cli/src/slash-commands.ts +0 -318
  331. package/spec-cli/src/source-files.ts +0 -104
  332. package/spec-cli/src/specs.ts +0 -498
  333. package/spec-cli/src/supervise.ts +0 -245
  334. package/spec-cli/src/tree.ts +0 -118
  335. package/spec-cli/src/tsx-bin.ts +0 -18
  336. package/spec-cli/src/uninstall.ts +0 -171
  337. package/spec-cli/src/uploads.ts +0 -253
  338. package/spec-cli/src/worktree-sources.ts +0 -42
  339. package/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +0 -8
  340. package/spec-dashboard/dist/assets/App-B6IbFbGu.js +0 -2
  341. package/spec-dashboard/dist/assets/Dashboard-C5ap-Sga.css +0 -1
  342. package/spec-dashboard/dist/assets/Dashboard-_sDk7Rcg.js +0 -27
  343. package/spec-dashboard/dist/assets/EvalsPage-BT357Lyt.js +0 -2
  344. package/spec-dashboard/dist/assets/IssuesPage-BG9rNOgV.js +0 -1
  345. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  346. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  347. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  348. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  349. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  350. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  351. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  352. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  353. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  354. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  355. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  356. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  357. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  358. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  359. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  360. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  361. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  362. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  363. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  364. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  365. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  366. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  367. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  368. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  369. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  370. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  371. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  372. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  373. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  374. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  375. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  376. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  377. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  378. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  379. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  380. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  381. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  382. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  383. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  384. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  385. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  386. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  387. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  388. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  389. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  390. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  391. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  392. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  393. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  394. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  395. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  396. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  397. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  398. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  399. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  400. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  401. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  402. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  403. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  404. package/spec-dashboard/dist/assets/MobileApp-D9yPMR3A.js +0 -2
  405. package/spec-dashboard/dist/assets/Modal-B3EcgeA3.js +0 -1
  406. package/spec-dashboard/dist/assets/PageScroll-CNZOugWV.js +0 -1
  407. package/spec-dashboard/dist/assets/ProjectsPage-C2CRHmvs.js +0 -1
  408. package/spec-dashboard/dist/assets/SessionInterface-6GBZ9nXN.css +0 -32
  409. package/spec-dashboard/dist/assets/SessionInterface-DOEjuT3l.js +0 -40
  410. package/spec-dashboard/dist/assets/SessionWindow-1nYgZ4CL.js +0 -1
  411. package/spec-dashboard/dist/assets/Settings-7WeTJn0V.js +0 -1
  412. package/spec-dashboard/dist/assets/Thread-CEbzAFQn.js +0 -13
  413. package/spec-dashboard/dist/assets/bindings-BC9vqpYU.js +0 -1
  414. package/spec-dashboard/dist/assets/data-SlvxNA2r.js +0 -1
  415. package/spec-dashboard/dist/assets/index-DLVeOHL-.js +0 -41
  416. package/spec-dashboard/dist/assets/index-DYLGfPjx.css +0 -1
  417. package/spec-dashboard/dist/assets/launch-Cp579UoJ.css +0 -1
  418. package/spec-dashboard/dist/assets/launch-yxCYr64x.js +0 -276
  419. package/spec-dashboard/dist/assets/sessionSurface--7l69h4F.js +0 -1
  420. package/spec-dashboard/dist/index.html +0 -29
  421. package/spec-dashboard/src/reviewFilters.js +0 -322
  422. package/spec-dashboard/src/reviewQuery.js +0 -174
  423. package/spec-dashboard/src/session.js +0 -199
  424. package/spec-eval/src/cache.ts +0 -57
  425. package/spec-eval/src/cli.ts +0 -894
  426. package/spec-eval/src/evaltab.ts +0 -264
  427. package/spec-eval/src/filing.ts +0 -39
  428. package/spec-eval/src/freshness.ts +0 -836
  429. package/spec-eval/src/humanok.ts +0 -28
  430. package/spec-eval/src/scenariofresh.ts +0 -244
  431. package/spec-eval/src/scenarios.ts +0 -672
  432. package/spec-eval/src/sessioneval.ts +0 -2220
  433. package/spec-eval/src/sidecar.ts +0 -93
  434. package/spec-eval/src/timeline.ts +0 -54
  435. package/spec-forge/src/__fixtures__/github-forge.json +0 -63
  436. package/spec-forge/src/cache.ts +0 -66
  437. package/spec-forge/src/cli.ts +0 -99
  438. package/spec-forge/src/drivers/github.ts +0 -132
  439. package/spec-forge/src/drivers/gitlab.ts +0 -153
  440. package/spec-forge/src/drivers.ts +0 -73
  441. package/spec-forge/src/links.ts +0 -72
  442. package/spec-forge/src/needs-eval.ts +0 -29
  443. package/spec-forge/src/port.ts +0 -36
  444. package/spec-forge/src/resident.ts +0 -46
  445. /package/{spec-cli → node_modules/@spexcode/spec-cli}/README.md +0 -0
  446. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-0.5.2-eef1.fixture +0 -0
  447. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-sed-v0.fixture +0 -0
  448. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/commit-msg +0 -0
  449. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-checkout +0 -0
  450. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-merge +0 -0
  451. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/pre-commit +0 -0
  452. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/prepare-commit-msg +0 -0
  453. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/reference-transaction +0 -0
  454. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/extract/spec.md +0 -0
  455. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/regroup/spec.md +0 -0
  456. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/rename/spec.md +0 -0
  457. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/spec.md +0 -0
  458. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/tidy/spec.md +0 -0
  459. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/comment-altitude/spec.md +0 -0
  460. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/idle.sh +0 -0
  461. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/spec.md +0 -0
  462. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/mark-active.sh +0 -0
  463. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/spec.md +0 -0
  464. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/fail.sh +0 -0
  465. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/spec.md +0 -0
  466. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec.md +0 -0
  467. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec.md +0 -0
  468. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec.md +0 -0
  469. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +0 -0
  470. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/forge-link/spec.md +0 -0
  471. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +0 -0
  472. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +0 -0
  473. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/spec.md +0 -0
  474. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/digest.mjs +0 -0
  475. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/spec.md +0 -0
  476. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/spec.md +0 -0
  477. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/spec.md +0 -0
  478. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/spec.md +0 -0
  479. /package/{spec-cli → node_modules/@spexcode/spec-core}/templates/spexcode.json +0 -0
package/README.md CHANGED
@@ -94,11 +94,13 @@ workflow on its own.
94
94
  When you want the live board (the graph, sessions, evals), start the runtime:
95
95
 
96
96
  ```sh
97
+ npm i -g @spexcode/spec-dashboard # install the optional UI package once
97
98
  spex serve # this project's backend — prints its URL
98
99
  spex dashboard # the machine's one gateway — every project behind one URL
99
100
  ```
100
101
 
101
- One `spex dashboard` per machine is enough: every project you serve shows up behind it, and its
102
+ The dashboard is a separate package so writing-only installs do not carry frontend build output. One `spex dashboard`
103
+ per machine is enough: every project you serve shows up behind it, and its
102
104
  `/projects` page manages them from the browser.
103
105
  [Getting started](https://spexcode.net/getting-started/) walks the rest of the setup.
104
106
 
package/bin/spex.mjs ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ // @@@ root release launcher ([[release-launcher]]) - the metapackage owns one command and delegates all
3
+ // product behavior to the independently compiled CLI package.
4
+ import '@spexcode/spec-cli/bin/spex.mjs'
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ // @@@ spex launcher ([[release-launcher]]) - package installs execute the package's compiled CLI directly;
3
+ // tsx remains a development tool and never enters an adopter's runtime closure.
4
+ import { spawn, spawnSync } from 'node:child_process'
5
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'
6
+ import { fileURLToPath } from 'node:url'
7
+ import { dirname, join } from 'node:path'
8
+
9
+ // Resolve from THIS package rather than cwd, so global and project-local installs run one compiled CLI.
10
+ const pkg = join(dirname(fileURLToPath(import.meta.url)), '..') // spec-cli/
11
+ const cli = join(pkg, 'dist', 'cli.js')
12
+ const workspace = join(pkg, '..')
13
+
14
+ // @@@ mid-merge guard ([[merge-tooling-resilience]]) - a released package contains no source to scan;
15
+ // a source workspace does. Refuse to run its possibly stale dist while its imported source trees still
16
+ // carry unresolved conflict markers, so hooks keep the retryable exit-75 contract during a merge.
17
+ const sourceRoot = join(pkg, 'src')
18
+ if (existsSync(sourceRoot)) {
19
+ const srcRoots = [sourceRoot, join(pkg, '..', 'packages', 'spec-core', 'src'), join(pkg, '..', 'spec-eval', 'src'), join(pkg, '..', 'spec-forge', 'src')]
20
+ const conflicted = srcRoots.flatMap((root) => {
21
+ if (!existsSync(root)) return []
22
+ return readdirSync(root, { recursive: true })
23
+ .filter((f) => /\.(ts|tsx|js|mjs)$/.test(String(f)))
24
+ .map((f) => join(root, String(f)))
25
+ .filter((path) => {
26
+ try { return /^<{7} /m.test(readFileSync(path, 'utf8')) } catch { return false }
27
+ })
28
+ })
29
+ if (conflicted.length) {
30
+ console.error('spex: paused mid-merge - unresolved conflict markers in the source SpexCode runs:')
31
+ for (const file of conflicted) console.error(` ${file}`)
32
+ console.error('resolve the merge, rebuild SpexCode, then retry. (exit 75)')
33
+ process.exit(75)
34
+ }
35
+
36
+ // @@@ source-workspace build ([[release-launcher]]) - the git hooks invoke this launcher straight from a
37
+ // checkout, where dist is intentionally untracked. Rebuild the complete runtime closure before linting
38
+ // candidate source; an installed package has no src tree and stays a pure Node -> dist execution path.
39
+ const runtimeEntries = [
40
+ cli,
41
+ join(workspace, 'packages', 'spec-core', 'dist', 'index.js'),
42
+ join(workspace, 'spec-eval', 'dist', 'index.js'),
43
+ join(workspace, 'spec-forge', 'dist', 'index.js'),
44
+ ]
45
+ const newestSource = srcRoots.reduce((newest, root) => {
46
+ if (!existsSync(root)) return newest
47
+ for (const entry of readdirSync(root, { recursive: true })) {
48
+ const path = join(root, String(entry))
49
+ try {
50
+ if (/\.(ts|tsx|js|mjs)$/.test(path)) newest = Math.max(newest, statSync(path).mtimeMs)
51
+ } catch { /* a concurrent source edit can only make the next invocation rebuild again */ }
52
+ }
53
+ return newest
54
+ }, 0)
55
+ const rebuild = runtimeEntries.some((entry) => {
56
+ try { return statSync(entry).mtimeMs < newestSource } catch { return true }
57
+ })
58
+ if (rebuild) {
59
+ const build = spawnSync('npm', ['run', 'build'], { cwd: workspace, stdio: 'inherit' })
60
+ if (build.error || build.status !== 0 || !existsSync(cli)) {
61
+ console.error('spex: source workspace build failed; fix it, then retry.')
62
+ process.exit(build.status ?? 1)
63
+ }
64
+ }
65
+ }
66
+ const args = process.argv.slice(2)
67
+ const env = { ...process.env }
68
+ // A backend/dashboard is a project or host control plane, never the managed session that happened to start it.
69
+ if (args[0] === 'serve' || args[0] === 'dashboard') {
70
+ const identityKeys = (env.SPEXCODE_SESSION_IDENTITY_VARS
71
+ || 'SPEXCODE_SESSION_ID,CLAUDE_CODE_SESSION_ID,CODEX_THREAD_ID,OPENCODE_SESSION_ID,PI_SESSION_ID')
72
+ .split(',').map((key) => key.trim()).filter(Boolean)
73
+ for (const key of identityKeys) delete env[key]
74
+ }
75
+ spawn(process.execPath, [cli, ...args], { stdio: 'inherit', env })
76
+ .on('exit', (code) => process.exit(code ?? 0))
@@ -0,0 +1,2 @@
1
+ export declare function assertLocalBackend(): Promise<void>;
2
+ export declare function attachSession(id: string): Promise<number>;
@@ -0,0 +1,48 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { networkInterfaces } from 'node:os';
3
+ import { alive, apiBase, TMUX_SOCK } from './sessions.js';
4
+ const AGENT_ALTERNATIVES = 'read the pane with `spex session show <SEL> --capture`, drive it with `session send` (plain text first; `--keys` only as a last resort)';
5
+ // attach only makes sense on the machine that runs the tmux server — the backend's. The board the selector
6
+ // resolved against IS that backend, so the test is: does the RESOLVED backend (see [[remote-client]]'s
7
+ // ladder — flag / worker env / cwd record / fallback) point at this machine? Loopback and any address this
8
+ // host owns count as local; anything else (a tailnet/LAN IP of another box, a hostname we can't claim)
9
+ // fails loud with the reason and the remote-capable alternatives, never a silent local fallback onto a
10
+ // tmux socket that holds no sessions.
11
+ export async function assertLocalBackend() {
12
+ const base = await apiBase();
13
+ let host;
14
+ try {
15
+ host = new URL(base).hostname;
16
+ }
17
+ catch {
18
+ host = '';
19
+ }
20
+ const mine = new Set(['localhost', '127.0.0.1', '::1', '[::1]']);
21
+ for (const addrs of Object.values(networkInterfaces()))
22
+ for (const a of addrs ?? [])
23
+ mine.add(a.address);
24
+ if (mine.has(host))
25
+ return;
26
+ console.error(`spex session attach: attach is LOCAL-only, and the resolved backend is another machine (${base}).
27
+ The tmux session lives on THAT machine — a terminal can't be attached over HTTP. Either run attach there
28
+ (e.g. over ssh), or ${AGENT_ALTERNATIVES} — those work remotely.`);
29
+ process.exit(2);
30
+ }
31
+ // foreground takeover of the session's real tmux window; returns only via detach (C-b d) or the session
32
+ // ending. Interactive and blocking by design — a caller without a terminal (an agent inside its turn, a
33
+ // pipe) is refused up front and pointed at the remote-capable verbs instead of tmux's bare "not a terminal".
34
+ export async function attachSession(id) {
35
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
36
+ console.error(`spex session attach: attach is INTERACTIVE and needs a terminal — it blocks until you detach.
37
+ An agent must not run it inside a turn (it freezes you); ${AGENT_ALTERNATIVES}.`);
38
+ process.exit(2);
39
+ }
40
+ if (!(await alive(id))) {
41
+ console.error(`spex session attach: ${id} is offline — no live tmux session to attach.
42
+ Bring it back with \`spex session resume ${id}\`, or read its record with \`spex session show ${id}\`.`);
43
+ return 1;
44
+ }
45
+ console.log(`attaching to ${id} — detach with C-b d (the session keeps running)`);
46
+ const r = spawnSync('tmux', ['-u', '-L', TMUX_SOCK, 'attach-session', '-t', id], { stdio: 'inherit' });
47
+ return r.status ?? 1;
48
+ }
@@ -0,0 +1,33 @@
1
+ import type { DispatchResult, HarnessDeliveryRecord } from './harness.js';
2
+ type ClaudeHeadlessDeliveryRecord = HarnessDeliveryRecord & {
3
+ status?: string;
4
+ };
5
+ export declare const claudeHeadlessSock: (id: string) => string;
6
+ export declare function claudeHeadlessLaunchCommand(id: string, runtimeDir: string, claudeCmd: string): string;
7
+ export declare const deliverViaClaudeHeadless: (rec: ClaudeHeadlessDeliveryRecord, text: string) => Promise<DispatchResult>;
8
+ export declare const interruptClaudeHeadless: (rec: HarnessDeliveryRecord) => Promise<DispatchResult>;
9
+ export declare class ClaudeHeadlessController {
10
+ private readonly id;
11
+ private readonly claudeCmd;
12
+ private readonly cwd;
13
+ private server;
14
+ private child;
15
+ private controlQueue;
16
+ private closing;
17
+ private readonly socketPath;
18
+ constructor(id: string, _runtimeDir: string, claudeCmd: string, cwd?: string);
19
+ start(initialPrompt?: string): Promise<void>;
20
+ close(): Promise<void>;
21
+ private accept;
22
+ private handle;
23
+ private interrupt;
24
+ private spawnTurn;
25
+ private observeEvent;
26
+ private ensureTurnExit;
27
+ private terminateTurn;
28
+ private waitForTurnExit;
29
+ private signalTurn;
30
+ private writeLine;
31
+ }
32
+ export declare function runClaudeHeadlessController(id: string, runtimeDir: string, claudeCmd: string, tail: string[]): Promise<void>;
33
+ export {};
@@ -0,0 +1,307 @@
1
+ import { rmSync } from 'node:fs';
2
+ import { createServer } from 'node:net';
3
+ import { spawn } from 'node:child_process';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { tmpdir } from 'node:os';
6
+ import { join } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { controlRequest, withTimeout } from './headless-controller.js';
9
+ import { shQuote } from './sh.js';
10
+ const PKG = fileURLToPath(new URL('..', import.meta.url));
11
+ const SPEX = join(PKG, 'bin', 'spex.mjs');
12
+ const CONTROL_TIMEOUT_MS = 60_000;
13
+ const START_TIMEOUT_MS = 30_000;
14
+ const INTERRUPT_TIMEOUT_MS = 10_000;
15
+ const RESULT_WAIT_MS = 20_000;
16
+ const RESULT_EXIT_GRACE_MS = 500;
17
+ const TERM_EXIT_GRACE_MS = 500;
18
+ const KILL_EXIT_GRACE_MS = 2_000;
19
+ const userEvent = (text) => JSON.stringify({
20
+ type: 'user',
21
+ message: { role: 'user', content: [{ type: 'text', text }] },
22
+ });
23
+ export const claudeHeadlessSock = (id) => join(tmpdir(), `spexcode-ch-${id}.sock`);
24
+ export function claudeHeadlessLaunchCommand(id, runtimeDir, claudeCmd) {
25
+ return [shQuote(SPEX), 'internal', 'claude-headless-run', shQuote(id), shQuote(runtimeDir), shQuote(claudeCmd), '--'].join(' ');
26
+ }
27
+ export const deliverViaClaudeHeadless = (rec, text) => controlRequest(claudeHeadlessSock(rec.session), { type: 'deliver', text, mode: rec.status === 'active' ? 'steer' : 'wake' }, {
28
+ name: 'claude-headless', session: rec.session, timeoutMs: CONTROL_TIMEOUT_MS,
29
+ rejected: 'claude-headless control rejected the request',
30
+ });
31
+ export const interruptClaudeHeadless = (rec) => controlRequest(claudeHeadlessSock(rec.session), { type: 'interrupt' }, {
32
+ name: 'claude-headless', session: rec.session, timeoutMs: CONTROL_TIMEOUT_MS,
33
+ rejected: 'claude-headless control rejected the request',
34
+ });
35
+ export class ClaudeHeadlessController {
36
+ id;
37
+ claudeCmd;
38
+ cwd;
39
+ server = null;
40
+ child = null;
41
+ controlQueue = Promise.resolve();
42
+ closing = false;
43
+ socketPath;
44
+ constructor(id, _runtimeDir, claudeCmd, cwd = process.cwd()) {
45
+ this.id = id;
46
+ this.claudeCmd = claudeCmd;
47
+ this.cwd = cwd;
48
+ this.socketPath = claudeHeadlessSock(id);
49
+ }
50
+ async start(initialPrompt) {
51
+ try {
52
+ rmSync(this.socketPath, { force: true });
53
+ }
54
+ catch { /* stale control socket is replaced at startup */ }
55
+ this.server = createServer((socket) => this.accept(socket));
56
+ await new Promise((resolve, reject) => {
57
+ const onError = (error) => { this.server?.off('listening', onListening); reject(error); };
58
+ const onListening = () => { this.server?.off('error', onError); resolve(); };
59
+ this.server.once('error', onError);
60
+ this.server.once('listening', onListening);
61
+ this.server.listen(this.socketPath);
62
+ });
63
+ if (initialPrompt)
64
+ void this.spawnTurn(initialPrompt, false).catch((error) => {
65
+ console.error(`[spex claude-headless] initial turn failed: ${error.message}`);
66
+ });
67
+ }
68
+ async close() {
69
+ if (this.closing)
70
+ return;
71
+ this.closing = true;
72
+ const child = this.child;
73
+ try {
74
+ if (child)
75
+ await this.ensureTurnExit(child);
76
+ }
77
+ finally {
78
+ await new Promise((resolve) => {
79
+ if (!this.server)
80
+ return resolve();
81
+ this.server.close(() => resolve());
82
+ });
83
+ try {
84
+ rmSync(this.socketPath, { force: true });
85
+ }
86
+ catch { /* best-effort cleanup after close */ }
87
+ }
88
+ }
89
+ accept(socket) {
90
+ socket.setEncoding('utf8');
91
+ let buffer = '';
92
+ let handled = false;
93
+ socket.on('data', (chunk) => {
94
+ if (handled)
95
+ return;
96
+ buffer += chunk;
97
+ const nl = buffer.indexOf('\n');
98
+ if (nl < 0)
99
+ return;
100
+ handled = true;
101
+ let request;
102
+ try {
103
+ request = JSON.parse(buffer.slice(0, nl));
104
+ }
105
+ catch (error) {
106
+ socket.end(`${JSON.stringify({ ok: false, error: `invalid control request: ${error.message}` })}\n`);
107
+ return;
108
+ }
109
+ this.controlQueue = this.controlQueue.then(async () => {
110
+ const result = await this.handle(request).catch((error) => ({ ok: false, error: error.message }));
111
+ socket.end(`${JSON.stringify(result)}\n`);
112
+ });
113
+ });
114
+ }
115
+ async handle(request) {
116
+ if (request.type === 'deliver') {
117
+ if (!request.text)
118
+ return { ok: false, error: 'empty prompt - nothing to deliver' };
119
+ const current = this.child;
120
+ if (request.mode === 'steer' && current?.active && current.process.stdin.writable) {
121
+ await this.writeLine(current, userEvent(request.text));
122
+ return { ok: true };
123
+ }
124
+ if (current?.active) {
125
+ await Promise.race([
126
+ withTimeout(current.result, RESULT_WAIT_MS, 'previous claude-headless turn did not reach its result before idle wake'),
127
+ current.exited.then((code) => { throw new Error(`previous claude-headless turn exited before its result (code ${code ?? 'signal'})`); }),
128
+ ]);
129
+ }
130
+ if (current)
131
+ await this.ensureTurnExit(current);
132
+ await this.spawnTurn(request.text, true);
133
+ return { ok: true };
134
+ }
135
+ if (request.type === 'interrupt')
136
+ return this.interrupt();
137
+ return { ok: false, error: 'unknown claude-headless control request' };
138
+ }
139
+ async interrupt() {
140
+ const child = this.child;
141
+ if (!child?.active || !child.process.stdin.writable)
142
+ return { ok: true };
143
+ const requestId = randomUUID();
144
+ const ack = new Promise((resolve) => child.interruptAcks.set(requestId, resolve));
145
+ await this.writeLine(child, JSON.stringify({
146
+ type: 'control_request',
147
+ request_id: requestId,
148
+ request: { subtype: 'interrupt' },
149
+ }));
150
+ try {
151
+ await withTimeout(ack, INTERRUPT_TIMEOUT_MS, `claude-headless interrupt was not confirmed for session ${this.id}`);
152
+ return { ok: true };
153
+ }
154
+ finally {
155
+ child.interruptAcks.delete(requestId);
156
+ }
157
+ }
158
+ async spawnTurn(text, resume) {
159
+ if (this.closing)
160
+ throw new Error('claude-headless controller is closing');
161
+ const mode = resume ? ['--resume', this.id] : ['--session-id', this.id];
162
+ const args = ['-p', ...mode, '--input-format', 'stream-json', '--output-format', 'stream-json', '--verbose'];
163
+ const command = `exec ${this.claudeCmd} ${args.map(shQuote).join(' ')}`;
164
+ const childProcess = spawn('/bin/sh', ['-lc', command], {
165
+ cwd: this.cwd,
166
+ env: process.env,
167
+ detached: true,
168
+ stdio: ['pipe', 'pipe', 'pipe'],
169
+ });
170
+ let sawFirstEvent;
171
+ const firstEvent = new Promise((resolve) => { sawFirstEvent = resolve; });
172
+ let resolveExit;
173
+ const exited = new Promise((resolve) => { resolveExit = resolve; });
174
+ let sawResult;
175
+ const result = new Promise((resolve) => { sawResult = resolve; });
176
+ const turn = {
177
+ process: childProcess,
178
+ active: true,
179
+ completed: false,
180
+ exited,
181
+ teardown: null,
182
+ result,
183
+ sawResult,
184
+ firstEvent,
185
+ sawFirstEvent,
186
+ interruptAcks: new Map(),
187
+ };
188
+ this.child = turn;
189
+ let stdoutBuffer = '';
190
+ childProcess.stdout.setEncoding('utf8');
191
+ childProcess.stderr.pipe(process.stderr);
192
+ childProcess.stdout.on('data', (chunk) => {
193
+ stdoutBuffer += chunk;
194
+ for (;;) {
195
+ const nl = stdoutBuffer.indexOf('\n');
196
+ if (nl < 0)
197
+ break;
198
+ const line = stdoutBuffer.slice(0, nl);
199
+ stdoutBuffer = stdoutBuffer.slice(nl + 1);
200
+ const nativeLine = `${line}\n`;
201
+ globalThis.process.stdout.write(nativeLine);
202
+ turn.sawFirstEvent();
203
+ this.observeEvent(turn, line);
204
+ }
205
+ });
206
+ childProcess.once('error', (error) => {
207
+ console.error(`[spex claude-headless] child spawn failed: ${error.message}`);
208
+ });
209
+ childProcess.once('close', (code) => {
210
+ turn.active = false;
211
+ if (stdoutBuffer)
212
+ console.error('[spex claude-headless] dropped a partial non-line stdout event');
213
+ if (this.child === turn)
214
+ this.child = null;
215
+ resolveExit(code);
216
+ if (!turn.completed && code !== 0 && !this.closing) {
217
+ void import('./harness.js').then(({ reportHeadlessTurnExit }) => reportHeadlessTurnExit(this.id, 'claude-headless', code, this.cwd));
218
+ }
219
+ });
220
+ await this.writeLine(turn, userEvent(text));
221
+ await Promise.race([
222
+ withTimeout(turn.firstEvent, START_TIMEOUT_MS, `claude-headless child produced no stream event for session ${this.id}`),
223
+ turn.exited.then((code) => { throw new Error(`claude-headless child exited before accepting the turn (code ${code ?? 'signal'})`); }),
224
+ ]);
225
+ }
226
+ observeEvent(turn, line) {
227
+ let event;
228
+ try {
229
+ event = JSON.parse(line);
230
+ }
231
+ catch {
232
+ return;
233
+ }
234
+ if (event?.type === 'control_response' && typeof event?.response?.request_id === 'string') {
235
+ turn.interruptAcks.get(event.response.request_id)?.();
236
+ }
237
+ if (event?.type === 'result' && !turn.completed) {
238
+ turn.completed = true;
239
+ turn.active = false;
240
+ turn.sawResult();
241
+ void this.ensureTurnExit(turn).catch((error) => {
242
+ console.error(`[spex claude-headless] completed turn teardown failed: ${error.message}`);
243
+ });
244
+ }
245
+ }
246
+ ensureTurnExit(turn) {
247
+ turn.teardown ??= this.terminateTurn(turn);
248
+ return turn.teardown;
249
+ }
250
+ async terminateTurn(turn) {
251
+ if (turn.completed) {
252
+ if (turn.process.stdin.writable)
253
+ turn.process.stdin.end();
254
+ if (await this.waitForTurnExit(turn, RESULT_EXIT_GRACE_MS))
255
+ return;
256
+ this.signalTurn(turn, 'SIGKILL');
257
+ await withTimeout(turn.exited, KILL_EXIT_GRACE_MS, `claude-headless completed turn process group ${turn.process.pid ?? 'unknown'} did not exit after SIGKILL`);
258
+ return;
259
+ }
260
+ this.signalTurn(turn, 'SIGTERM');
261
+ if (await this.waitForTurnExit(turn, TERM_EXIT_GRACE_MS))
262
+ return;
263
+ this.signalTurn(turn, 'SIGKILL');
264
+ await withTimeout(turn.exited, KILL_EXIT_GRACE_MS, `claude-headless turn process group ${turn.process.pid ?? 'unknown'} did not exit after SIGKILL`);
265
+ }
266
+ async waitForTurnExit(turn, timeoutMs) {
267
+ try {
268
+ await withTimeout(turn.exited, timeoutMs, 'turn exit grace elapsed');
269
+ return true;
270
+ }
271
+ catch {
272
+ return false;
273
+ }
274
+ }
275
+ signalTurn(turn, signal) {
276
+ const pid = turn.process.pid;
277
+ try {
278
+ if (pid)
279
+ process.kill(-pid, signal);
280
+ else
281
+ turn.process.kill(signal);
282
+ }
283
+ catch (error) {
284
+ if (error.code !== 'ESRCH')
285
+ throw error;
286
+ }
287
+ }
288
+ writeLine(turn, line) {
289
+ return new Promise((resolve, reject) => {
290
+ if (!turn.process.stdin.writable)
291
+ return reject(new Error('claude-headless child stdin is not writable'));
292
+ turn.process.stdin.write(`${line}\n`, (error) => error ? reject(error) : resolve());
293
+ });
294
+ }
295
+ }
296
+ export async function runClaudeHeadlessController(id, runtimeDir, claudeCmd, tail) {
297
+ const controller = new ClaudeHeadlessController(id, runtimeDir, claudeCmd);
298
+ const resume = tail[0] === '--resume';
299
+ const prompt = resume ? undefined : tail[0] === '--session-id' ? tail.slice(2).join(' ') : tail.join(' ');
300
+ await controller.start(prompt);
301
+ await new Promise((resolve) => {
302
+ const stop = () => void controller.close().finally(resolve);
303
+ process.once('SIGINT', stop);
304
+ process.once('SIGTERM', stop);
305
+ process.once('SIGHUP', stop);
306
+ });
307
+ }
@@ -0,0 +1 @@
1
+ export {};