spexcode 0.6.2 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +3 -1
  2. package/bin/spex.mjs +4 -0
  3. package/node_modules/@spexcode/session-core/dist/delivery-queue.d.ts +23 -0
  4. package/node_modules/@spexcode/session-core/dist/delivery-queue.js +195 -0
  5. package/node_modules/@spexcode/session-core/dist/index.d.ts +5 -0
  6. package/node_modules/@spexcode/session-core/dist/index.js +5 -0
  7. package/node_modules/@spexcode/session-core/dist/internal.d.ts +3 -0
  8. package/node_modules/@spexcode/session-core/dist/internal.js +3 -0
  9. package/node_modules/@spexcode/session-core/dist/message.d.ts +22 -0
  10. package/node_modules/@spexcode/session-core/dist/message.js +52 -0
  11. package/node_modules/@spexcode/session-core/dist/record-lock.d.ts +7 -0
  12. package/node_modules/@spexcode/session-core/dist/record-lock.js +152 -0
  13. package/node_modules/@spexcode/session-core/dist/runtime-session.d.ts +50 -0
  14. package/node_modules/@spexcode/session-core/dist/runtime-session.js +286 -0
  15. package/node_modules/@spexcode/session-core/dist/session-cursors.d.ts +14 -0
  16. package/node_modules/@spexcode/session-core/dist/session-cursors.js +82 -0
  17. package/node_modules/@spexcode/session-core/dist/session-timeline.d.ts +46 -0
  18. package/node_modules/@spexcode/session-core/dist/session-timeline.js +216 -0
  19. package/node_modules/@spexcode/session-core/package.json +33 -0
  20. package/node_modules/@spexcode/spec-cli/bin/spex.mjs +77 -0
  21. package/node_modules/@spexcode/spec-cli/dist/attach.d.ts +2 -0
  22. package/node_modules/@spexcode/spec-cli/dist/attach.js +48 -0
  23. package/node_modules/@spexcode/spec-cli/dist/claude-headless.d.ts +36 -0
  24. package/node_modules/@spexcode/spec-cli/dist/claude-headless.js +316 -0
  25. package/node_modules/@spexcode/spec-cli/dist/cli.d.ts +1 -0
  26. package/node_modules/@spexcode/spec-cli/dist/cli.js +1908 -0
  27. package/node_modules/@spexcode/spec-cli/dist/client.d.ts +112 -0
  28. package/node_modules/@spexcode/spec-cli/dist/client.js +481 -0
  29. package/node_modules/@spexcode/spec-cli/dist/cockpit.d.ts +7 -0
  30. package/node_modules/@spexcode/spec-cli/dist/cockpit.js +26 -0
  31. package/node_modules/@spexcode/spec-cli/dist/codex-headless.d.ts +1 -0
  32. package/{spec-cli/src/codex-headless.ts → node_modules/@spexcode/spec-cli/dist/codex-headless.js} +3 -9
  33. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.d.ts +58 -0
  34. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.js +798 -0
  35. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.d.ts +1 -0
  36. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.js +90 -0
  37. package/node_modules/@spexcode/spec-cli/dist/contract-filter.d.ts +14 -0
  38. package/node_modules/@spexcode/spec-cli/dist/contract-filter.js +219 -0
  39. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.d.ts +6 -0
  40. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.js +50 -0
  41. package/node_modules/@spexcode/spec-cli/dist/doctor.d.ts +9 -0
  42. package/node_modules/@spexcode/spec-cli/dist/doctor.js +553 -0
  43. package/node_modules/@spexcode/spec-cli/dist/eval-host.d.ts +1 -0
  44. package/node_modules/@spexcode/spec-cli/dist/eval-host.js +19 -0
  45. package/node_modules/@spexcode/spec-cli/dist/execution-trace.d.ts +26 -0
  46. package/node_modules/@spexcode/spec-cli/dist/execution-trace.js +475 -0
  47. package/node_modules/@spexcode/spec-cli/dist/file-write.d.ts +2 -0
  48. package/node_modules/@spexcode/spec-cli/dist/file-write.js +26 -0
  49. package/node_modules/@spexcode/spec-cli/dist/flat.d.ts +89 -0
  50. package/node_modules/@spexcode/spec-cli/dist/flat.js +1076 -0
  51. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.d.ts +56 -0
  52. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.js +168 -0
  53. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.d.ts +28 -0
  54. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.js +363 -0
  55. package/node_modules/@spexcode/spec-cli/dist/gateway.d.ts +38 -0
  56. package/node_modules/@spexcode/spec-cli/dist/gateway.js +527 -0
  57. package/node_modules/@spexcode/spec-cli/dist/graphCache.d.ts +27 -0
  58. package/node_modules/@spexcode/spec-cli/dist/graphCache.js +717 -0
  59. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.d.ts +14 -0
  60. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.js +36 -0
  61. package/node_modules/@spexcode/spec-cli/dist/graphStream.d.ts +85 -0
  62. package/node_modules/@spexcode/spec-cli/dist/graphStream.js +1195 -0
  63. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.d.ts +64 -0
  64. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.js +166 -0
  65. package/node_modules/@spexcode/spec-cli/dist/guide.d.ts +8 -0
  66. package/{spec-cli/src/guide.ts → node_modules/@spexcode/spec-cli/dist/guide.js} +36 -32
  67. package/node_modules/@spexcode/spec-cli/dist/harness-select.d.ts +18 -0
  68. package/node_modules/@spexcode/spec-cli/dist/harness-select.js +62 -0
  69. package/node_modules/@spexcode/spec-cli/dist/harness.d.ts +338 -0
  70. package/node_modules/@spexcode/spec-cli/dist/harness.js +3146 -0
  71. package/node_modules/@spexcode/spec-cli/dist/headless-controller.d.ts +9 -0
  72. package/node_modules/@spexcode/spec-cli/dist/headless-controller.js +47 -0
  73. package/node_modules/@spexcode/spec-cli/dist/help.d.ts +15 -0
  74. package/node_modules/@spexcode/spec-cli/dist/help.js +594 -0
  75. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.d.ts +18 -0
  76. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.js +122 -0
  77. package/node_modules/@spexcode/spec-cli/dist/hooks.d.ts +1 -0
  78. package/{spec-cli/src/hooks.ts → node_modules/@spexcode/spec-cli/dist/hooks.js} +15 -15
  79. package/node_modules/@spexcode/spec-cli/dist/host-resources.d.ts +97 -0
  80. package/node_modules/@spexcode/spec-cli/dist/host-resources.js +795 -0
  81. package/node_modules/@spexcode/spec-cli/dist/host.d.ts +88 -0
  82. package/node_modules/@spexcode/spec-cli/dist/host.js +663 -0
  83. package/node_modules/@spexcode/spec-cli/dist/index.d.ts +1 -0
  84. package/node_modules/@spexcode/spec-cli/dist/index.js +899 -0
  85. package/node_modules/@spexcode/spec-cli/dist/init.d.ts +1 -0
  86. package/node_modules/@spexcode/spec-cli/dist/init.js +284 -0
  87. package/node_modules/@spexcode/spec-cli/dist/issues-cli.d.ts +6 -0
  88. package/node_modules/@spexcode/spec-cli/dist/issues-cli.js +334 -0
  89. package/node_modules/@spexcode/spec-cli/dist/issues.d.ts +69 -0
  90. package/node_modules/@spexcode/spec-cli/dist/issues.js +189 -0
  91. package/node_modules/@spexcode/spec-cli/dist/lint.d.ts +34 -0
  92. package/node_modules/@spexcode/spec-cli/dist/lint.js +476 -0
  93. package/node_modules/@spexcode/spec-cli/dist/listen.d.ts +8 -0
  94. package/node_modules/@spexcode/spec-cli/dist/listen.js +24 -0
  95. package/node_modules/@spexcode/spec-cli/dist/localIssues.d.ts +65 -0
  96. package/node_modules/@spexcode/spec-cli/dist/localIssues.js +582 -0
  97. package/node_modules/@spexcode/spec-cli/dist/login-page.d.ts +5 -0
  98. package/{spec-cli/src/login-page.ts → node_modules/@spexcode/spec-cli/dist/login-page.js} +7 -7
  99. package/node_modules/@spexcode/spec-cli/dist/loop-in.d.ts +23 -0
  100. package/{spec-cli/src/loop-in.ts → node_modules/@spexcode/spec-cli/dist/loop-in.js} +35 -45
  101. package/node_modules/@spexcode/spec-cli/dist/machine-peer.d.ts +69 -0
  102. package/node_modules/@spexcode/spec-cli/dist/machine-peer.js +603 -0
  103. package/node_modules/@spexcode/spec-cli/dist/materialize.d.ts +18 -0
  104. package/node_modules/@spexcode/spec-cli/dist/materialize.js +468 -0
  105. package/node_modules/@spexcode/spec-cli/dist/mentions.d.ts +50 -0
  106. package/node_modules/@spexcode/spec-cli/dist/mentions.js +117 -0
  107. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.d.ts +5 -0
  108. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.js +215 -0
  109. package/node_modules/@spexcode/spec-cli/dist/opencode.d.ts +3 -0
  110. package/{spec-cli/src/opencode.ts → node_modules/@spexcode/spec-cli/dist/opencode.js} +9 -13
  111. package/node_modules/@spexcode/spec-cli/dist/pi-harness.d.ts +3 -0
  112. package/{spec-cli/src/pi-harness.ts → node_modules/@spexcode/spec-cli/dist/pi-harness.js} +45 -40
  113. package/node_modules/@spexcode/spec-cli/dist/pi-headless.d.ts +25 -0
  114. package/node_modules/@spexcode/spec-cli/dist/pi-headless.js +196 -0
  115. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.d.ts +21 -0
  116. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.js +146 -0
  117. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.d.ts +10 -0
  118. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.js +404 -0
  119. package/node_modules/@spexcode/spec-cli/dist/pty-helper.d.mts +1 -0
  120. package/node_modules/@spexcode/spec-cli/dist/pty-helper.mjs +101 -0
  121. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.d.mts +2 -0
  122. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.mjs +23 -0
  123. package/node_modules/@spexcode/spec-cli/dist/public-graph.d.ts +46 -0
  124. package/node_modules/@spexcode/spec-cli/dist/public-graph.js +56 -0
  125. package/node_modules/@spexcode/spec-cli/dist/ranker.d.ts +15 -0
  126. package/node_modules/@spexcode/spec-cli/dist/ranker.js +188 -0
  127. package/node_modules/@spexcode/spec-cli/dist/reaper.d.ts +6 -0
  128. package/node_modules/@spexcode/spec-cli/dist/reaper.js +81 -0
  129. package/node_modules/@spexcode/spec-cli/dist/reviews.d.ts +189 -0
  130. package/node_modules/@spexcode/spec-cli/dist/reviews.js +350 -0
  131. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.d.ts +6 -0
  132. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.js +37 -0
  133. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.d.ts +21 -0
  134. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.js +84 -0
  135. package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.d.ts +1 -0
  136. package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.js +58 -0
  137. package/node_modules/@spexcode/spec-cli/dist/search.bench.d.mts +1 -0
  138. package/node_modules/@spexcode/spec-cli/dist/search.bench.mjs +75 -0
  139. package/node_modules/@spexcode/spec-cli/dist/search.d.ts +20 -0
  140. package/node_modules/@spexcode/spec-cli/dist/search.js +61 -0
  141. package/node_modules/@spexcode/spec-cli/dist/session-declarations.d.ts +13 -0
  142. package/node_modules/@spexcode/spec-cli/dist/session-declarations.js +126 -0
  143. package/node_modules/@spexcode/spec-cli/dist/session-execution.d.ts +10 -0
  144. package/node_modules/@spexcode/spec-cli/dist/session-execution.js +70 -0
  145. package/node_modules/@spexcode/spec-cli/dist/session-files.d.ts +28 -0
  146. package/node_modules/@spexcode/spec-cli/dist/session-files.js +130 -0
  147. package/node_modules/@spexcode/spec-cli/dist/session-follow.d.ts +31 -0
  148. package/node_modules/@spexcode/spec-cli/dist/session-follow.js +179 -0
  149. package/node_modules/@spexcode/spec-cli/dist/session-reparent.d.ts +10 -0
  150. package/node_modules/@spexcode/spec-cli/dist/session-reparent.js +33 -0
  151. package/node_modules/@spexcode/spec-cli/dist/session-timeline.d.ts +11 -0
  152. package/node_modules/@spexcode/spec-cli/dist/session-timeline.js +20 -0
  153. package/node_modules/@spexcode/spec-cli/dist/session-web.d.ts +24 -0
  154. package/node_modules/@spexcode/spec-cli/dist/session-web.js +141 -0
  155. package/node_modules/@spexcode/spec-cli/dist/sessions.d.ts +433 -0
  156. package/node_modules/@spexcode/spec-cli/dist/sessions.js +4667 -0
  157. package/node_modules/@spexcode/spec-cli/dist/sh.d.ts +1 -0
  158. package/node_modules/@spexcode/spec-cli/dist/sh.js +3 -0
  159. package/node_modules/@spexcode/spec-cli/dist/shim-runtime.d.ts +1 -0
  160. package/{spec-cli/src/shim-runtime.ts → node_modules/@spexcode/spec-cli/dist/shim-runtime.js} +3 -4
  161. package/node_modules/@spexcode/spec-cli/dist/slash-commands.d.ts +9 -0
  162. package/node_modules/@spexcode/spec-cli/dist/slash-commands.js +307 -0
  163. package/node_modules/@spexcode/spec-cli/dist/source-files.d.ts +9 -0
  164. package/node_modules/@spexcode/spec-cli/dist/source-files.js +113 -0
  165. package/node_modules/@spexcode/spec-cli/dist/supervise.d.ts +1 -0
  166. package/node_modules/@spexcode/spec-cli/dist/supervise.js +308 -0
  167. package/node_modules/@spexcode/spec-cli/dist/tree.d.ts +25 -0
  168. package/node_modules/@spexcode/spec-cli/dist/tree.js +98 -0
  169. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.d.ts +3 -0
  170. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.js +41 -0
  171. package/node_modules/@spexcode/spec-cli/dist/uninstall.d.ts +3 -0
  172. package/node_modules/@spexcode/spec-cli/dist/uninstall.js +177 -0
  173. package/node_modules/@spexcode/spec-cli/dist/uploads.d.ts +36 -0
  174. package/node_modules/@spexcode/spec-cli/dist/uploads.js +243 -0
  175. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.d.ts +1 -0
  176. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.js +47 -0
  177. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/dispatch.sh +5 -5
  178. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/harness.sh +1 -1
  179. package/node_modules/@spexcode/spec-cli/package.json +49 -0
  180. package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -0
  181. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec-first.sh +1 -1
  182. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec-of-file.sh +1 -0
  183. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/spec.md +2 -2
  184. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/stop-gate.sh +31 -29
  185. package/node_modules/@spexcode/spec-core/dist/anchors.d.ts +94 -0
  186. package/node_modules/@spexcode/spec-core/dist/anchors.js +730 -0
  187. package/node_modules/@spexcode/spec-core/dist/git.d.ts +170 -0
  188. package/node_modules/@spexcode/spec-core/dist/git.js +2768 -0
  189. package/node_modules/@spexcode/spec-core/dist/graph-delta.d.ts +44 -0
  190. package/node_modules/@spexcode/spec-core/dist/graph-delta.js +72 -0
  191. package/node_modules/@spexcode/spec-core/dist/graph.d.ts +34 -0
  192. package/node_modules/@spexcode/spec-core/dist/graph.js +237 -0
  193. package/node_modules/@spexcode/spec-core/dist/graphDelta.d.ts +3 -0
  194. package/node_modules/@spexcode/spec-core/dist/graphDelta.js +13 -0
  195. package/node_modules/@spexcode/spec-core/dist/harness-identity.d.ts +31 -0
  196. package/node_modules/@spexcode/spec-core/dist/harness-identity.js +20 -0
  197. package/node_modules/@spexcode/spec-core/dist/identity-presets.d.ts +152 -0
  198. package/node_modules/@spexcode/spec-core/dist/identity-presets.js +132 -0
  199. package/node_modules/@spexcode/spec-core/dist/index.d.ts +45 -0
  200. package/node_modules/@spexcode/spec-core/dist/index.js +19 -0
  201. package/node_modules/@spexcode/spec-core/dist/layout.d.ts +187 -0
  202. package/node_modules/@spexcode/spec-core/dist/layout.js +548 -0
  203. package/node_modules/@spexcode/spec-core/dist/process-identity.d.ts +37 -0
  204. package/node_modules/@spexcode/spec-core/dist/process-identity.js +214 -0
  205. package/node_modules/@spexcode/spec-core/dist/project-identity.d.ts +12 -0
  206. package/node_modules/@spexcode/spec-core/dist/project-identity.js +71 -0
  207. package/node_modules/@spexcode/spec-core/dist/project-store.d.ts +3 -0
  208. package/node_modules/@spexcode/spec-core/dist/project-store.js +14 -0
  209. package/node_modules/@spexcode/spec-core/dist/resilience.d.ts +2 -0
  210. package/node_modules/@spexcode/spec-core/dist/resilience.js +40 -0
  211. package/node_modules/@spexcode/spec-core/dist/review/index.d.ts +3 -0
  212. package/node_modules/@spexcode/spec-core/dist/review/index.js +5 -0
  213. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.d.ts +77 -0
  214. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.js +308 -0
  215. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.d.ts +66 -0
  216. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.js +180 -0
  217. package/node_modules/@spexcode/spec-core/dist/review/session.d.ts +4 -0
  218. package/node_modules/@spexcode/spec-core/dist/review/session.js +8 -0
  219. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.d.ts +15 -0
  220. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.js +12 -0
  221. package/node_modules/@spexcode/spec-core/dist/root-lru.d.ts +4 -0
  222. package/{spec-cli/src/root-lru.ts → node_modules/@spexcode/spec-core/dist/root-lru.js} +26 -30
  223. package/node_modules/@spexcode/spec-core/dist/specs.d.ts +117 -0
  224. package/node_modules/@spexcode/spec-core/dist/specs.js +489 -0
  225. package/node_modules/@spexcode/spec-core/package.json +28 -0
  226. package/node_modules/@spexcode/spec-eval/dist/cache.d.ts +10 -0
  227. package/node_modules/@spexcode/spec-eval/dist/cache.js +50 -0
  228. package/node_modules/@spexcode/spec-eval/dist/cli.d.ts +22 -0
  229. package/node_modules/@spexcode/spec-eval/dist/cli.js +981 -0
  230. package/node_modules/@spexcode/spec-eval/dist/evaltab.d.ts +98 -0
  231. package/node_modules/@spexcode/spec-eval/dist/evaltab.js +176 -0
  232. package/node_modules/@spexcode/spec-eval/dist/filing.d.ts +16 -0
  233. package/node_modules/@spexcode/spec-eval/dist/filing.js +36 -0
  234. package/node_modules/@spexcode/spec-eval/dist/freshness.d.ts +48 -0
  235. package/node_modules/@spexcode/spec-eval/dist/freshness.js +799 -0
  236. package/node_modules/@spexcode/spec-eval/dist/host.d.ts +46 -0
  237. package/node_modules/@spexcode/spec-eval/dist/host.js +53 -0
  238. package/node_modules/@spexcode/spec-eval/dist/humanok.d.ts +11 -0
  239. package/node_modules/@spexcode/spec-eval/dist/humanok.js +27 -0
  240. package/node_modules/@spexcode/spec-eval/dist/index.d.ts +4 -0
  241. package/node_modules/@spexcode/spec-eval/dist/index.js +4 -0
  242. package/node_modules/@spexcode/spec-eval/dist/remarks.d.ts +31 -0
  243. package/node_modules/@spexcode/spec-eval/dist/remarks.js +1 -0
  244. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.d.ts +13 -0
  245. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.js +303 -0
  246. package/node_modules/@spexcode/spec-eval/dist/scenarios.d.ts +99 -0
  247. package/node_modules/@spexcode/spec-eval/dist/scenarios.js +650 -0
  248. package/node_modules/@spexcode/spec-eval/dist/sessioneval.d.ts +307 -0
  249. package/node_modules/@spexcode/spec-eval/dist/sessioneval.js +1883 -0
  250. package/node_modules/@spexcode/spec-eval/dist/sidecar.d.ts +55 -0
  251. package/node_modules/@spexcode/spec-eval/dist/sidecar.js +82 -0
  252. package/node_modules/@spexcode/spec-eval/dist/timeline.d.ts +25 -0
  253. package/node_modules/@spexcode/spec-eval/dist/timeline.js +65 -0
  254. package/node_modules/@spexcode/spec-eval/dist/ui-path.d.ts +1 -0
  255. package/node_modules/@spexcode/spec-eval/dist/ui-path.js +2 -0
  256. package/node_modules/@spexcode/spec-eval/package.json +36 -0
  257. package/node_modules/@spexcode/spec-forge/dist/cache.d.ts +29 -0
  258. package/node_modules/@spexcode/spec-forge/dist/cache.js +59 -0
  259. package/node_modules/@spexcode/spec-forge/dist/cli.d.ts +1 -0
  260. package/node_modules/@spexcode/spec-forge/dist/cli.js +100 -0
  261. package/node_modules/@spexcode/spec-forge/dist/drivers/github.d.ts +2 -0
  262. package/node_modules/@spexcode/spec-forge/dist/drivers/github.js +116 -0
  263. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.d.ts +7 -0
  264. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.js +144 -0
  265. package/node_modules/@spexcode/spec-forge/dist/drivers.d.ts +10 -0
  266. package/node_modules/@spexcode/spec-forge/dist/drivers.js +83 -0
  267. package/node_modules/@spexcode/spec-forge/dist/index.d.ts +4 -0
  268. package/node_modules/@spexcode/spec-forge/dist/index.js +4 -0
  269. package/node_modules/@spexcode/spec-forge/dist/links.d.ts +15 -0
  270. package/node_modules/@spexcode/spec-forge/dist/links.js +65 -0
  271. package/node_modules/@spexcode/spec-forge/dist/needs-eval.d.ts +10 -0
  272. package/node_modules/@spexcode/spec-forge/dist/needs-eval.js +20 -0
  273. package/node_modules/@spexcode/spec-forge/dist/port.d.ts +53 -0
  274. package/node_modules/@spexcode/spec-forge/dist/port.js +1 -0
  275. package/node_modules/@spexcode/spec-forge/dist/resident.d.ts +7 -0
  276. package/node_modules/@spexcode/spec-forge/dist/resident.js +43 -0
  277. package/node_modules/@spexcode/spec-forge/package.json +32 -0
  278. package/package.json +33 -19
  279. package/spec-cli/bin/spex.mjs +0 -69
  280. package/spec-cli/src/anchors.ts +0 -728
  281. package/spec-cli/src/attach.ts +0 -43
  282. package/spec-cli/src/claude-headless.ts +0 -321
  283. package/spec-cli/src/cli.ts +0 -1258
  284. package/spec-cli/src/client.ts +0 -414
  285. package/spec-cli/src/cockpit.ts +0 -43
  286. package/spec-cli/src/codex-runtime-generations.ts +0 -646
  287. package/spec-cli/src/commit-surgery.ts +0 -68
  288. package/spec-cli/src/contract-filter.ts +0 -202
  289. package/spec-cli/src/delivery-queue.ts +0 -165
  290. package/spec-cli/src/doctor.ts +0 -516
  291. package/spec-cli/src/execution-trace.ts +0 -444
  292. package/spec-cli/src/file-write.ts +0 -22
  293. package/spec-cli/src/gateway-auth.ts +0 -181
  294. package/spec-cli/src/gateway-hub.ts +0 -358
  295. package/spec-cli/src/gateway.ts +0 -461
  296. package/spec-cli/src/git.ts +0 -2556
  297. package/spec-cli/src/graph.ts +0 -271
  298. package/spec-cli/src/graphCache.ts +0 -710
  299. package/spec-cli/src/graphDelta.ts +0 -77
  300. package/spec-cli/src/graphStream.ts +0 -1019
  301. package/spec-cli/src/harness-select.ts +0 -77
  302. package/spec-cli/src/harness.ts +0 -3025
  303. package/spec-cli/src/headless-controller.ts +0 -63
  304. package/spec-cli/src/help.ts +0 -492
  305. package/spec-cli/src/host-resources.ts +0 -762
  306. package/spec-cli/src/host.ts +0 -611
  307. package/spec-cli/src/identity-presets.d.ts +0 -13
  308. package/spec-cli/src/identity-presets.js +0 -138
  309. package/spec-cli/src/index.ts +0 -818
  310. package/spec-cli/src/init.ts +0 -258
  311. package/spec-cli/src/issues-cli.ts +0 -276
  312. package/spec-cli/src/issues.ts +0 -237
  313. package/spec-cli/src/layout.ts +0 -640
  314. package/spec-cli/src/lint.ts +0 -488
  315. package/spec-cli/src/listen.ts +0 -28
  316. package/spec-cli/src/localIssues.ts +0 -538
  317. package/spec-cli/src/materialize.ts +0 -417
  318. package/spec-cli/src/mentions.ts +0 -81
  319. package/spec-cli/src/opencode-headless.ts +0 -205
  320. package/spec-cli/src/pi-headless.ts +0 -153
  321. package/spec-cli/src/plugin-harness.ts +0 -157
  322. package/spec-cli/src/process-identity.ts +0 -207
  323. package/spec-cli/src/project-identity.ts +0 -73
  324. package/spec-cli/src/project-store.ts +0 -17
  325. package/spec-cli/src/pty-bridge.ts +0 -396
  326. package/spec-cli/src/pty-helper.mjs +0 -96
  327. package/spec-cli/src/pty-native-helper.mjs +0 -22
  328. package/spec-cli/src/ranker.ts +0 -191
  329. package/spec-cli/src/reaper.ts +0 -125
  330. package/spec-cli/src/resilience.ts +0 -41
  331. package/spec-cli/src/reviewSnapshot.ts +0 -28
  332. package/spec-cli/src/reviews.ts +0 -434
  333. package/spec-cli/src/runtime-guard.ts +0 -35
  334. package/spec-cli/src/runtime-ownership.ts +0 -88
  335. package/spec-cli/src/search.bench.mjs +0 -80
  336. package/spec-cli/src/search.ts +0 -63
  337. package/spec-cli/src/session-cursors.ts +0 -91
  338. package/spec-cli/src/session-execution.ts +0 -68
  339. package/spec-cli/src/session-files.ts +0 -121
  340. package/spec-cli/src/session-follow.ts +0 -182
  341. package/spec-cli/src/session-reparent.ts +0 -33
  342. package/spec-cli/src/session-timeline.ts +0 -247
  343. package/spec-cli/src/session-web.ts +0 -135
  344. package/spec-cli/src/sessions.ts +0 -3883
  345. package/spec-cli/src/sh.ts +0 -3
  346. package/spec-cli/src/slash-commands.ts +0 -318
  347. package/spec-cli/src/source-files.ts +0 -104
  348. package/spec-cli/src/specs.ts +0 -498
  349. package/spec-cli/src/supervise.ts +0 -245
  350. package/spec-cli/src/tree.ts +0 -118
  351. package/spec-cli/src/tsx-bin.ts +0 -18
  352. package/spec-cli/src/uninstall.ts +0 -171
  353. package/spec-cli/src/uploads.ts +0 -253
  354. package/spec-cli/src/worktree-sources.ts +0 -42
  355. package/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +0 -8
  356. package/spec-dashboard/dist/assets/App-B6IbFbGu.js +0 -2
  357. package/spec-dashboard/dist/assets/Dashboard-C5ap-Sga.css +0 -1
  358. package/spec-dashboard/dist/assets/Dashboard-_sDk7Rcg.js +0 -27
  359. package/spec-dashboard/dist/assets/EvalsPage-BT357Lyt.js +0 -2
  360. package/spec-dashboard/dist/assets/IssuesPage-BG9rNOgV.js +0 -1
  361. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  362. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  363. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  364. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  365. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  366. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  367. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  368. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  369. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  370. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  371. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  372. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  373. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  374. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  375. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  376. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  377. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  378. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  379. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  380. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  381. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  382. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  383. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  384. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  385. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  386. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  387. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  388. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  389. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  390. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  391. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  392. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  393. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  394. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  395. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  396. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  397. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  398. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  399. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  400. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  401. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  402. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  403. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  404. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  405. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  406. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  407. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  408. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  409. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  410. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  411. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  412. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  413. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  414. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  415. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  416. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  417. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  418. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  419. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  420. package/spec-dashboard/dist/assets/MobileApp-D9yPMR3A.js +0 -2
  421. package/spec-dashboard/dist/assets/Modal-B3EcgeA3.js +0 -1
  422. package/spec-dashboard/dist/assets/PageScroll-CNZOugWV.js +0 -1
  423. package/spec-dashboard/dist/assets/ProjectsPage-C2CRHmvs.js +0 -1
  424. package/spec-dashboard/dist/assets/SessionInterface-6GBZ9nXN.css +0 -32
  425. package/spec-dashboard/dist/assets/SessionInterface-DOEjuT3l.js +0 -40
  426. package/spec-dashboard/dist/assets/SessionWindow-1nYgZ4CL.js +0 -1
  427. package/spec-dashboard/dist/assets/Settings-7WeTJn0V.js +0 -1
  428. package/spec-dashboard/dist/assets/Thread-CEbzAFQn.js +0 -13
  429. package/spec-dashboard/dist/assets/bindings-BC9vqpYU.js +0 -1
  430. package/spec-dashboard/dist/assets/data-SlvxNA2r.js +0 -1
  431. package/spec-dashboard/dist/assets/index-DLVeOHL-.js +0 -41
  432. package/spec-dashboard/dist/assets/index-DYLGfPjx.css +0 -1
  433. package/spec-dashboard/dist/assets/launch-Cp579UoJ.css +0 -1
  434. package/spec-dashboard/dist/assets/launch-yxCYr64x.js +0 -276
  435. package/spec-dashboard/dist/assets/sessionSurface--7l69h4F.js +0 -1
  436. package/spec-dashboard/dist/index.html +0 -29
  437. package/spec-dashboard/src/reviewFilters.js +0 -322
  438. package/spec-dashboard/src/reviewQuery.js +0 -174
  439. package/spec-dashboard/src/session.js +0 -199
  440. package/spec-eval/src/cache.ts +0 -57
  441. package/spec-eval/src/cli.ts +0 -894
  442. package/spec-eval/src/evaltab.ts +0 -264
  443. package/spec-eval/src/filing.ts +0 -39
  444. package/spec-eval/src/freshness.ts +0 -836
  445. package/spec-eval/src/humanok.ts +0 -28
  446. package/spec-eval/src/scenariofresh.ts +0 -244
  447. package/spec-eval/src/scenarios.ts +0 -672
  448. package/spec-eval/src/sessioneval.ts +0 -2220
  449. package/spec-eval/src/sidecar.ts +0 -93
  450. package/spec-eval/src/timeline.ts +0 -54
  451. package/spec-forge/src/__fixtures__/github-forge.json +0 -63
  452. package/spec-forge/src/cache.ts +0 -66
  453. package/spec-forge/src/cli.ts +0 -99
  454. package/spec-forge/src/drivers/github.ts +0 -132
  455. package/spec-forge/src/drivers/gitlab.ts +0 -153
  456. package/spec-forge/src/drivers.ts +0 -73
  457. package/spec-forge/src/links.ts +0 -72
  458. package/spec-forge/src/needs-eval.ts +0 -29
  459. package/spec-forge/src/port.ts +0 -36
  460. package/spec-forge/src/resident.ts +0 -46
  461. /package/{spec-cli → node_modules/@spexcode/spec-cli}/README.md +0 -0
  462. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-0.5.2-eef1.fixture +0 -0
  463. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-sed-v0.fixture +0 -0
  464. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/commit-msg +0 -0
  465. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-checkout +0 -0
  466. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-merge +0 -0
  467. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/pre-commit +0 -0
  468. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/prepare-commit-msg +0 -0
  469. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/reference-transaction +0 -0
  470. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/extract/spec.md +0 -0
  471. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/regroup/spec.md +0 -0
  472. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/rename/spec.md +0 -0
  473. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/spec.md +0 -0
  474. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/tidy/spec.md +0 -0
  475. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/comment-altitude/spec.md +0 -0
  476. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/idle.sh +0 -0
  477. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/spec.md +0 -0
  478. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/mark-active.sh +0 -0
  479. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/spec.md +0 -0
  480. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/fail.sh +0 -0
  481. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/spec.md +0 -0
  482. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec.md +0 -0
  483. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec.md +0 -0
  484. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec.md +0 -0
  485. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +0 -0
  486. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/forge-link/spec.md +0 -0
  487. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +0 -0
  488. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +0 -0
  489. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/spec.md +0 -0
  490. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/digest.mjs +0 -0
  491. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/spec.md +0 -0
  492. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/spec.md +0 -0
  493. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/spec.md +0 -0
  494. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/spec.md +0 -0
  495. /package/{spec-cli → node_modules/@spexcode/spec-core}/templates/spexcode.json +0 -0
@@ -1,396 +0,0 @@
1
- import { execFile, spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'
2
- import { fileURLToPath } from 'node:url'
3
- import { promisify } from 'node:util'
4
- import { alive, withSessionInputLock } from './sessions.js'
5
-
6
- const pexec = promisify(execFile)
7
- const TMUX_SOCK = process.env.SPEXCODE_TMUX || 'spexcode'
8
- const HELPER = fileURLToPath(new URL('./pty-helper.mjs', import.meta.url))
9
-
10
- export type Viewer = {
11
- send: (data: Buffer) => void
12
- commitSize?: (cols: number, rows: number) => void
13
- }
14
-
15
- type Subscription = {
16
- visible: boolean
17
- lingering: boolean
18
- cols: number
19
- rows: number
20
- bridge?: Bridge
21
- lingerTimer?: ReturnType<typeof setTimeout>
22
- restoreTimer?: ReturnType<typeof setTimeout>
23
- startupError?: string
24
- }
25
-
26
- type Bridge = {
27
- id: string
28
- viewer: Viewer
29
- proc: ChildProcessWithoutNullStreams
30
- cols: number
31
- rows: number
32
- ptyPid?: number
33
- stderr: string
34
- clientTty?: string
35
- delivery: 'stream' | 'initial' | 'quarantine'
36
- refreshBuf: Buffer
37
- refreshPending: boolean
38
- refreshRunning: boolean
39
- refreshOffset?: number
40
- deliveryTimer?: ReturnType<typeof setTimeout>
41
- startupError?: string
42
- }
43
-
44
- const subscribers = new Map<string, Map<Viewer, Subscription>>()
45
- const BSU = Buffer.from('\x1b[?2026h')
46
- const ESU = Buffer.from('\x1b[?2026l')
47
- const GEOMETRY_STABILIZATION_MS = 400
48
- // A hidden but still-alive browser keeps its own client briefly so a quick return is continuous. A dead
49
- // socket bypasses this window and detaches immediately.
50
- const LINGER_MS = Number(process.env.SPEXCODE_TERM_LINGER_MS) > 0 ? Number(process.env.SPEXCODE_TERM_LINGER_MS) : 30_000
51
-
52
- function subscriptionMap(id: string): Map<Viewer, Subscription> {
53
- let map = subscribers.get(id)
54
- if (!map) subscribers.set(id, map = new Map())
55
- return map
56
- }
57
-
58
- function currentSubscription(id: string, viewer: Viewer): Subscription | undefined {
59
- return subscribers.get(id)?.get(viewer)
60
- }
61
-
62
- function isCurrent(bridge: Bridge): boolean {
63
- return currentSubscription(bridge.id, bridge.viewer)?.bridge === bridge
64
- }
65
-
66
- function deliver(bridge: Bridge, data: Buffer): void {
67
- const subscription = currentSubscription(bridge.id, bridge.viewer)
68
- if (!subscription || (!subscription.visible && !subscription.lingering)) return
69
- try { bridge.viewer.send(data) } catch { /* socket close or heartbeat expiry owns removal */ }
70
- }
71
-
72
- function commitSize(bridge: Bridge): void {
73
- const subscription = currentSubscription(bridge.id, bridge.viewer)
74
- if (!subscription?.visible) return
75
- try { bridge.viewer.commitSize?.(bridge.cols, bridge.rows) } catch { /* socket close owns removal */ }
76
- }
77
-
78
- async function tmux(args: string[]): Promise<string> {
79
- try {
80
- const { stdout } = await pexec('tmux', ['-L', TMUX_SOCK, ...args])
81
- return stdout.trim()
82
- } catch { return '' }
83
- }
84
-
85
- function onHelperOutput(bridge: Bridge, chunk: Buffer): void {
86
- if (!isCurrent(bridge)) return
87
- if (bridge.delivery === 'stream') {
88
- deliver(bridge, chunk)
89
- return
90
- }
91
- bridge.refreshBuf = bridge.refreshBuf.length ? Buffer.concat([bridge.refreshBuf, chunk]) : chunk
92
- releaseInitialRefresh(bridge)
93
- }
94
-
95
- function sendControl(bridge: Bridge, message: object): void {
96
- try { bridge.proc.stdin.write(`${JSON.stringify(message)}\n`) } catch { /* exit recovery owns retry */ }
97
- }
98
-
99
- function onHelperStderr(bridge: Bridge, chunk: Buffer): void {
100
- bridge.stderr += chunk.toString('utf8')
101
- let newline: number
102
- while ((newline = bridge.stderr.indexOf('\n')) >= 0) {
103
- const line = bridge.stderr.slice(0, newline)
104
- bridge.stderr = bridge.stderr.slice(newline + 1)
105
- const ready = line.match(/^READY (\d+)$/)
106
- if (ready) {
107
- bridge.ptyPid = Number(ready[1])
108
- const subscription = currentSubscription(bridge.id, bridge.viewer)
109
- if (subscription) subscription.startupError = undefined
110
- if (bridge.delivery === 'initial') {
111
- armDeliveryBoundary(bridge)
112
- queueRefresh(bridge)
113
- }
114
- continue
115
- }
116
- const resized = line.match(/^RESIZED (\d+) (\d+)$/)
117
- if (resized) {
118
- if (bridge.delivery === 'initial'
119
- && Number(resized[1]) === bridge.cols
120
- && Number(resized[2]) === bridge.rows) {
121
- queueRefresh(bridge)
122
- }
123
- } else if (line) {
124
- const failed = line.match(/^ERROR (.+)$/)
125
- if (failed) reportStartupError(bridge, failed[1])
126
- console.error(`[terminal helper ${bridge.id}/${bridge.ptyPid ?? 'starting'}] ${line}`)
127
- }
128
- }
129
- }
130
-
131
- function reportStartupError(bridge: Bridge, detail: string): void {
132
- const subscription = currentSubscription(bridge.id, bridge.viewer)
133
- if (!subscription || subscription.bridge !== bridge) return
134
- const message = boundedStartupError(detail)
135
- bridge.startupError = message
136
- if (!message || subscription.startupError === message) return
137
- subscription.startupError = message
138
- deliver(bridge, Buffer.from(`\r\n[SpexCode terminal unavailable] ${message}\r\n`, 'utf8'))
139
- }
140
-
141
- function boundedStartupError(detail: unknown): string {
142
- return (detail instanceof Error ? detail.message : String(detail))
143
- .replace(/[\x00-\x1f\x7f]+/g, ' ').trim().slice(0, 500) || 'native PTY failed to start'
144
- }
145
-
146
- function ensureBridge(id: string, viewer: Viewer, subscription: Subscription, cols: number, rows: number): { bridge: Bridge | null; created: boolean } {
147
- if (subscription.bridge) return { bridge: subscription.bridge, created: false }
148
- let proc: ChildProcessWithoutNullStreams | undefined
149
- try {
150
- proc = spawn(process.execPath, [HELPER, id, String(cols), String(rows)], {
151
- stdio: ['pipe', 'pipe', 'pipe'],
152
- env: process.env,
153
- })
154
- } catch (error) {
155
- try { proc?.kill() } catch { /* spawn did not complete */ }
156
- const detail = boundedStartupError(error)
157
- if (subscription.startupError !== detail) {
158
- subscription.startupError = detail
159
- try { viewer.send(Buffer.from(`\r\n[SpexCode terminal unavailable] ${detail}\r\n`, 'utf8')) } catch { /* socket closed */ }
160
- }
161
- return { bridge: null, created: false }
162
- }
163
- const bridge: Bridge = {
164
- id, viewer, proc, cols, rows, stderr: '', delivery: 'initial',
165
- refreshBuf: Buffer.alloc(0), refreshPending: false, refreshRunning: false,
166
- }
167
- subscription.bridge = bridge
168
- proc.stdout.on('data', (data: Buffer) => onHelperOutput(bridge, data))
169
- proc.stderr.on('data', (data: Buffer) => onHelperStderr(bridge, data))
170
- let reaped = false
171
- const gone = (detail?: string) => {
172
- if (reaped) return
173
- reaped = true
174
- const current = currentSubscription(id, viewer)
175
- if (current?.bridge !== bridge) return
176
- if (!bridge.ptyPid && !bridge.startupError) reportStartupError(bridge, detail || 'helper exited before native PTY startup')
177
- current.bridge = undefined
178
- clearDelivery(bridge)
179
- try { bridge.proc.kill() } catch { /* already gone */ }
180
- scheduleRestore(id, viewer, current)
181
- }
182
- proc.on('exit', (code, signal) => gone(`helper exited before native PTY startup (${signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`})`))
183
- proc.on('error', (error) => gone(`helper process failed: ${error.message}`))
184
- return { bridge, created: true }
185
- }
186
-
187
- function cancelLinger(subscription: Subscription): void {
188
- if (subscription.lingerTimer) clearTimeout(subscription.lingerTimer)
189
- subscription.lingerTimer = undefined
190
- subscription.lingering = false
191
- }
192
-
193
- function cancelRestore(subscription: Subscription): void {
194
- if (subscription.restoreTimer) clearTimeout(subscription.restoreTimer)
195
- subscription.restoreTimer = undefined
196
- }
197
-
198
- function killBridge(subscription: Subscription): void {
199
- cancelLinger(subscription)
200
- cancelRestore(subscription)
201
- const bridge = subscription.bridge
202
- if (!bridge) return
203
- subscription.bridge = undefined
204
- clearDelivery(bridge)
205
- try { bridge.proc.stdin.end() } catch { /* already gone */ }
206
- const kill = setTimeout(() => { try { bridge.proc.kill() } catch { /* already gone */ } }, 250)
207
- kill.unref()
208
- }
209
-
210
- function beginDelivery(bridge: Bridge): void {
211
- if (bridge.delivery === 'stream') bridge.refreshBuf = Buffer.alloc(0)
212
- bridge.delivery = 'initial'
213
- bridge.refreshOffset = undefined
214
- armDeliveryBoundary(bridge)
215
- }
216
-
217
- function armDeliveryBoundary(bridge: Bridge): void {
218
- if (bridge.deliveryTimer) clearTimeout(bridge.deliveryTimer)
219
- bridge.deliveryTimer = setTimeout(() => finishDelivery(bridge), GEOMETRY_STABILIZATION_MS)
220
- bridge.deliveryTimer.unref()
221
- }
222
-
223
- function clearDelivery(bridge: Bridge): void {
224
- bridge.delivery = 'stream'
225
- if (bridge.deliveryTimer) clearTimeout(bridge.deliveryTimer)
226
- bridge.deliveryTimer = undefined
227
- bridge.refreshBuf = Buffer.alloc(0)
228
- bridge.refreshPending = false
229
- bridge.refreshOffset = undefined
230
- }
231
-
232
- function completeTransactionEnd(buffer: Buffer, offset: number): number | undefined {
233
- const begin = buffer.indexOf(BSU, offset)
234
- const end = begin >= 0 ? buffer.indexOf(ESU, begin + BSU.length) : -1
235
- return end >= 0 ? end + ESU.length : undefined
236
- }
237
-
238
- function releaseInitialRefresh(bridge: Bridge): void {
239
- if (bridge.delivery !== 'initial' || bridge.refreshOffset === undefined) return
240
- const end = completeTransactionEnd(bridge.refreshBuf, bridge.refreshOffset)
241
- if (end === undefined) return
242
- const batch = bridge.refreshBuf.subarray(0, end)
243
- bridge.refreshBuf = bridge.refreshBuf.subarray(end)
244
- bridge.delivery = 'quarantine'
245
- commitSize(bridge)
246
- if (batch.length) deliver(bridge, batch)
247
- }
248
-
249
- function finishDelivery(bridge: Bridge): void {
250
- if (bridge.delivery === 'stream' || !isCurrent(bridge)) return
251
- const failOpen = bridge.delivery === 'initial'
252
- const batch = bridge.refreshBuf
253
- clearDelivery(bridge)
254
- if (!failOpen && !batch.length) return
255
- // The control commit and following binary frame are one browser render transaction, including fail-open.
256
- commitSize(bridge)
257
- deliver(bridge, batch)
258
- }
259
-
260
- async function refreshBridge(bridge: Bridge): Promise<boolean> {
261
- if (!isCurrent(bridge) || !bridge.ptyPid) return false
262
- const tty = await clientTty(bridge)
263
- if (!tty) return false
264
- await tmux(['refresh-client', '-t', tty])
265
- return true
266
- }
267
-
268
- function queueRefresh(bridge: Bridge): void {
269
- if (bridge.delivery !== 'initial') return
270
- bridge.refreshPending = true
271
- if (bridge.refreshRunning) return
272
- bridge.refreshPending = false
273
- bridge.refreshRunning = true
274
- void refreshBridge(bridge).then((refreshed) => {
275
- bridge.refreshRunning = false
276
- if (!isCurrent(bridge) || bridge.delivery !== 'initial') return
277
- if (bridge.refreshPending) {
278
- queueRefresh(bridge)
279
- return
280
- }
281
- if (!refreshed) return
282
- bridge.refreshOffset = bridge.refreshBuf.length
283
- releaseInitialRefresh(bridge)
284
- })
285
- }
286
-
287
- async function clientTty(bridge: Bridge): Promise<string | undefined> {
288
- if (bridge.clientTty) return bridge.clientTty
289
- if (!bridge.ptyPid) return undefined
290
- const clients = await tmux(['list-clients', '-t', bridge.id, '-F', '#{client_pid} #{client_tty}'])
291
- for (const line of clients.split('\n')) {
292
- const space = line.indexOf(' ')
293
- if (space > 0 && Number(line.slice(0, space)) === bridge.ptyPid) {
294
- return (bridge.clientTty = line.slice(space + 1).trim())
295
- }
296
- }
297
- return undefined
298
- }
299
-
300
- function resize(bridge: Bridge, cols: number, rows: number): void {
301
- if (bridge.cols === cols && bridge.rows === rows) return
302
- beginDelivery(bridge)
303
- bridge.cols = cols
304
- bridge.rows = rows
305
- sendControl(bridge, { t: 'resize', cols, rows })
306
- }
307
-
308
- export function attachViewer(id: string, viewer: Viewer): void {
309
- const map = subscriptionMap(id)
310
- const previous = map.get(viewer)
311
- if (previous) killBridge(previous)
312
- map.set(viewer, { visible: false, lingering: false, cols: 0, rows: 0 })
313
- }
314
-
315
- export function hideViewer(id: string, viewer: Viewer): void {
316
- const subscription = currentSubscription(id, viewer)
317
- if (!subscription) return
318
- subscription.visible = false
319
- if (!subscription.bridge) return
320
- subscription.lingering = true
321
- if (subscription.lingerTimer) return
322
- subscription.lingerTimer = setTimeout(() => {
323
- subscription.lingerTimer = undefined
324
- if (!subscription.visible && currentSubscription(id, viewer) === subscription) killBridge(subscription)
325
- }, LINGER_MS)
326
- subscription.lingerTimer.unref()
327
- }
328
-
329
- export function detachViewer(id: string, viewer: Viewer): void {
330
- const map = subscribers.get(id)
331
- const subscription = map?.get(viewer)
332
- if (!map || !subscription) return
333
- // A closed/dead socket is not a hidden live tab: remove its native client now, never after linger.
334
- killBridge(subscription)
335
- map.delete(viewer)
336
- if (map.size === 0) subscribers.delete(id)
337
- }
338
-
339
- export function resizeBridge(id: string, viewer: Viewer, colsValue: number, rowsValue: number): void {
340
- const cols = Math.floor(colsValue), rows = Math.floor(rowsValue)
341
- if (!(cols > 0 && rows > 0)) return
342
- const subscription = currentSubscription(id, viewer)
343
- if (!subscription) return
344
- const seamless = subscription.lingering && !!subscription.bridge
345
- && subscription.bridge.cols === cols && subscription.bridge.rows === rows
346
- cancelLinger(subscription)
347
- subscription.visible = true
348
- subscription.cols = cols
349
- subscription.rows = rows
350
- const { bridge, created } = ensureBridge(id, viewer, subscription, cols, rows)
351
- if (!bridge || created || seamless) return
352
- if (bridge.cols === cols && bridge.rows === rows) {
353
- beginDelivery(bridge)
354
- queueRefresh(bridge)
355
- } else {
356
- resize(bridge, cols, rows)
357
- }
358
- }
359
-
360
- const MAX_INPUT_BYTES = 64 * 1024
361
-
362
- export function forwardInput(id: string, viewer: Viewer, data: string): boolean {
363
- const subscription = currentSubscription(id, viewer)
364
- if (!subscription?.visible || !subscription.bridge || !data || Buffer.byteLength(data, 'utf8') > MAX_INPUT_BYTES) return false
365
- return withSessionInputLock(id, () => {
366
- sendControl(subscription.bridge!, { t: 'input', data })
367
- return true
368
- }) ?? false
369
- }
370
-
371
- async function restoreBridge(id: string, viewer: Viewer, subscription: Subscription): Promise<void> {
372
- subscription.restoreTimer = undefined
373
- if (currentSubscription(id, viewer) !== subscription || subscription.bridge || !subscription.visible || !(await alive(id))) return
374
- if (!(subscription.cols > 0 && subscription.rows > 0)) return
375
- ensureBridge(id, viewer, subscription, subscription.cols, subscription.rows)
376
- }
377
-
378
- function scheduleRestore(id: string, viewer: Viewer, subscription: Subscription): void {
379
- if (currentSubscription(id, viewer) !== subscription || !subscription.visible || subscription.bridge || subscription.restoreTimer) return
380
- subscription.restoreTimer = setTimeout(() => void restoreBridge(id, viewer, subscription), 750)
381
- subscription.restoreTimer.unref()
382
- }
383
-
384
- let supervising = false
385
- export function superviseBridges(intervalMs = 4000): void {
386
- if (supervising) return
387
- supervising = true
388
- const tick = () => {
389
- for (const [id, viewers] of subscribers) {
390
- for (const [viewer, subscription] of viewers) scheduleRestore(id, viewer, subscription)
391
- }
392
- const timer = setTimeout(tick, intervalMs)
393
- timer.unref()
394
- }
395
- tick()
396
- }
@@ -1,96 +0,0 @@
1
- import * as pty from 'node-pty'
2
- import { execFileSync } from 'node:child_process'
3
- import { ensureExecutableIfPresent, nodePtySpawnHelperPath } from './pty-native-helper.mjs'
4
-
5
- const [id, colsArg, rowsArg] = process.argv.slice(2)
6
- const cols = Number(colsArg)
7
- const rows = Number(rowsArg)
8
- const socket = process.env.SPEXCODE_TMUX || 'spexcode'
9
-
10
- if (!id || !(cols > 0 && rows > 0)) {
11
- process.stderr.write('ERROR invalid helper arguments\n')
12
- process.exit(2)
13
- }
14
-
15
- // Establish the outer-terminal contract before this process owns a PTY. tmux must preserve hyperlinks and
16
- // wrap client updates in DEC 2026 for xterm 6; doing the setup before forkpty preserves helper isolation.
17
- try {
18
- // The dashboard renders the pane, not tmux's client chrome. Keeping this as a tmux session option makes
19
- // the requested PTY grid the pane grid too; filtering a coloured final row in xterm would corrupt real
20
- // pane content. SpexCode owns these sessions, so a later foreground attach sees the same status-free pane.
21
- execFileSync('tmux', ['-L', socket, 'set-option', '-t', id, 'status', 'off'])
22
- // Control follows the person actually driving: `latest` sizes the window to the most recently
23
- // active client, so a small screen takes the grid the moment its user interacts and sees the WHOLE
24
- // pane, while an idle larger viewer letterboxes. `largest` optimized the big display's real estate
25
- // but left a small concurrent viewer a cropped corner it could never take back.
26
- execFileSync('tmux', ['-L', socket, 'set-window-option', '-t', id, 'window-size', 'latest'])
27
- execFileSync('tmux', ['-L', socket, 'set-option', '-g', 'mouse', 'on'])
28
- execFileSync('tmux', ['-L', socket, 'set-option', '-g', 'history-limit', '50000'])
29
- // Wheel routing stays tmux-default: copy-mode history for a plain pane, pass-through to a
30
- // mouse-owning TUI. Claude's TUI virtual-scrolls its own transcript on those reports (it lives on
31
- // the alternate screen and repaints in place, so tmux history cannot substitute — an in-place
32
- // renderer never scrolls lines off the top). Restore the default bindings idempotently in case an
33
- // earlier release rebound them server-wide; the unbind may already be clean, so it fails quietly.
34
- execFileSync('tmux', ['-L', socket, 'bind-key', '-n', 'WheelUpPane', 'if', '-F', '-t=', '#{||:#{pane_in_mode},#{mouse_any_flag}}', 'send-keys -M', 'copy-mode -et='])
35
- try { execFileSync('tmux', ['-L', socket, 'unbind-key', '-n', 'WheelDownPane']) } catch { /* already unbound */ }
36
- const features = execFileSync('tmux', ['-L', socket, 'show-options', '-gsv', 'terminal-features'], { encoding: 'utf8' })
37
- const xtermFeatures = new Set(features.split('\n').filter((line) => line.startsWith('xterm*:')).flatMap((line) => line.split(':').slice(1)))
38
- const missing = ['sync', 'hyperlinks'].filter((feature) => !xtermFeatures.has(feature))
39
- if (missing.length) {
40
- execFileSync('tmux', ['-L', socket, 'set-option', '-as', 'terminal-features', `,xterm*:${missing.join(':')}`])
41
- }
42
- } catch { /* attach below fails loudly if the tmux server/session is unavailable */ }
43
-
44
- let terminal
45
- try {
46
- ensureExecutableIfPresent(nodePtySpawnHelperPath(pty.native))
47
- terminal = pty.spawn('tmux', ['-u', '-L', socket, 'attach-session', '-t', id], {
48
- name: 'xterm-256color',
49
- cols,
50
- rows,
51
- env: { ...process.env, LANG: process.env.LANG || 'en_US.UTF-8' },
52
- })
53
- } catch (error) {
54
- const detail = (error instanceof Error ? error.message : String(error))
55
- .replace(/[\x00-\x1f\x7f]+/g, ' ').trim().slice(0, 500)
56
- process.stderr.write(`ERROR ${detail || 'native PTY failed to start'}\n`)
57
- process.exit(1)
58
- }
59
-
60
- terminal.onData((data) => process.stdout.write(Buffer.from(data, 'utf8')))
61
- terminal.onExit(({ exitCode }) => process.exit(exitCode === 0 ? 0 : 1))
62
- process.stderr.write(`READY ${terminal.pid}\n`)
63
-
64
- let input = ''
65
- process.stdin.setEncoding('utf8')
66
- process.stdin.on('data', (chunk) => {
67
- input += chunk
68
- let newline
69
- while ((newline = input.indexOf('\n')) >= 0) {
70
- const line = input.slice(0, newline)
71
- input = input.slice(newline + 1)
72
- if (!line) continue
73
- try {
74
- const message = JSON.parse(line)
75
- if (message?.t === 'resize' && message.cols > 0 && message.rows > 0) {
76
- const nextCols = Math.floor(message.cols)
77
- const nextRows = Math.floor(message.rows)
78
- terminal.resize(nextCols, nextRows)
79
- process.stderr.write(`RESIZED ${nextCols} ${nextRows}\n`)
80
- } else if (message?.t === 'input' && typeof message.data === 'string' && Buffer.byteLength(message.data, 'utf8') <= 64 * 1024) {
81
- terminal.write(message.data)
82
- }
83
- } catch { /* malformed controls cannot become terminal input */ }
84
- }
85
- })
86
-
87
- let closing = false
88
- function close() {
89
- if (closing) return
90
- closing = true
91
- try { terminal.kill() } catch { /* already gone */ }
92
- setTimeout(() => process.exit(0), 100).unref()
93
- }
94
- process.stdin.on('end', close)
95
- process.on('SIGTERM', close)
96
- process.on('SIGINT', close)
@@ -1,22 +0,0 @@
1
- import { chmodSync, statSync } from 'node:fs'
2
- import { createRequire } from 'node:module'
3
- import { dirname, join } from 'node:path'
4
-
5
- const require = createRequire(import.meta.url)
6
-
7
- export function nodePtySpawnHelperPath(nativeModule) {
8
- const nativeAddon = Object.values(require.cache).find((loaded) => loaded?.exports === nativeModule)?.filename
9
- if (!nativeAddon) throw new Error('cannot locate node-pty loaded native addon')
10
- return join(dirname(nativeAddon), 'spawn-helper')
11
- }
12
-
13
- export function ensureExecutableIfPresent(path) {
14
- let mode
15
- try {
16
- mode = statSync(path).mode & 0o777
17
- } catch (error) {
18
- if (error?.code === 'ENOENT') return
19
- throw error
20
- }
21
- if ((mode & 0o111) !== 0o111) chmodSync(path, mode | 0o111)
22
- }