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
@@ -0,0 +1,144 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ let ctx = null;
3
+ function gitlabCtx() {
4
+ if (ctx)
5
+ return ctx;
6
+ const remote = execFileSync('git', ['remote', 'get-url', 'origin'], { encoding: 'utf8' }).trim();
7
+ const parsed = parseRemote(remote);
8
+ if (!parsed)
9
+ throw new Error(`gitlab: cannot parse origin remote '${remote}' as a GitLab URL`);
10
+ const token = process.env.GITLAB_TOKEN || credentialToken(parsed.host);
11
+ if (!token) {
12
+ throw new Error(`gitlab: no token for ${parsed.host} — set GITLAB_TOKEN, or store a PAT in git's credential store:\n` +
13
+ ` printf "protocol=https\\nhost=${parsed.host}\\nusername=<user>\\npassword=<token>\\n\\n" | git credential approve`);
14
+ }
15
+ ctx = { ...parsed, token };
16
+ return ctx;
17
+ }
18
+ export function parseRemote(remote) {
19
+ let m = remote.match(/^(https?:\/\/[^/]+)\/(.+?)(?:\.git)?\/?$/);
20
+ if (m)
21
+ return { base: m[1], host: m[1].replace(/^https?:\/\//, ''), project: m[2] };
22
+ m = remote.match(/^(?:ssh:\/\/)?[\w.-]+@([\w.-]+)(?::\d+)?[:/](.+?)(?:\.git)?\/?$/);
23
+ if (m)
24
+ return { base: `https://${m[1]}`, host: m[1], project: m[2] };
25
+ return null;
26
+ }
27
+ function credentialToken(host) {
28
+ try {
29
+ const out = execFileSync('git', ['credential', 'fill'], {
30
+ input: `protocol=https\nhost=${host}\n\n`,
31
+ encoding: 'utf8',
32
+ env: { ...process.env, GIT_TERMINAL_PROMPT: '0', GIT_ASKPASS: 'true' },
33
+ stdio: ['pipe', 'pipe', 'ignore'],
34
+ });
35
+ return out.match(/^password=(.+)$/m)?.[1] ?? '';
36
+ }
37
+ catch {
38
+ return '';
39
+ }
40
+ }
41
+ async function api(path, init) {
42
+ const { base, project, token } = gitlabCtx();
43
+ const sep = path.includes('?') ? '&' : '?';
44
+ const url = `${base}/api/v4/projects/${encodeURIComponent(project)}/${path}${init?.method ? '' : `${sep}per_page=100`}`;
45
+ const res = await fetch(url, {
46
+ ...init,
47
+ headers: { 'PRIVATE-TOKEN': token, 'content-type': 'application/json', ...init?.headers },
48
+ });
49
+ if (!res.ok)
50
+ throw new Error(`gitlab: ${init?.method ?? 'GET'} ${path} → ${res.status} ${(await res.text()).slice(0, 300)}`);
51
+ return (await res.json());
52
+ }
53
+ // GitLab's API has no bounded list query; stop at a short page and cap the walk.
54
+ async function paged(path) {
55
+ const sep = path.includes('?') ? '&' : '?';
56
+ const out = [];
57
+ for (let page = 1; page <= 20; page++) {
58
+ const rows = await api(`${path}${sep}page=${page}`);
59
+ out.push(...rows);
60
+ if (rows.length < 100)
61
+ break;
62
+ }
63
+ return out;
64
+ }
65
+ async function toIssue(r) {
66
+ return {
67
+ number: r.iid,
68
+ title: r.title,
69
+ body: r.description ?? '',
70
+ url: r.web_url,
71
+ state: normalizeState(r.state),
72
+ labels: forgeLabels(r.labels),
73
+ author: r.author?.username ?? '',
74
+ createdAt: r.created_at ?? '',
75
+ comments: r.user_notes_count > 0 ? await listNotes(r.iid) : [],
76
+ };
77
+ }
78
+ function forgeLabels(labels) {
79
+ return (labels ?? []).flatMap((label) => {
80
+ const name = typeof label === 'string' ? label : label.name ?? '';
81
+ if (!name)
82
+ return [];
83
+ if (typeof label === 'string')
84
+ return [{ name }];
85
+ return [{ name, ...(label.color ? { color: label.color } : {}), ...(label.text_color ? { textColor: label.text_color } : {}) }];
86
+ });
87
+ }
88
+ function normalizeState(state) {
89
+ const s = (state || '').toLowerCase();
90
+ return s === 'opened' ? 'open' : s;
91
+ }
92
+ async function listNotes(iid) {
93
+ const rows = await paged(`issues/${iid}/notes`);
94
+ return rows
95
+ .filter((n) => !n.system)
96
+ .map((n) => ({ author: n.author?.username ?? '', createdAt: n.created_at ?? '', body: n.body ?? '' }));
97
+ }
98
+ export const gitlabDriver = {
99
+ host: 'gitlab',
100
+ async listIssues() {
101
+ const rows = await paged('issues?state=all&with_labels_details=true');
102
+ return Promise.all(rows.map(toIssue));
103
+ },
104
+ async listIssuesSince(sinceISO) {
105
+ const rows = await paged(`issues?state=all&with_labels_details=true&updated_after=${encodeURIComponent(sinceISO)}`);
106
+ return Promise.all(rows.map(toIssue));
107
+ },
108
+ async listPRs() {
109
+ const rows = await paged('merge_requests?state=opened');
110
+ return Promise.all(rows.map(async (r) => ({
111
+ number: r.iid,
112
+ title: r.title,
113
+ url: r.web_url,
114
+ state: normalizeState(r.state),
115
+ headRefName: r.source_branch,
116
+ closesIssues: (await paged(`merge_requests/${r.iid}/closes_issues`)).map((i) => i.iid),
117
+ })));
118
+ },
119
+ async createIssue({ title, body }) {
120
+ const r = await api('issues', {
121
+ method: 'POST',
122
+ body: JSON.stringify({ title, description: body }),
123
+ });
124
+ if (!r.web_url?.startsWith('http') || !Number.isFinite(r.iid))
125
+ throw new Error(`gitlab: issue create returned an unexpected result: ${JSON.stringify(r)}`);
126
+ return { number: r.iid, url: r.web_url };
127
+ },
128
+ async createComment({ number, body }) {
129
+ const { base, project } = gitlabCtx();
130
+ const r = await api(`issues/${number}/notes`, { method: 'POST', body: JSON.stringify({ body }) });
131
+ if (!Number.isFinite(r.id))
132
+ throw new Error(`gitlab: note create returned an unexpected result: ${JSON.stringify(r)}`);
133
+ return { url: `${base}/${project}/-/issues/${number}#note_${r.id}` };
134
+ },
135
+ async closeIssue({ number }) {
136
+ const r = await api(`issues/${number}`, {
137
+ method: 'PUT',
138
+ body: JSON.stringify({ state_event: 'close' }),
139
+ });
140
+ if (!r.web_url?.startsWith('http'))
141
+ throw new Error(`gitlab: issue close returned an unexpected result: ${JSON.stringify(r)}`);
142
+ return { url: r.web_url };
143
+ },
144
+ };
@@ -0,0 +1,10 @@
1
+ import type { ForgeDriver } from './port.js';
2
+ export declare const FORGE_DRIVERS: ForgeDriver[];
3
+ export declare const DEFAULT_FORGE_HOST = "github";
4
+ export declare function forgeDriverFor(host: string): ForgeDriver | undefined;
5
+ export declare function forgeIssueStores(): {
6
+ id: string;
7
+ label: string;
8
+ kind: 'forge';
9
+ }[];
10
+ export declare function resolveForgeHost(): string;
@@ -0,0 +1,83 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { githubDriver } from './drivers/github.js';
5
+ import { gitlabDriver } from './drivers/gitlab.js';
6
+ export const FORGE_DRIVERS = [githubDriver, gitlabDriver];
7
+ export const DEFAULT_FORGE_HOST = 'github';
8
+ export function forgeDriverFor(host) {
9
+ return FORGE_DRIVERS.find((d) => d.host === host);
10
+ }
11
+ export function forgeIssueStores() {
12
+ const driver = forgeDriverFor(resolveForgeHost());
13
+ return driver ? [{ id: driver.host, label: driver.host, kind: 'forge' }] : [];
14
+ }
15
+ function gitEnv() {
16
+ const env = { ...process.env };
17
+ delete env.GIT_DIR;
18
+ delete env.GIT_WORK_TREE;
19
+ delete env.GIT_INDEX_FILE;
20
+ delete env.GIT_OBJECT_DIRECTORY;
21
+ return env;
22
+ }
23
+ function gitOut(args) {
24
+ try {
25
+ return execFileSync('git', args, { env: gitEnv(), encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || null;
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ function configuredHost() {
32
+ const root = gitOut(['rev-parse', '--show-toplevel']);
33
+ if (!root)
34
+ return null;
35
+ for (const name of ['spexcode.local.json', 'spexcode.json']) {
36
+ const p = join(root, name);
37
+ if (!existsSync(p))
38
+ continue;
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(readFileSync(p, 'utf8'));
42
+ }
43
+ catch (e) {
44
+ throw new Error(`${p} is not valid JSON: ${e.message}`);
45
+ }
46
+ const host = parsed?.forge?.host;
47
+ if (typeof host === 'string' && host.trim())
48
+ return host.trim();
49
+ }
50
+ return null;
51
+ }
52
+ function remoteHostname(url) {
53
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(url)) {
54
+ try {
55
+ return new URL(url).hostname || null;
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ const scp = /^(?:[^@\s/]+@)?([^:/\s]+):./.exec(url);
62
+ return scp ? scp[1] : null;
63
+ }
64
+ function hostFor(hostname) {
65
+ const h = hostname.toLowerCase();
66
+ if (h.includes('github'))
67
+ return 'github';
68
+ if (h.includes('bitbucket'))
69
+ return 'bitbucket';
70
+ return 'gitlab';
71
+ }
72
+ let cached = null;
73
+ const RESOLVE_TTL_MS = 30_000;
74
+ export function resolveForgeHost() {
75
+ const now = Date.now();
76
+ if (cached && now - cached.at < RESOLVE_TTL_MS)
77
+ return cached.host;
78
+ const url = gitOut(['remote', 'get-url', 'origin']);
79
+ const hostname = url ? remoteHostname(url) : null;
80
+ const host = configuredHost() ?? (hostname ? hostFor(hostname) : DEFAULT_FORGE_HOST);
81
+ cached = { host, at: now };
82
+ return host;
83
+ }
@@ -0,0 +1,4 @@
1
+ export * from './port.js';
2
+ export * from './links.js';
3
+ export * from './drivers.js';
4
+ export * from './resident.js';
@@ -0,0 +1,4 @@
1
+ export * from './port.js';
2
+ export * from './links.js';
3
+ export * from './drivers.js';
4
+ export * from './resident.js';
@@ -0,0 +1,15 @@
1
+ import type { ForgeIssue, ForgePR } from './port.js';
2
+ export type LinkedIssue = ForgeIssue & {
3
+ via: 'marker' | 'pr';
4
+ };
5
+ export type LinkedPR = ForgePR & {
6
+ via: 'branch';
7
+ };
8
+ export type NodeLinks = {
9
+ node: string;
10
+ issues: LinkedIssue[];
11
+ prs: LinkedPR[];
12
+ };
13
+ export declare function parseSpecMarkers(body: string): string[];
14
+ export declare function branchToNode(branch: string, nodeIds: string[]): string | null;
15
+ export declare function resolveLinks(issues: ForgeIssue[], prs: ForgePR[], nodeIds: string[]): NodeLinks[];
@@ -0,0 +1,65 @@
1
+ export function parseSpecMarkers(body) {
2
+ const ids = [];
3
+ for (const m of (body || '').matchAll(/^\s*spec:\s*(.+)$/gim)) {
4
+ for (const part of m[1].split(',')) {
5
+ const id = part.trim();
6
+ if (id)
7
+ ids.push(id);
8
+ }
9
+ }
10
+ return ids;
11
+ }
12
+ export function branchToNode(branch, nodeIds) {
13
+ if (!branch?.startsWith('node/'))
14
+ return null;
15
+ const rest = branch.slice('node/'.length);
16
+ let best = null;
17
+ for (const id of nodeIds) {
18
+ if (rest === id || rest.startsWith(id + '-')) {
19
+ if (!best || id.length > best.length)
20
+ best = id;
21
+ }
22
+ }
23
+ return best;
24
+ }
25
+ export function resolveLinks(issues, prs, nodeIds) {
26
+ const known = new Set(nodeIds);
27
+ const byNode = new Map();
28
+ const slot = (node) => {
29
+ let s = byNode.get(node);
30
+ if (!s) {
31
+ s = { issues: new Map(), prs: new Map() };
32
+ byNode.set(node, s);
33
+ }
34
+ return s;
35
+ };
36
+ const prNode = new Map();
37
+ for (const pr of prs) {
38
+ const node = branchToNode(pr.headRefName, nodeIds);
39
+ if (!node)
40
+ continue;
41
+ prNode.set(pr.number, node);
42
+ slot(node).prs.set(pr.number, { ...pr, via: 'branch' });
43
+ }
44
+ const issueByNumber = new Map(issues.map((i) => [i.number, i]));
45
+ for (const issue of issues) {
46
+ for (const id of parseSpecMarkers(issue.body)) {
47
+ if (known.has(id))
48
+ slot(id).issues.set(issue.number, { ...issue, via: 'marker' });
49
+ }
50
+ }
51
+ for (const pr of prs) {
52
+ const node = prNode.get(pr.number);
53
+ if (!node)
54
+ continue;
55
+ for (const num of pr.closesIssues) {
56
+ const issue = issueByNumber.get(num);
57
+ if (issue && !slot(node).issues.has(num)) {
58
+ slot(node).issues.set(num, { ...issue, via: 'pr' });
59
+ }
60
+ }
61
+ }
62
+ return [...byNode.entries()]
63
+ .map(([node, s]) => ({ node, issues: [...s.issues.values()], prs: [...s.prs.values()] }))
64
+ .sort((a, b) => a.node.localeCompare(b.node));
65
+ }
@@ -0,0 +1,10 @@
1
+ import type { ForgeIssue, ForgePR } from './port.js';
2
+ import { type LinkedIssue } from './links.js';
3
+ export declare const NEEDS_EVAL = "needs-eval";
4
+ export declare function isNeedsEval(issue: ForgeIssue): boolean;
5
+ export type EvalPending = LinkedIssue;
6
+ export type NodeEvalPending = {
7
+ node: string;
8
+ pending: EvalPending[];
9
+ };
10
+ export declare function resolveEvalPending(issues: ForgeIssue[], prs: ForgePR[], nodeIds: string[]): NodeEvalPending[];
@@ -0,0 +1,20 @@
1
+ import { resolveLinks } from './links.js';
2
+ export const NEEDS_EVAL = 'needs-eval';
3
+ const BODY_MARKER = new RegExp(`^\\s*${NEEDS_EVAL}\\s*:?\\s*$`, 'im');
4
+ export function isNeedsEval(issue) {
5
+ if (issue.labels.some((l) => l.name.trim().toLowerCase() === NEEDS_EVAL))
6
+ return true;
7
+ return BODY_MARKER.test(issue.body || '');
8
+ }
9
+ export function resolveEvalPending(issues, prs, nodeIds) {
10
+ const flagged = new Set(issues.filter(isNeedsEval).map((i) => i.number));
11
+ if (!flagged.size)
12
+ return [];
13
+ const out = [];
14
+ for (const { node, issues: linked } of resolveLinks(issues, prs, nodeIds)) {
15
+ const pending = linked.filter((i) => i.state === 'open' && flagged.has(i.number));
16
+ if (pending.length)
17
+ out.push({ node, pending });
18
+ }
19
+ return out;
20
+ }
@@ -0,0 +1,53 @@
1
+ export type ForgeComment = {
2
+ author: string;
3
+ createdAt: string;
4
+ body: string;
5
+ };
6
+ export type ForgeLabel = {
7
+ name: string;
8
+ color?: string;
9
+ textColor?: string;
10
+ };
11
+ export type ForgeIssue = {
12
+ number: number;
13
+ title: string;
14
+ body: string;
15
+ url: string;
16
+ state: string;
17
+ labels: ForgeLabel[];
18
+ author: string;
19
+ createdAt: string;
20
+ comments: ForgeComment[];
21
+ };
22
+ export type ForgePR = {
23
+ number: number;
24
+ title: string;
25
+ url: string;
26
+ state: string;
27
+ headRefName: string;
28
+ closesIssues: number[];
29
+ };
30
+ export interface ForgeDriver {
31
+ readonly host: string;
32
+ listIssues(): Promise<ForgeIssue[]>;
33
+ listPRs(): Promise<ForgePR[]>;
34
+ createIssue(input: {
35
+ title: string;
36
+ body: string;
37
+ }): Promise<{
38
+ number: number;
39
+ url: string;
40
+ }>;
41
+ createComment(input: {
42
+ number: number;
43
+ body: string;
44
+ }): Promise<{
45
+ url: string;
46
+ }>;
47
+ closeIssue(input: {
48
+ number: number;
49
+ }): Promise<{
50
+ url: string;
51
+ }>;
52
+ listIssuesSince?(sinceISO: string): Promise<ForgeIssue[]>;
53
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { ForgeIssue, ForgePR } from './port.js';
2
+ export declare function residentForgeState(): {
3
+ issues: ForgeIssue[];
4
+ prs: ForgePR[];
5
+ };
6
+ export declare function residentForgeRevision(): number;
7
+ export declare function refreshForgeNow(): Promise<void>;
@@ -0,0 +1,43 @@
1
+ import { ForgeCache } from './cache.js';
2
+ import { forgeDriverFor, resolveForgeHost } from './drivers.js';
3
+ const cache = new ForgeCache();
4
+ let inFlight = null;
5
+ let lastAttempt = 0;
6
+ const TTL_MS = 20_000;
7
+ let lastIssueSync = null;
8
+ let lastFull = 0;
9
+ const FULL_MS = 30 * 60_000;
10
+ function refreshIfStale(now) {
11
+ if (inFlight || (lastAttempt && now - lastAttempt < TTL_MS))
12
+ return;
13
+ const driver = forgeDriverFor(resolveForgeHost());
14
+ if (!driver)
15
+ return;
16
+ lastAttempt = now;
17
+ const startISO = new Date(now).toISOString(); // stamped at fetch START so an update during the fetch lands in the next window
18
+ const incremental = lastIssueSync && driver.listIssuesSince && now - lastFull < FULL_MS;
19
+ inFlight = (incremental
20
+ ? Promise.all([
21
+ driver.listIssuesSince(lastIssueSync).then((delta) => cache.applyIssues(delta)),
22
+ driver.listPRs().then((prs) => cache.setPRs(prs)),
23
+ ]).then(() => { lastIssueSync = startISO; })
24
+ : cache.reconcile(driver).then(() => { lastFull = now; lastIssueSync = startISO; }))
25
+ .catch(() => { })
26
+ .finally(() => { inFlight = null; });
27
+ }
28
+ export function residentForgeState() {
29
+ refreshIfStale(Date.now());
30
+ return cache.state();
31
+ }
32
+ export function residentForgeRevision() {
33
+ return cache.stateRevision();
34
+ }
35
+ export async function refreshForgeNow() {
36
+ if (inFlight)
37
+ await inFlight;
38
+ lastAttempt = 0;
39
+ lastFull = 0;
40
+ refreshIfStale(Date.now());
41
+ if (inFlight)
42
+ await inFlight;
43
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@spexcode/spec-forge",
3
+ "version": "0.6.6",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./dist/index.js",
7
+ "./port": "./dist/port.js",
8
+ "./links": "./dist/links.js",
9
+ "./drivers": "./dist/drivers.js",
10
+ "./resident": "./dist/resident.js",
11
+ "./cli": "./dist/cli.js",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "files": ["dist"],
15
+ "description": "Host-agnostic forge link tracer — reads a forge's open issues/PRs and resolves each to the spec node it serves (issue-body `Spec: <id>` marker + `node/<id>` PR branch). Read-only; a node's status stays git-derived.",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "scripts": {
20
+ "build": "node ../scripts/build-dist.mjs",
21
+ "prepublishOnly": "node ../scripts/release-publish.mjs --from-package-publish",
22
+ "test": "tsx --test src/*.test.ts"
23
+ },
24
+ "dependencies": {
25
+ "@spexcode/spec-core": "0.6.6"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20.16.0",
29
+ "tsx": "^4.19.2",
30
+ "typescript": "^5.6.3"
31
+ }
32
+ }
package/package.json CHANGED
@@ -1,42 +1,47 @@
1
1
  {
2
2
  "name": "spexcode",
3
- "version": "0.6.2",
3
+ "version": "0.6.6",
4
4
  "type": "module",
5
5
  "description": "SpexCode — a spec-driven, self-developing dev tool. The `spex` CLI + spec server reads the .spec tree and its git history, and serves the dashboard.",
6
6
  "license": "MIT",
7
7
  "bin": {
8
- "spex": "spec-cli/bin/spex.mjs"
8
+ "spex": "bin/spex.mjs"
9
9
  },
10
+ "workspaces": [
11
+ "packages/*",
12
+ "spec-cli",
13
+ "spec-eval",
14
+ "spec-forge",
15
+ "spec-dashboard"
16
+ ],
10
17
  "files": [
11
- "spec-cli/src",
12
- "!spec-cli/src/**/*.test.ts",
13
- "spec-cli/bin",
14
- "spec-cli/templates",
15
- "spec-cli/hooks",
16
- "spec-eval/src",
17
- "!spec-eval/src/**/*.test.ts",
18
- "spec-forge/src",
19
- "!spec-forge/src/**/*.test.ts",
20
- "spec-dashboard/dist",
21
- "spec-dashboard/src/reviewFilters.js",
22
- "spec-dashboard/src/reviewQuery.js",
23
- "spec-dashboard/src/session.js",
24
- "README.md"
18
+ "bin"
25
19
  ],
26
20
  "engines": {
27
21
  "node": ">=22"
28
22
  },
29
23
  "scripts": {
30
- "api": "cd spec-cli && npm run serve",
24
+ "build": "npm run build --workspace=@spexcode/spec-core && npm run build --workspace=@spexcode/session-core && npm run build --workspace=@spexcode/spec-eval && npm run build --workspace=@spexcode/spec-forge && npm run build --workspace=@spexcode/spec-cli",
25
+ "api": "npm run build && node bin/spex.mjs serve",
31
26
  "web": "cd spec-dashboard && npm run dev",
27
+ "build:public": "node scripts/public-graph-build.mjs",
28
+ "test:public-graph": "npm run build:public && node spec-dashboard/test/public-graph-static.e2e.mjs",
32
29
  "lint": "node scripts/sync-init-plugins.mjs --check && cd spec-cli && npm run -s lint",
33
30
  "sync:init-plugins": "node scripts/sync-init-plugins.mjs --write",
34
31
  "test:init-plugins": "node --test scripts/sync-init-plugins.test.mjs",
32
+ "test:release-publish": "node --test scripts/release-publish.test.mjs",
33
+ "release:check": "node scripts/release-publish.mjs",
34
+ "release:publish": "node scripts/release-publish.mjs --publish",
35
+ "prepublishOnly": "node scripts/release-publish.mjs --from-package-publish",
36
+ "test:docs-release": "node --test scripts/docs-release.test.mjs scripts/reference-snapshot.test.mjs",
35
37
  "hooks": "bash scripts/install-hooks.sh",
36
38
  "prepack": "node scripts/sync-init-plugins.mjs --check && node scripts/prepack.mjs"
37
39
  },
38
40
  "dependencies": {
39
- "tsx": "^4.19.2"
41
+ "@spexcode/spec-cli": "0.6.6"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
40
45
  },
41
46
  "optionalDependencies": {
42
47
  "@hono/node-server": "^1.13.7",
@@ -47,5 +52,14 @@
47
52
  "devDependencies": {
48
53
  "@types/node": "^20.16.0",
49
54
  "typescript": "^5.6.3"
50
- }
55
+ },
56
+ "bundleDependencies": [
57
+ "@spexcode/spec-cli"
58
+ ],
59
+ "main": "index.js",
60
+ "directories": {
61
+ "doc": "docs"
62
+ },
63
+ "keywords": [],
64
+ "author": ""
51
65
  }
@@ -1,69 +0,0 @@
1
- #!/usr/bin/env node
2
- // @@@ spex launcher - this repo has no build step, so the installed `spex` bin shells to tsx to
3
- // run the TypeScript CLI directly. After `npm link` (or a global install) `spex lint` works anywhere.
4
- import { spawn } from 'node:child_process'
5
- import { existsSync, readdirSync, readFileSync } from 'node:fs'
6
- import { createRequire } from 'node:module'
7
- import { fileURLToPath } from 'node:url'
8
- import { dirname, join } from 'node:path'
9
-
10
- // @@@ self-contained - resolve tsx + cli from THIS package, not the cwd. A fresh worktree off main has
11
- // no node_modules, so `npx tsx` there would try to install; using the package's own tsx makes a global
12
- // `spex` work from any cwd (agents, git hooks) against this package's code, operating on the cwd.
13
- const pkg = join(dirname(fileURLToPath(import.meta.url)), '..') // spec-cli/
14
- const cli = join(pkg, 'src', 'cli.ts')
15
-
16
- // @@@ mid-merge guard - no build step means every spex call parses this package's live TypeScript, so
17
- // while a merge conflict is being resolved in the checkout that hosts it, the source holds conflict
18
- // markers and tsx dies with a raw esbuild stacktrace — on EVERY call, including the Stop hook and an
19
- // agent's `spex session done`. Catch that one transient state up front: scan the source trees the CLI
20
- // imports (spec-cli ←→ spec-eval ←→ spec-forge), and if any file carries a marker, print one actionable
21
- // line and exit 75 (EX_TEMPFAIL: transient, retry) instead of spawning tsx into the stacktrace.
22
- const srcRoots = [join(pkg, 'src'), join(pkg, '..', 'spec-eval', 'src'), join(pkg, '..', 'spec-forge', 'src')]
23
- const conflicted = srcRoots.flatMap((root) => {
24
- if (!existsSync(root)) return []
25
- return readdirSync(root, { recursive: true })
26
- .filter((f) => /\.(ts|tsx|js|mjs)$/.test(String(f)))
27
- .map((f) => join(root, String(f)))
28
- .filter((path) => {
29
- try { return /^<{7} /m.test(readFileSync(path, 'utf8')) } catch { return false }
30
- })
31
- })
32
- if (conflicted.length) {
33
- console.error('spex: paused mid-merge — unresolved conflict markers in the source spex runs:')
34
- for (const f of conflicted) console.error(` ${f}`)
35
- console.error('spex executes this TypeScript directly (no build step); resolve the merge, then retry. (exit 75)')
36
- process.exit(75)
37
- }
38
- // @@@ cross-platform tsx resolution ([[platform-support]]) - resolve tsx's JS ENTRY (dist/cli.mjs) with
39
- // Node's own resolver from spec-cli, then run it through THIS node binary (process.execPath). tsx may live
40
- // in spec-cli/node_modules (dev) or be hoisted above the installed `spexcode` package (a real consumer
41
- // project) — one resolver covers both without hardcoded consumer paths. We deliberately never spawn the
42
- // `.bin/tsx` shim, nor a `.mjs` directly: on Windows the shim is an extensionless sh script and the `.mjs`
43
- // leans on a shebang, neither of which `child_process.spawn` can execute — that is the #37 crash
44
- // (`spawn …\node_modules\.bin\tsx ENOENT`) of `spex init`. `node dist/cli.mjs …` is shell-free and identical
45
- // on every OS.
46
- function resolveTsxCli() {
47
- try {
48
- const req = createRequire(join(pkg, 'package.json'))
49
- return join(dirname(req.resolve('tsx/package.json')), 'dist', 'cli.mjs')
50
- } catch {
51
- console.error('spex: cannot find the `tsx` runtime this package needs — run `npm install` in the SpexCode package, then retry.')
52
- process.exit(69)
53
- }
54
- }
55
- const tsxCli = resolveTsxCli()
56
- const args = process.argv.slice(2)
57
- const env = { ...process.env }
58
- // A backend/dashboard is a project or host control plane, never the managed session that happened to start
59
- // it. Scrub before tsx starts: doing this inside cli.ts is too late because tsx's resident esbuild helper has
60
- // already inherited the caller. New session launches provide the adapter-registry-derived key manifest; the
61
- // fallback covers sessions created before that manifest existed.
62
- if (args[0] === 'serve' || args[0] === 'dashboard') {
63
- const identityKeys = (env.SPEXCODE_SESSION_IDENTITY_VARS
64
- || 'SPEXCODE_SESSION_ID,CLAUDE_CODE_SESSION_ID,CODEX_THREAD_ID,OPENCODE_SESSION_ID,PI_SESSION_ID')
65
- .split(',').map((key) => key.trim()).filter(Boolean)
66
- for (const key of identityKeys) delete env[key]
67
- }
68
- spawn(process.execPath, [tsxCli, cli, ...args], { stdio: 'inherit', env })
69
- .on('exit', (code) => process.exit(code ?? 0))