@neuralnomads/codenomad-dev 0.10.3-dev-20260213-ba418a85

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 (462) hide show
  1. package/README.md +126 -0
  2. package/dist/api-types.js +1 -0
  3. package/dist/auth/auth-store.js +134 -0
  4. package/dist/auth/http-auth.js +37 -0
  5. package/dist/auth/manager.js +128 -0
  6. package/dist/auth/password-hash.js +32 -0
  7. package/dist/auth/session-manager.js +17 -0
  8. package/dist/auth/token-manager.js +27 -0
  9. package/dist/background-processes/manager.js +437 -0
  10. package/dist/bin.js +24 -0
  11. package/dist/config/binaries.js +148 -0
  12. package/dist/config/location.js +57 -0
  13. package/dist/config/schema.js +70 -0
  14. package/dist/config/store.js +200 -0
  15. package/dist/events/bus.js +41 -0
  16. package/dist/filesystem/__tests__/search-cache.test.js +40 -0
  17. package/dist/filesystem/browser.js +285 -0
  18. package/dist/filesystem/search-cache.js +43 -0
  19. package/dist/filesystem/search.js +135 -0
  20. package/dist/index.js +410 -0
  21. package/dist/integrations/github/bot-signature.js +11 -0
  22. package/dist/integrations/github/git-ops.js +133 -0
  23. package/dist/integrations/github/github-types.js +1 -0
  24. package/dist/integrations/github/job-runner.js +608 -0
  25. package/dist/integrations/github/octokit.js +58 -0
  26. package/dist/integrations/github/sanitize-webhook.js +42 -0
  27. package/dist/integrations/github/webhook-verify.js +21 -0
  28. package/dist/integrations/github/workspace-context.js +10 -0
  29. package/dist/integrations/github/worktree-context.js +15 -0
  30. package/dist/launcher.js +149 -0
  31. package/dist/loader.js +21 -0
  32. package/dist/logger.js +109 -0
  33. package/dist/opencode/request-context.js +39 -0
  34. package/dist/opencode/worktree-directory.js +42 -0
  35. package/dist/opencode-config/README.md +32 -0
  36. package/dist/opencode-config/opencode.jsonc +3 -0
  37. package/dist/opencode-config/package.json +9 -0
  38. package/dist/opencode-config/plugin/codenomad.ts +32 -0
  39. package/dist/opencode-config/plugin/lib/background-process.ts +253 -0
  40. package/dist/opencode-config/plugin/lib/client.ts +133 -0
  41. package/dist/opencode-config/plugin/lib/request.ts +214 -0
  42. package/dist/opencode-config-template/README.md +32 -0
  43. package/dist/opencode-config-template/opencode.jsonc +3 -0
  44. package/dist/opencode-config-template/plugin/codenomad.ts +40 -0
  45. package/dist/opencode-config-template/plugin/lib/background-process.ts +160 -0
  46. package/dist/opencode-config-template/plugin/lib/client.ts +165 -0
  47. package/dist/opencode-config.js +26 -0
  48. package/dist/plugins/channel.js +40 -0
  49. package/dist/plugins/handlers.js +17 -0
  50. package/dist/releases/dev-release-monitor.js +75 -0
  51. package/dist/releases/release-monitor.js +107 -0
  52. package/dist/server/http-server.js +547 -0
  53. package/dist/server/network-addresses.js +72 -0
  54. package/dist/server/routes/auth-pages/login.html +134 -0
  55. package/dist/server/routes/auth-pages/token.html +93 -0
  56. package/dist/server/routes/auth.js +134 -0
  57. package/dist/server/routes/background-processes.js +60 -0
  58. package/dist/server/routes/config.js +59 -0
  59. package/dist/server/routes/events.js +43 -0
  60. package/dist/server/routes/filesystem.js +43 -0
  61. package/dist/server/routes/github-plugin.js +215 -0
  62. package/dist/server/routes/github-webhook.js +32 -0
  63. package/dist/server/routes/meta.js +47 -0
  64. package/dist/server/routes/plugin.js +52 -0
  65. package/dist/server/routes/storage.js +52 -0
  66. package/dist/server/routes/workspaces.js +89 -0
  67. package/dist/server/routes/worktrees.js +156 -0
  68. package/dist/server/tls.js +224 -0
  69. package/dist/storage/instance-store.js +56 -0
  70. package/dist/ui/__tests__/remote-ui.test.js +46 -0
  71. package/dist/ui/remote-ui.js +462 -0
  72. package/dist/workspaces/git-worktrees.js +199 -0
  73. package/dist/workspaces/instance-events.js +180 -0
  74. package/dist/workspaces/manager.js +375 -0
  75. package/dist/workspaces/opencode-auth.js +16 -0
  76. package/dist/workspaces/runtime.js +346 -0
  77. package/dist/workspaces/worktree-map.js +116 -0
  78. package/package.json +49 -0
  79. package/public/apple-touch-icon-180x180.png +0 -0
  80. package/public/assets/CodeNomad-Icon-bmTWNPXy.png +0 -0
  81. package/public/assets/abap-BdImnpbu.js +1 -0
  82. package/public/assets/actionscript-3-CfeIJUat.js +1 -0
  83. package/public/assets/ada-bCR0ucgS.js +1 -0
  84. package/public/assets/andromeeda-C-Jbm3Hp.js +1 -0
  85. package/public/assets/angular-html-CU67Zn6k.js +1 -0
  86. package/public/assets/angular-ts-BwZT4LLn.js +1 -0
  87. package/public/assets/apache-Pmp26Uib.js +1 -0
  88. package/public/assets/apex-DhZLUxFE.js +1 -0
  89. package/public/assets/apl-dKokRX4l.js +1 -0
  90. package/public/assets/applescript-Co6uUVPk.js +1 -0
  91. package/public/assets/ara-BRHolxvo.js +1 -0
  92. package/public/assets/asciidoc-Dv7Oe6Be.js +1 -0
  93. package/public/assets/asm-D_Q5rh1f.js +1 -0
  94. package/public/assets/astro-CbQHKStN.js +1 -0
  95. package/public/assets/aurora-x-D-2ljcwZ.js +1 -0
  96. package/public/assets/awk-DMzUqQB5.js +1 -0
  97. package/public/assets/ayu-dark-Cv9koXgw.js +1 -0
  98. package/public/assets/ballerina-BFfxhgS-.js +1 -0
  99. package/public/assets/bat-BkioyH1T.js +1 -0
  100. package/public/assets/beancount-k_qm7-4y.js +1 -0
  101. package/public/assets/berry-D08WgyRC.js +1 -0
  102. package/public/assets/bibtex-CHM0blh-.js +1 -0
  103. package/public/assets/bicep-Bmn6On1c.js +1 -0
  104. package/public/assets/blade-DVc8C-J4.js +1 -0
  105. package/public/assets/bsl-BO_Y6i37.js +1 -0
  106. package/public/assets/c-BIGW1oBm.js +1 -0
  107. package/public/assets/cadence-Bv_4Rxtq.js +1 -0
  108. package/public/assets/cairo-KRGpt6FW.js +1 -0
  109. package/public/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  110. package/public/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  111. package/public/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  112. package/public/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  113. package/public/assets/clarity-D53aC0YG.js +1 -0
  114. package/public/assets/clojure-P80f7IUj.js +1 -0
  115. package/public/assets/cmake-D1j8_8rp.js +1 -0
  116. package/public/assets/cobol-nwyudZeR.js +1 -0
  117. package/public/assets/codeowners-Bp6g37R7.js +1 -0
  118. package/public/assets/codeql-DsOJ9woJ.js +1 -0
  119. package/public/assets/coffee-Ch7k5sss.js +1 -0
  120. package/public/assets/common-lisp-Cg-RD9OK.js +1 -0
  121. package/public/assets/coq-DkFqJrB1.js +1 -0
  122. package/public/assets/core-BSTVzpXI.js +1 -0
  123. package/public/assets/cpp-CofmeUqb.js +1 -0
  124. package/public/assets/crystal-tKQVLTB8.js +1 -0
  125. package/public/assets/csharp-CX12Zw3r.js +1 -0
  126. package/public/assets/css-DPfMkruS.js +1 -0
  127. package/public/assets/csv-fuZLfV_i.js +1 -0
  128. package/public/assets/cue-D82EKSYY.js +1 -0
  129. package/public/assets/cypher-COkxafJQ.js +1 -0
  130. package/public/assets/d-85-TOEBH.js +1 -0
  131. package/public/assets/dark-plus-eOWES_5F.js +1 -0
  132. package/public/assets/dart-CF10PKvl.js +1 -0
  133. package/public/assets/dax-CEL-wOlO.js +1 -0
  134. package/public/assets/desktop-BmXAJ9_W.js +1 -0
  135. package/public/assets/diff-D97Zzqfu.js +1 -0
  136. package/public/assets/docker-BcOcwvcX.js +1 -0
  137. package/public/assets/dotenv-Da5cRb03.js +1 -0
  138. package/public/assets/dracula-BzJJZx-M.js +1 -0
  139. package/public/assets/dracula-soft-BXkSAIEj.js +1 -0
  140. package/public/assets/dream-maker-BtqSS_iP.js +1 -0
  141. package/public/assets/edge-BkV0erSs.js +1 -0
  142. package/public/assets/elixir-CDX3lj18.js +1 -0
  143. package/public/assets/elm-DbKCFpqz.js +1 -0
  144. package/public/assets/emacs-lisp-C9XAeP06.js +1 -0
  145. package/public/assets/erb-BOJIQeun.js +1 -0
  146. package/public/assets/erlang-DsQrWhSR.js +1 -0
  147. package/public/assets/everforest-dark-BgDCqdQA.js +1 -0
  148. package/public/assets/everforest-light-C8M2exoo.js +1 -0
  149. package/public/assets/fennel-BYunw83y.js +1 -0
  150. package/public/assets/fish-BvzEVeQv.js +1 -0
  151. package/public/assets/fluent-C4IJs8-o.js +1 -0
  152. package/public/assets/fortran-fixed-form-BZjJHVRy.js +1 -0
  153. package/public/assets/fortran-free-form-D22FLkUw.js +1 -0
  154. package/public/assets/fsharp-CXgrBDvD.js +1 -0
  155. package/public/assets/gdresource-B7Tvp0Sc.js +1 -0
  156. package/public/assets/gdscript-DTMYz4Jt.js +1 -0
  157. package/public/assets/gdshader-DkwncUOv.js +1 -0
  158. package/public/assets/genie-D0YGMca9.js +1 -0
  159. package/public/assets/gherkin-DyxjwDmM.js +1 -0
  160. package/public/assets/git-commit-F4YmCXRG.js +1 -0
  161. package/public/assets/git-rebase-r7XF79zn.js +1 -0
  162. package/public/assets/github-dark-DHJKELXO.js +1 -0
  163. package/public/assets/github-dark-default-Cuk6v7N8.js +1 -0
  164. package/public/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  165. package/public/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  166. package/public/assets/github-light-DAi9KRSo.js +1 -0
  167. package/public/assets/github-light-default-D7oLnXFd.js +1 -0
  168. package/public/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  169. package/public/assets/gleam-BspZqrRM.js +1 -0
  170. package/public/assets/glimmer-js-Rg0-pVw9.js +1 -0
  171. package/public/assets/glimmer-ts-U6CK756n.js +1 -0
  172. package/public/assets/glsl-DplSGwfg.js +1 -0
  173. package/public/assets/gnuplot-DdkO51Og.js +1 -0
  174. package/public/assets/go-Dn2_MT6a.js +1 -0
  175. package/public/assets/graphql-ChdNCCLP.js +1 -0
  176. package/public/assets/groovy-gcz8RCvz.js +1 -0
  177. package/public/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  178. package/public/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  179. package/public/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  180. package/public/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  181. package/public/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  182. package/public/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  183. package/public/assets/hack-CaT9iCJl.js +1 -0
  184. package/public/assets/haml-B8DHNrY2.js +1 -0
  185. package/public/assets/handlebars-BL8al0AC.js +1 -0
  186. package/public/assets/haskell-Df6bDoY_.js +1 -0
  187. package/public/assets/haxe-CzTSHFRz.js +1 -0
  188. package/public/assets/hcl-BWvSN4gD.js +1 -0
  189. package/public/assets/hjson-D5-asLiD.js +1 -0
  190. package/public/assets/hlsl-D3lLCCz7.js +1 -0
  191. package/public/assets/houston-DnULxvSX.js +1 -0
  192. package/public/assets/html-GMplVEZG.js +1 -0
  193. package/public/assets/html-derivative-BFtXZ54Q.js +1 -0
  194. package/public/assets/http-jrhK8wxY.js +1 -0
  195. package/public/assets/hurl-irOxFIW8.js +1 -0
  196. package/public/assets/hxml-Bvhsp5Yf.js +1 -0
  197. package/public/assets/hy-DFXneXwc.js +1 -0
  198. package/public/assets/imba-DGztddWO.js +1 -0
  199. package/public/assets/index-D4PT0yE4.js +1 -0
  200. package/public/assets/index-DN20ggb1.js +1 -0
  201. package/public/assets/index-DdQ7zIzB.js +1 -0
  202. package/public/assets/index-Dl-rJJuP.js +1 -0
  203. package/public/assets/index-Dlo2gDiy.css +1 -0
  204. package/public/assets/ini-BEwlwnbL.js +1 -0
  205. package/public/assets/java-CylS5w8V.js +1 -0
  206. package/public/assets/javascript-wDzz0qaB.js +1 -0
  207. package/public/assets/jinja-4LBKfQ-Z.js +1 -0
  208. package/public/assets/jison-wvAkD_A8.js +1 -0
  209. package/public/assets/json-Cp-IABpG.js +1 -0
  210. package/public/assets/json5-C9tS-k6U.js +1 -0
  211. package/public/assets/jsonc-Des-eS-w.js +1 -0
  212. package/public/assets/jsonl-DcaNXYhu.js +1 -0
  213. package/public/assets/jsonnet-DFQXde-d.js +1 -0
  214. package/public/assets/jssm-C2t-YnRu.js +1 -0
  215. package/public/assets/jsx-g9-lgVsj.js +1 -0
  216. package/public/assets/julia-C8NyazO9.js +1 -0
  217. package/public/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  218. package/public/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  219. package/public/assets/kanagawa-wave-DWedfzmr.js +1 -0
  220. package/public/assets/kdl-DV7GczEv.js +1 -0
  221. package/public/assets/kotlin-BdnUsdx6.js +1 -0
  222. package/public/assets/kusto-BvAqAH-y.js +1 -0
  223. package/public/assets/laserwave-DUszq2jm.js +1 -0
  224. package/public/assets/latex-BUKiar2Z.js +1 -0
  225. package/public/assets/lean-DP1Csr6i.js +1 -0
  226. package/public/assets/less-B1dDrJ26.js +1 -0
  227. package/public/assets/light-plus-B7mTdjB0.js +1 -0
  228. package/public/assets/liquid-DYVedYrR.js +1 -0
  229. package/public/assets/llvm-BtvRca6l.js +1 -0
  230. package/public/assets/loading-CmEVQgyj.css +1 -0
  231. package/public/assets/loading-DgqIiz-T.js +1 -0
  232. package/public/assets/log-2UxHyX5q.js +1 -0
  233. package/public/assets/logo-BtOb2qkB.js +1 -0
  234. package/public/assets/lua-BbnMAYS6.js +1 -0
  235. package/public/assets/luau-CXu1NL6O.js +1 -0
  236. package/public/assets/main-CSlDZj4f.js +188 -0
  237. package/public/assets/main-HAZkIolJ.css +19 -0
  238. package/public/assets/make-CHLpvVh8.js +1 -0
  239. package/public/assets/markdown-Cvjx9yec.js +1 -0
  240. package/public/assets/marko-CPi9NSCl.js +1 -0
  241. package/public/assets/material-theme-D5KoaKCx.js +1 -0
  242. package/public/assets/material-theme-darker-BfHTSMKl.js +1 -0
  243. package/public/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  244. package/public/assets/material-theme-ocean-CyktbL80.js +1 -0
  245. package/public/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  246. package/public/assets/matlab-D7o27uSR.js +1 -0
  247. package/public/assets/mdc-DUICxH0z.js +1 -0
  248. package/public/assets/mdx-Cmh6b_Ma.js +1 -0
  249. package/public/assets/mermaid-DKYwYmdq.js +1 -0
  250. package/public/assets/min-dark-CafNBF8u.js +1 -0
  251. package/public/assets/min-light-CTRr51gU.js +1 -0
  252. package/public/assets/mipsasm-CKIfxQSi.js +1 -0
  253. package/public/assets/mojo-1DNp92w6.js +1 -0
  254. package/public/assets/monokai-D4h5O-jR.js +1 -0
  255. package/public/assets/move-Bu9oaDYs.js +1 -0
  256. package/public/assets/narrat-DRg8JJMk.js +1 -0
  257. package/public/assets/nextflow-CUEJCptM.js +1 -0
  258. package/public/assets/nginx-DknmC5AR.js +1 -0
  259. package/public/assets/night-owl-C39BiMTA.js +1 -0
  260. package/public/assets/nim-CVrawwO9.js +1 -0
  261. package/public/assets/nix-BbRYJGeE.js +1 -0
  262. package/public/assets/nord-Ddv68eIx.js +1 -0
  263. package/public/assets/nushell-C-sUppwS.js +1 -0
  264. package/public/assets/objective-c-DXmwc3jG.js +1 -0
  265. package/public/assets/objective-cpp-CLxacb5B.js +1 -0
  266. package/public/assets/ocaml-C0hk2d4L.js +1 -0
  267. package/public/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  268. package/public/assets/one-light-PoHY5YXO.js +1 -0
  269. package/public/assets/pascal-D93ZcfNL.js +1 -0
  270. package/public/assets/perl-C0TMdlhV.js +1 -0
  271. package/public/assets/php-CDn_0X-4.js +1 -0
  272. package/public/assets/pkl-u5AG7uiY.js +1 -0
  273. package/public/assets/plastic-3e1v2bzS.js +1 -0
  274. package/public/assets/plsql-ChMvpjG-.js +1 -0
  275. package/public/assets/po-BTJTHyun.js +1 -0
  276. package/public/assets/poimandres-CS3Unz2-.js +1 -0
  277. package/public/assets/polar-C0HS_06l.js +1 -0
  278. package/public/assets/postcss-CXtECtnM.js +1 -0
  279. package/public/assets/powerquery-CEu0bR-o.js +1 -0
  280. package/public/assets/powershell-Dpen1YoG.js +1 -0
  281. package/public/assets/prisma-Dd19v3D-.js +1 -0
  282. package/public/assets/prolog-CbFg5uaA.js +1 -0
  283. package/public/assets/proto-DyJlTyXw.js +1 -0
  284. package/public/assets/pug-CGlum2m_.js +1 -0
  285. package/public/assets/puppet-BMWR74SV.js +1 -0
  286. package/public/assets/purescript-CklMAg4u.js +1 -0
  287. package/public/assets/python-B6aJPvgy.js +1 -0
  288. package/public/assets/qml-3beO22l8.js +1 -0
  289. package/public/assets/qmldir-C8lEn-DE.js +1 -0
  290. package/public/assets/qss-IeuSbFQv.js +1 -0
  291. package/public/assets/r-DiinP2Uv.js +1 -0
  292. package/public/assets/racket-BqYA7rlc.js +1 -0
  293. package/public/assets/raku-DXvB9xmW.js +1 -0
  294. package/public/assets/razor-WgofotgN.js +1 -0
  295. package/public/assets/red-bN70gL4F.js +1 -0
  296. package/public/assets/reg-C-SQnVFl.js +1 -0
  297. package/public/assets/regexp-CDVJQ6XC.js +1 -0
  298. package/public/assets/rel-C3B-1QV4.js +1 -0
  299. package/public/assets/riscv-BM1_JUlF.js +1 -0
  300. package/public/assets/rose-pine-BHrmToEH.js +1 -0
  301. package/public/assets/rose-pine-dawn-CnK8MTSM.js +1 -0
  302. package/public/assets/rose-pine-moon-NleAzG8P.js +1 -0
  303. package/public/assets/rosmsg-BJDFO7_C.js +1 -0
  304. package/public/assets/rst-B0xPkSld.js +1 -0
  305. package/public/assets/ruby-BvKwtOVI.js +1 -0
  306. package/public/assets/rust-B1yitclQ.js +1 -0
  307. package/public/assets/sas-cz2c8ADy.js +1 -0
  308. package/public/assets/sass-Cj5Yp3dK.js +1 -0
  309. package/public/assets/scala-C151Ov-r.js +1 -0
  310. package/public/assets/scheme-C98Dy4si.js +1 -0
  311. package/public/assets/scss-OYdSNvt2.js +1 -0
  312. package/public/assets/sdbl-DVxCFoDh.js +1 -0
  313. package/public/assets/shaderlab-Dg9Lc6iA.js +1 -0
  314. package/public/assets/shellscript-Yzrsuije.js +1 -0
  315. package/public/assets/shellsession-BADoaaVG.js +1 -0
  316. package/public/assets/slack-dark-BthQWCQV.js +1 -0
  317. package/public/assets/slack-ochin-DqwNpetd.js +1 -0
  318. package/public/assets/smalltalk-BERRCDM3.js +1 -0
  319. package/public/assets/snazzy-light-Bw305WKR.js +1 -0
  320. package/public/assets/solarized-dark-DXbdFlpD.js +1 -0
  321. package/public/assets/solarized-light-L9t79GZl.js +1 -0
  322. package/public/assets/solidity-BbcW6ACK.js +1 -0
  323. package/public/assets/soy-Brmx7dQM.js +1 -0
  324. package/public/assets/sparql-rVzFXLq3.js +1 -0
  325. package/public/assets/splunk-BtCnVYZw.js +1 -0
  326. package/public/assets/sql-BLtJtn59.js +1 -0
  327. package/public/assets/ssh-config-_ykCGR6B.js +1 -0
  328. package/public/assets/stata-BH5u7GGu.js +1 -0
  329. package/public/assets/stylus-BEDo0Tqx.js +1 -0
  330. package/public/assets/svelte-3Dk4HxPD.js +1 -0
  331. package/public/assets/swift-Dg5xB15N.js +1 -0
  332. package/public/assets/synthwave-84-CbfX1IO0.js +1 -0
  333. package/public/assets/system-verilog-CnnmHF94.js +1 -0
  334. package/public/assets/systemd-4A_iFExJ.js +1 -0
  335. package/public/assets/talonscript-CkByrt1z.js +1 -0
  336. package/public/assets/tasl-QIJgUcNo.js +1 -0
  337. package/public/assets/tcl-dwOrl1Do.js +1 -0
  338. package/public/assets/templ-W15q3VgB.js +1 -0
  339. package/public/assets/terraform-BETggiCN.js +1 -0
  340. package/public/assets/tex-Cppo0RY3.js +1 -0
  341. package/public/assets/tokyo-night-hegEt444.js +1 -0
  342. package/public/assets/toml-vGWfd6FD.js +1 -0
  343. package/public/assets/ts-tags-zn1MmPIZ.js +1 -0
  344. package/public/assets/tsv-B_m7g4N7.js +1 -0
  345. package/public/assets/tsx-COt5Ahok.js +1 -0
  346. package/public/assets/turtle-BsS91CYL.js +1 -0
  347. package/public/assets/twig-CO9l9SDP.js +1 -0
  348. package/public/assets/typescript-BPQ3VLAy.js +1 -0
  349. package/public/assets/typespec-Df68jz8_.js +1 -0
  350. package/public/assets/typst-DHCkPAjA.js +1 -0
  351. package/public/assets/v-BcVCzyr7.js +1 -0
  352. package/public/assets/vala-CsfeWuGM.js +1 -0
  353. package/public/assets/vb-D17OF-Vu.js +1 -0
  354. package/public/assets/verilog-BQ8w6xss.js +1 -0
  355. package/public/assets/vesper-DU1UobuO.js +1 -0
  356. package/public/assets/vhdl-CeAyd5Ju.js +1 -0
  357. package/public/assets/viml-CJc9bBzg.js +1 -0
  358. package/public/assets/vitesse-black-Bkuqu6BP.js +1 -0
  359. package/public/assets/vitesse-dark-D0r3Knsf.js +1 -0
  360. package/public/assets/vitesse-light-CVO1_9PV.js +1 -0
  361. package/public/assets/vue-CCoi5OLL.js +1 -0
  362. package/public/assets/vue-html-DAAvJJDi.js +1 -0
  363. package/public/assets/vue-vine-_Ih-lPRR.js +1 -0
  364. package/public/assets/vyper-CDx5xZoG.js +1 -0
  365. package/public/assets/wasm-CG6Dc4jp.js +1 -0
  366. package/public/assets/wasm-MzD3tlZU.js +1 -0
  367. package/public/assets/wenyan-BV7otONQ.js +1 -0
  368. package/public/assets/wgsl-Dx-B1_4e.js +1 -0
  369. package/public/assets/wikitext-BhOHFoWU.js +1 -0
  370. package/public/assets/wit-5i3qLPDT.js +1 -0
  371. package/public/assets/wolfram-lXgVvXCa.js +1 -0
  372. package/public/assets/xml-sdJ4AIDG.js +1 -0
  373. package/public/assets/xsl-CtQFsRM5.js +1 -0
  374. package/public/assets/yaml-Buea-lGh.js +1 -0
  375. package/public/assets/zenscript-DVFEvuxE.js +1 -0
  376. package/public/assets/zig-VOosw3JB.js +1 -0
  377. package/public/favicon.ico +0 -0
  378. package/public/index.html +38 -0
  379. package/public/loading.html +28 -0
  380. package/public/logo.png +0 -0
  381. package/public/manifest.webmanifest +1 -0
  382. package/public/maskable-icon-512x512.png +0 -0
  383. package/public/monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
  384. package/public/monaco/vs/base/worker/workerMain.js +31 -0
  385. package/public/monaco/vs/basic-languages/cpp/cpp.js +10 -0
  386. package/public/monaco/vs/basic-languages/kotlin/kotlin.js +10 -0
  387. package/public/monaco/vs/basic-languages/markdown/markdown.js +10 -0
  388. package/public/monaco/vs/basic-languages/python/python.js +10 -0
  389. package/public/monaco/vs/editor/editor.main.css +8 -0
  390. package/public/monaco/vs/editor/editor.main.js +798 -0
  391. package/public/monaco/vs/language/css/cssMode.js +13 -0
  392. package/public/monaco/vs/language/css/cssWorker.js +77 -0
  393. package/public/monaco/vs/language/html/htmlMode.js +13 -0
  394. package/public/monaco/vs/language/html/htmlWorker.js +454 -0
  395. package/public/monaco/vs/language/json/jsonMode.js +19 -0
  396. package/public/monaco/vs/language/json/jsonWorker.js +42 -0
  397. package/public/monaco/vs/language/typescript/tsMode.js +20 -0
  398. package/public/monaco/vs/language/typescript/tsWorker.js +51328 -0
  399. package/public/monaco/vs/loader.js +11 -0
  400. package/public/monaco.worker.js +7 -0
  401. package/public/pwa-192x192.png +0 -0
  402. package/public/pwa-512x512.png +0 -0
  403. package/public/pwa-64x64.png +0 -0
  404. package/public/registerSW.js +1 -0
  405. package/public/sw.js +1 -0
  406. package/public/ui-version.json +3 -0
  407. package/public/workbox-60d14903.js +1 -0
  408. package/scripts/copy-auth-pages.mjs +22 -0
  409. package/scripts/copy-opencode-config.mjs +61 -0
  410. package/scripts/copy-ui-dist.mjs +21 -0
  411. package/src/api-types.ts +326 -0
  412. package/src/auth/auth-store.ts +175 -0
  413. package/src/auth/http-auth.ts +38 -0
  414. package/src/auth/manager.ts +163 -0
  415. package/src/auth/password-hash.ts +49 -0
  416. package/src/auth/session-manager.ts +23 -0
  417. package/src/auth/token-manager.ts +32 -0
  418. package/src/background-processes/manager.ts +519 -0
  419. package/src/bin.ts +29 -0
  420. package/src/config/binaries.ts +192 -0
  421. package/src/config/location.ts +78 -0
  422. package/src/config/schema.ts +104 -0
  423. package/src/config/store.ts +244 -0
  424. package/src/events/bus.ts +45 -0
  425. package/src/filesystem/__tests__/search-cache.test.ts +61 -0
  426. package/src/filesystem/browser.ts +353 -0
  427. package/src/filesystem/search-cache.ts +66 -0
  428. package/src/filesystem/search.ts +184 -0
  429. package/src/index.ts +540 -0
  430. package/src/launcher.ts +177 -0
  431. package/src/loader.ts +21 -0
  432. package/src/logger.ts +133 -0
  433. package/src/opencode-config.ts +31 -0
  434. package/src/plugins/channel.ts +55 -0
  435. package/src/plugins/handlers.ts +36 -0
  436. package/src/releases/dev-release-monitor.ts +118 -0
  437. package/src/releases/release-monitor.ts +149 -0
  438. package/src/server/http-server.ts +693 -0
  439. package/src/server/network-addresses.ts +75 -0
  440. package/src/server/routes/auth-pages/login.html +134 -0
  441. package/src/server/routes/auth-pages/token.html +93 -0
  442. package/src/server/routes/auth.ts +164 -0
  443. package/src/server/routes/background-processes.ts +85 -0
  444. package/src/server/routes/config.ts +76 -0
  445. package/src/server/routes/events.ts +61 -0
  446. package/src/server/routes/filesystem.ts +54 -0
  447. package/src/server/routes/meta.ts +58 -0
  448. package/src/server/routes/plugin.ts +75 -0
  449. package/src/server/routes/storage.ts +66 -0
  450. package/src/server/routes/workspaces.ts +113 -0
  451. package/src/server/routes/worktrees.ts +195 -0
  452. package/src/server/tls.ts +283 -0
  453. package/src/storage/instance-store.ts +64 -0
  454. package/src/ui/__tests__/remote-ui.test.ts +58 -0
  455. package/src/ui/remote-ui.ts +571 -0
  456. package/src/workspaces/git-worktrees.ts +241 -0
  457. package/src/workspaces/instance-events.ts +226 -0
  458. package/src/workspaces/manager.ts +493 -0
  459. package/src/workspaces/opencode-auth.ts +22 -0
  460. package/src/workspaces/runtime.ts +428 -0
  461. package/src/workspaces/worktree-map.ts +129 -0
  462. package/tsconfig.json +17 -0
@@ -0,0 +1,519 @@
1
+ import { spawn, spawnSync, type ChildProcess } from "child_process"
2
+ import { createWriteStream, existsSync, promises as fs } from "fs"
3
+ import path from "path"
4
+ import { randomBytes } from "crypto"
5
+ import type { EventBus } from "../events/bus"
6
+ import type { WorkspaceManager } from "../workspaces/manager"
7
+ import type { Logger } from "../logger"
8
+ import type { BackgroundProcess, BackgroundProcessStatus } from "../api-types"
9
+
10
+ const ROOT_DIR = ".codenomad/background_processes"
11
+ const INDEX_FILE = "index.json"
12
+ const OUTPUT_FILE = "output.txt"
13
+ const STOP_TIMEOUT_MS = 2000
14
+ const EXIT_WAIT_TIMEOUT_MS = 5000
15
+ const MAX_OUTPUT_BYTES = 20 * 1024
16
+ const OUTPUT_PUBLISH_INTERVAL_MS = 1000
17
+
18
+ interface ManagerDeps {
19
+ workspaceManager: WorkspaceManager
20
+ eventBus: EventBus
21
+ logger: Logger
22
+ }
23
+
24
+ interface RunningProcess {
25
+ id: string
26
+ child: ChildProcess
27
+ outputPath: string
28
+ exitPromise: Promise<void>
29
+ workspaceId: string
30
+ }
31
+
32
+ export class BackgroundProcessManager {
33
+ private readonly running = new Map<string, RunningProcess>()
34
+
35
+ constructor(private readonly deps: ManagerDeps) {
36
+ this.deps.eventBus.on("workspace.stopped", (event) => this.cleanupWorkspace(event.workspaceId))
37
+ this.deps.eventBus.on("workspace.error", (event) => this.cleanupWorkspace(event.workspace.id))
38
+ }
39
+
40
+ async list(workspaceId: string): Promise<BackgroundProcess[]> {
41
+ const records = await this.readIndex(workspaceId)
42
+ const enriched = await Promise.all(
43
+ records.map(async (record) => ({
44
+ ...record,
45
+ outputSizeBytes: await this.getOutputSize(workspaceId, record.id),
46
+ })),
47
+ )
48
+ return enriched
49
+ }
50
+
51
+ async start(workspaceId: string, title: string, command: string): Promise<BackgroundProcess> {
52
+ const workspace = this.deps.workspaceManager.get(workspaceId)
53
+ if (!workspace) {
54
+ throw new Error("Workspace not found")
55
+ }
56
+
57
+ const id = this.generateId()
58
+ const processDir = await this.ensureProcessDir(workspaceId, id)
59
+ const outputPath = path.join(processDir, OUTPUT_FILE)
60
+
61
+ const outputStream = createWriteStream(outputPath, { flags: "a" })
62
+
63
+ const { shellCommand, shellArgs, spawnOptions } = this.buildShellSpawn(command)
64
+
65
+ const child = spawn(shellCommand, shellArgs, {
66
+ cwd: workspace.path,
67
+ stdio: ["ignore", "pipe", "pipe"],
68
+ detached: process.platform !== "win32",
69
+ ...spawnOptions,
70
+ })
71
+
72
+ child.on("exit", () => {
73
+ this.killProcessTree(child, "SIGTERM")
74
+ })
75
+
76
+ const record: BackgroundProcess = {
77
+
78
+ id,
79
+ workspaceId,
80
+ title,
81
+ command,
82
+ cwd: workspace.path,
83
+ status: "running",
84
+ pid: child.pid,
85
+ startedAt: new Date().toISOString(),
86
+ outputSizeBytes: 0,
87
+ }
88
+
89
+ const exitPromise = new Promise<void>((resolve) => {
90
+ child.on("close", async (code) => {
91
+ await new Promise<void>((resolve) => outputStream.end(resolve))
92
+ this.running.delete(id)
93
+
94
+ record.status = this.statusFromExit(code)
95
+ record.exitCode = code === null ? undefined : code
96
+ record.stoppedAt = new Date().toISOString()
97
+
98
+ await this.upsertIndex(workspaceId, record)
99
+ record.outputSizeBytes = await this.getOutputSize(workspaceId, record.id)
100
+ this.publishUpdate(workspaceId, record)
101
+ resolve()
102
+ })
103
+ })
104
+
105
+ this.running.set(id, { id, child, outputPath, exitPromise, workspaceId })
106
+
107
+ let lastPublishAt = 0
108
+ const maybePublishSize = () => {
109
+ const now = Date.now()
110
+ if (now - lastPublishAt < OUTPUT_PUBLISH_INTERVAL_MS) {
111
+ return
112
+ }
113
+ lastPublishAt = now
114
+ this.publishUpdate(workspaceId, record)
115
+ }
116
+
117
+ child.stdout?.on("data", (data) => {
118
+ outputStream.write(data)
119
+ record.outputSizeBytes = (record.outputSizeBytes ?? 0) + data.length
120
+ maybePublishSize()
121
+ })
122
+ child.stderr?.on("data", (data) => {
123
+ outputStream.write(data)
124
+ record.outputSizeBytes = (record.outputSizeBytes ?? 0) + data.length
125
+ maybePublishSize()
126
+ })
127
+
128
+ await this.upsertIndex(workspaceId, record)
129
+ record.outputSizeBytes = await this.getOutputSize(workspaceId, record.id)
130
+ this.publishUpdate(workspaceId, record)
131
+ return record
132
+ }
133
+
134
+ async stop(workspaceId: string, processId: string): Promise<BackgroundProcess | null> {
135
+ const record = await this.findProcess(workspaceId, processId)
136
+ if (!record) {
137
+ return null
138
+ }
139
+
140
+ const running = this.running.get(processId)
141
+ if (running?.child && !running.child.killed) {
142
+ this.killProcessTree(running.child, "SIGTERM")
143
+ await this.waitForExit(running)
144
+ }
145
+
146
+ if (record.status === "running") {
147
+ record.status = "stopped"
148
+ record.stoppedAt = new Date().toISOString()
149
+ await this.upsertIndex(workspaceId, record)
150
+ record.outputSizeBytes = await this.getOutputSize(workspaceId, record.id)
151
+ this.publishUpdate(workspaceId, record)
152
+ }
153
+
154
+ return record
155
+ }
156
+
157
+ async terminate(workspaceId: string, processId: string): Promise<void> {
158
+ const record = await this.findProcess(workspaceId, processId)
159
+ if (!record) return
160
+
161
+ const running = this.running.get(processId)
162
+ if (running?.child && !running.child.killed) {
163
+ this.killProcessTree(running.child, "SIGTERM")
164
+ await this.waitForExit(running)
165
+ }
166
+
167
+ await this.removeFromIndex(workspaceId, processId)
168
+ await this.removeProcessDir(workspaceId, processId)
169
+
170
+ this.deps.eventBus.publish({
171
+ type: "instance.event",
172
+ instanceId: workspaceId,
173
+ event: { type: "background.process.removed", properties: { processId } },
174
+ })
175
+ }
176
+
177
+ async readOutput(
178
+ workspaceId: string,
179
+ processId: string,
180
+ options: { method?: "full" | "tail" | "head" | "grep"; pattern?: string; lines?: number; maxBytes?: number },
181
+ ) {
182
+ const outputPath = this.getOutputPath(workspaceId, processId)
183
+ if (!existsSync(outputPath)) {
184
+ return { id: processId, content: "", truncated: false, sizeBytes: 0 }
185
+ }
186
+
187
+ const stats = await fs.stat(outputPath)
188
+ const sizeBytes = stats.size
189
+ const method = options.method ?? "full"
190
+ const lineCount = options.lines ?? 10
191
+
192
+ const raw = await this.readOutputBytes(outputPath, sizeBytes, options.maxBytes)
193
+ let content = raw
194
+
195
+ switch (method) {
196
+ case "head":
197
+ content = this.headLines(raw, lineCount)
198
+ break
199
+ case "tail":
200
+ content = this.tailLines(raw, lineCount)
201
+ break
202
+ case "grep":
203
+ if (!options.pattern) {
204
+ throw new Error("Pattern is required for grep output")
205
+ }
206
+ content = this.grepLines(raw, options.pattern)
207
+ break
208
+ default:
209
+ content = raw
210
+ }
211
+
212
+ const effectiveMaxBytes = options.maxBytes
213
+ return {
214
+ id: processId,
215
+ content,
216
+ truncated: effectiveMaxBytes !== undefined && sizeBytes > effectiveMaxBytes,
217
+ sizeBytes,
218
+ }
219
+ }
220
+
221
+ async streamOutput(workspaceId: string, processId: string, reply: any) {
222
+ const outputPath = this.getOutputPath(workspaceId, processId)
223
+ if (!existsSync(outputPath)) {
224
+ reply.code(404).send({ error: "Output not found" })
225
+ return
226
+ }
227
+
228
+ reply.raw.setHeader("Content-Type", "text/event-stream")
229
+ reply.raw.setHeader("Cache-Control", "no-cache")
230
+ reply.raw.setHeader("Connection", "keep-alive")
231
+ reply.raw.flushHeaders?.()
232
+ reply.hijack()
233
+
234
+ const file = await fs.open(outputPath, "r")
235
+ let position = (await file.stat()).size
236
+
237
+ const tick = async () => {
238
+ const stats = await file.stat()
239
+ if (stats.size <= position) return
240
+
241
+ const length = stats.size - position
242
+ const buffer = Buffer.alloc(length)
243
+ await file.read(buffer, 0, length, position)
244
+ position = stats.size
245
+
246
+ const content = buffer.toString("utf-8")
247
+ reply.raw.write(`data: ${JSON.stringify({ type: "chunk", content })}\n\n`)
248
+ }
249
+
250
+ const interval = setInterval(() => {
251
+ tick().catch((error) => {
252
+ this.deps.logger.warn({ err: error }, "Failed to stream background process output")
253
+ })
254
+ }, 1000)
255
+
256
+ const close = () => {
257
+ clearInterval(interval)
258
+ file.close().catch(() => undefined)
259
+ reply.raw.end?.()
260
+ }
261
+
262
+ reply.raw.on("close", close)
263
+ reply.raw.on("error", close)
264
+ }
265
+
266
+ private async cleanupWorkspace(workspaceId: string) {
267
+ for (const [, running] of this.running.entries()) {
268
+ if (running.workspaceId !== workspaceId) continue
269
+ this.killProcessTree(running.child, "SIGTERM")
270
+ await this.waitForExit(running)
271
+ }
272
+
273
+ await this.removeWorkspaceDir(workspaceId)
274
+ }
275
+
276
+ private killProcessTree(child: ChildProcess, signal: NodeJS.Signals) {
277
+ const pid = child.pid
278
+ if (!pid) return
279
+
280
+ if (process.platform === "win32") {
281
+ const args = this.buildWindowsTaskkillArgs(pid, signal)
282
+ try {
283
+ spawnSync("taskkill", args, { stdio: "ignore" })
284
+ return
285
+ } catch {
286
+ // Fall back to killing the direct child.
287
+ }
288
+ } else {
289
+ try {
290
+ process.kill(-pid, signal)
291
+ return
292
+ } catch {
293
+ // Fall back to killing the direct child.
294
+ }
295
+ }
296
+
297
+ try {
298
+ child.kill(signal)
299
+ } catch {
300
+ // ignore
301
+ }
302
+ }
303
+
304
+ private async waitForExit(running: RunningProcess) {
305
+ let exited = false
306
+ const exitPromise = running.exitPromise.finally(() => {
307
+ exited = true
308
+ })
309
+
310
+ const killTimeout = setTimeout(() => {
311
+ if (!exited) {
312
+ this.killProcessTree(running.child, "SIGKILL")
313
+ }
314
+ }, STOP_TIMEOUT_MS)
315
+
316
+ try {
317
+ await Promise.race([
318
+ exitPromise,
319
+ new Promise<void>((resolve) => {
320
+ setTimeout(resolve, EXIT_WAIT_TIMEOUT_MS)
321
+ }),
322
+ ])
323
+
324
+ if (!exited) {
325
+ this.killProcessTree(running.child, "SIGKILL")
326
+ this.running.delete(running.id)
327
+ this.deps.logger.warn({ pid: running.child.pid }, "Timed out waiting for background process to exit")
328
+ }
329
+ } finally {
330
+ clearTimeout(killTimeout)
331
+ }
332
+ }
333
+
334
+
335
+ private buildShellSpawn(command: string): { shellCommand: string; shellArgs: string[]; spawnOptions?: Record<string, unknown> } {
336
+ if (process.platform === "win32") {
337
+ const comspec = process.env.ComSpec || "cmd.exe"
338
+ return {
339
+ shellCommand: comspec,
340
+ shellArgs: ["/d", "/s", "/c", command],
341
+ spawnOptions: { windowsVerbatimArguments: true },
342
+ }
343
+ }
344
+
345
+ // Keep bash for macOS/Linux.
346
+ return { shellCommand: "bash", shellArgs: ["-c", command] }
347
+ }
348
+
349
+ private buildWindowsTaskkillArgs(pid: number, signal: NodeJS.Signals): string[] {
350
+ // Default to graceful termination (no /F), then force kill when we escalate.
351
+ const force = signal === "SIGKILL"
352
+ const args = ["/PID", String(pid), "/T"]
353
+ if (force) {
354
+ args.push("/F")
355
+ }
356
+ return args
357
+ }
358
+
359
+ private statusFromExit(code: number | null): BackgroundProcessStatus {
360
+ if (code === null) return "stopped"
361
+ if (code === 0) return "stopped"
362
+ return "error"
363
+ }
364
+
365
+ private async readOutputBytes(outputPath: string, sizeBytes: number, maxBytes?: number): Promise<string> {
366
+ if (maxBytes === undefined || sizeBytes <= maxBytes) {
367
+ return await fs.readFile(outputPath, "utf-8")
368
+ }
369
+
370
+ const start = Math.max(0, sizeBytes - maxBytes)
371
+ const file = await fs.open(outputPath, "r")
372
+ const buffer = Buffer.alloc(sizeBytes - start)
373
+ await file.read(buffer, 0, buffer.length, start)
374
+ await file.close()
375
+ return buffer.toString("utf-8")
376
+ }
377
+
378
+ private headLines(input: string, lines: number): string {
379
+ const parts = input.split(/\r?\n/)
380
+ return parts.slice(0, Math.max(0, lines)).join("\n")
381
+ }
382
+
383
+ private tailLines(input: string, lines: number): string {
384
+ const parts = input.split(/\r?\n/)
385
+ return parts.slice(Math.max(0, parts.length - lines)).join("\n")
386
+ }
387
+
388
+ private grepLines(input: string, pattern: string): string {
389
+ let matcher: RegExp
390
+ try {
391
+ matcher = new RegExp(pattern)
392
+ } catch {
393
+ throw new Error("Invalid grep pattern")
394
+ }
395
+ return input
396
+ .split(/\r?\n/)
397
+ .filter((line) => matcher.test(line))
398
+ .join("\n")
399
+ }
400
+
401
+ private async ensureProcessDir(workspaceId: string, processId: string) {
402
+ const root = await this.ensureWorkspaceDir(workspaceId)
403
+ const processDir = path.join(root, processId)
404
+ await fs.mkdir(processDir, { recursive: true })
405
+ return processDir
406
+ }
407
+
408
+ private async ensureWorkspaceDir(workspaceId: string) {
409
+ const workspace = this.deps.workspaceManager.get(workspaceId)
410
+ if (!workspace) {
411
+ throw new Error("Workspace not found")
412
+ }
413
+ const root = path.join(workspace.path, ROOT_DIR, workspaceId)
414
+ await fs.mkdir(root, { recursive: true })
415
+ return root
416
+ }
417
+
418
+ private getOutputPath(workspaceId: string, processId: string) {
419
+ const workspace = this.deps.workspaceManager.get(workspaceId)
420
+ if (!workspace) {
421
+ throw new Error("Workspace not found")
422
+ }
423
+ return path.join(workspace.path, ROOT_DIR, workspaceId, processId, OUTPUT_FILE)
424
+ }
425
+
426
+ private async findProcess(workspaceId: string, processId: string): Promise<BackgroundProcess | null> {
427
+ const records = await this.readIndex(workspaceId)
428
+ return records.find((entry) => entry.id === processId) ?? null
429
+ }
430
+
431
+ private async readIndex(workspaceId: string): Promise<BackgroundProcess[]> {
432
+ const indexPath = await this.getIndexPath(workspaceId)
433
+ if (!existsSync(indexPath)) return []
434
+
435
+ try {
436
+ const raw = await fs.readFile(indexPath, "utf-8")
437
+ const parsed = JSON.parse(raw)
438
+ return Array.isArray(parsed) ? (parsed as BackgroundProcess[]) : []
439
+ } catch {
440
+ return []
441
+ }
442
+ }
443
+
444
+ private async upsertIndex(workspaceId: string, record: BackgroundProcess) {
445
+ const records = await this.readIndex(workspaceId)
446
+ const index = records.findIndex((entry) => entry.id === record.id)
447
+ if (index >= 0) {
448
+ records[index] = record
449
+ } else {
450
+ records.push(record)
451
+ }
452
+ await this.writeIndex(workspaceId, records)
453
+ }
454
+
455
+ private async removeFromIndex(workspaceId: string, processId: string) {
456
+ const records = await this.readIndex(workspaceId)
457
+ const next = records.filter((entry) => entry.id !== processId)
458
+ await this.writeIndex(workspaceId, next)
459
+ }
460
+
461
+ private async writeIndex(workspaceId: string, records: BackgroundProcess[]) {
462
+ const indexPath = await this.getIndexPath(workspaceId)
463
+ await fs.mkdir(path.dirname(indexPath), { recursive: true })
464
+ await fs.writeFile(indexPath, JSON.stringify(records, null, 2))
465
+ }
466
+
467
+ private async getIndexPath(workspaceId: string) {
468
+ const workspace = this.deps.workspaceManager.get(workspaceId)
469
+ if (!workspace) {
470
+ throw new Error("Workspace not found")
471
+ }
472
+ return path.join(workspace.path, ROOT_DIR, workspaceId, INDEX_FILE)
473
+ }
474
+
475
+ private async removeProcessDir(workspaceId: string, processId: string) {
476
+ const workspace = this.deps.workspaceManager.get(workspaceId)
477
+ if (!workspace) {
478
+ return
479
+ }
480
+ const processDir = path.join(workspace.path, ROOT_DIR, workspaceId, processId)
481
+ await fs.rm(processDir, { recursive: true, force: true })
482
+ }
483
+
484
+ private async removeWorkspaceDir(workspaceId: string) {
485
+ const workspace = this.deps.workspaceManager.get(workspaceId)
486
+ if (!workspace) {
487
+ return
488
+ }
489
+ const workspaceDir = path.join(workspace.path, ROOT_DIR, workspaceId)
490
+ await fs.rm(workspaceDir, { recursive: true, force: true })
491
+ }
492
+
493
+ private async getOutputSize(workspaceId: string, processId: string): Promise<number> {
494
+ const outputPath = this.getOutputPath(workspaceId, processId)
495
+ if (!existsSync(outputPath)) {
496
+ return 0
497
+ }
498
+ try {
499
+ const stats = await fs.stat(outputPath)
500
+ return stats.size
501
+ } catch {
502
+ return 0
503
+ }
504
+ }
505
+
506
+ private publishUpdate(workspaceId: string, record: BackgroundProcess) {
507
+ this.deps.eventBus.publish({
508
+ type: "instance.event",
509
+ instanceId: workspaceId,
510
+ event: { type: "background.process.updated", properties: { process: record } },
511
+ })
512
+ }
513
+
514
+ private generateId(): string {
515
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "").slice(0, 15)
516
+ const random = randomBytes(3).toString("hex")
517
+ return `proc_${timestamp}_${random}`
518
+ }
519
+ }
package/src/bin.ts ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from "child_process"
4
+ import path from "path"
5
+ import { fileURLToPath, pathToFileURL } from "url"
6
+
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const __dirname = path.dirname(__filename)
9
+ const cliEntry = path.join(__dirname, "index.js")
10
+ const loaderFileUrl = pathToFileURL(path.join(__dirname, "loader.js")).href
11
+ const registerScript = `import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("${encodeURI(loaderFileUrl)}", pathToFileURL("./"));`
12
+ const loaderArg = `data:text/javascript,${registerScript}`
13
+
14
+ const child = spawn(process.execPath, ["--import", loaderArg, cliEntry, ...process.argv.slice(2)], {
15
+ stdio: "inherit",
16
+ })
17
+
18
+ child.on("exit", (code, signal) => {
19
+ if (signal) {
20
+ process.kill(process.pid, signal)
21
+ return
22
+ }
23
+ process.exit(code ?? 0)
24
+ })
25
+
26
+ child.on("error", (error) => {
27
+ console.error("Failed to launch CLI runtime", error)
28
+ process.exit(1)
29
+ })