@sunshinelife83/hearth 1.0.0

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 (436) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +323 -0
  3. package/bin/hearth-agentd.js +4 -0
  4. package/bin/hearth.js +4 -0
  5. package/bin/run-entrypoint.js +20 -0
  6. package/dist/agent-tools.js +738 -0
  7. package/dist/app-version.js +16 -0
  8. package/dist/apply-patch.js +402 -0
  9. package/dist/artifact-error.js +8 -0
  10. package/dist/artifact-tools.js +377 -0
  11. package/dist/cli-workspace.js +36 -0
  12. package/dist/cli.js +1086 -0
  13. package/dist/config-migration.js +82 -0
  14. package/dist/config-schema.js +136 -0
  15. package/dist/config.js +115 -0
  16. package/dist/context/context-tools.js +150 -0
  17. package/dist/context/repo-map.js +102 -0
  18. package/dist/dashboard/app.js +226 -0
  19. package/dist/dashboard/index.html +45 -0
  20. package/dist/dashboard/landing.html +57 -0
  21. package/dist/dashboard/styles.css +23 -0
  22. package/dist/dashboard.js +271 -0
  23. package/dist/db/client.js +29 -0
  24. package/dist/db/migrations.js +262 -0
  25. package/dist/db/schema.js +85 -0
  26. package/dist/device-tokens.js +61 -0
  27. package/dist/git-worktrees.js +134 -0
  28. package/dist/git.js +41 -0
  29. package/dist/incoming-artifacts.js +378 -0
  30. package/dist/local-agent-acp.js +768 -0
  31. package/dist/local-agent-adapters.js +20 -0
  32. package/dist/local-agent-availability.js +92 -0
  33. package/dist/local-agent-catalog.js +51 -0
  34. package/dist/local-agent-claude.js +334 -0
  35. package/dist/local-agent-client.js +519 -0
  36. package/dist/local-agent-codex.js +532 -0
  37. package/dist/local-agent-config.js +34 -0
  38. package/dist/local-agent-daemon-lifecycle.js +195 -0
  39. package/dist/local-agent-daemon-main.js +86 -0
  40. package/dist/local-agent-daemon-protocol.js +302 -0
  41. package/dist/local-agent-daemon.js +407 -0
  42. package/dist/local-agent-errors.js +378 -0
  43. package/dist/local-agent-grok.js +202 -0
  44. package/dist/local-agent-manager.js +715 -0
  45. package/dist/local-agent-opencode.js +463 -0
  46. package/dist/local-agent-path.js +24 -0
  47. package/dist/local-agent-pi-sandbox.js +472 -0
  48. package/dist/local-agent-pi.js +298 -0
  49. package/dist/local-agent-presentation.js +104 -0
  50. package/dist/local-agent-profiles.js +127 -0
  51. package/dist/local-agent-runtime-pool.js +481 -0
  52. package/dist/local-agent-runtime.js +1 -0
  53. package/dist/local-agent-store.js +193 -0
  54. package/dist/local-agent-targets.js +97 -0
  55. package/dist/logger.js +97 -0
  56. package/dist/machine-id.js +35 -0
  57. package/dist/mcp-modern-server.js +65 -0
  58. package/dist/oauth-provider.js +331 -0
  59. package/dist/oauth-store.js +144 -0
  60. package/dist/onboarding.js +35 -0
  61. package/dist/orchestration/brief.js +70 -0
  62. package/dist/orchestration/lanes.js +145 -0
  63. package/dist/orchestration/result.js +46 -0
  64. package/dist/orchestration/scope.js +61 -0
  65. package/dist/pi-tools.js +58 -0
  66. package/dist/policy/command-policy.js +104 -0
  67. package/dist/policy/env-allowlist.js +96 -0
  68. package/dist/policy/sandbox.js +68 -0
  69. package/dist/policy/workspace-profiles.js +47 -0
  70. package/dist/process-journal.js +116 -0
  71. package/dist/process-platform.js +49 -0
  72. package/dist/process-sessions.js +388 -0
  73. package/dist/rate-limit.js +77 -0
  74. package/dist/request-meta.js +9 -0
  75. package/dist/review-checkpoints.js +349 -0
  76. package/dist/roots.js +37 -0
  77. package/dist/server-shutdown.js +12 -0
  78. package/dist/server.js +980 -0
  79. package/dist/skills.js +84 -0
  80. package/dist/snapshot-manager.js +123 -0
  81. package/dist/stdio-server.js +80 -0
  82. package/dist/task-store.js +203 -0
  83. package/dist/task-tools.js +455 -0
  84. package/dist/tool-surfaces/claude.js +220 -0
  85. package/dist/tool-surfaces/codex.js +255 -0
  86. package/dist/tool-surfaces/index.js +15 -0
  87. package/dist/tool-surfaces/shared.js +228 -0
  88. package/dist/tool-surfaces/types.js +27 -0
  89. package/dist/ui/.vite/manifest.json +2544 -0
  90. package/dist/ui/assets/abap-CLvhMVsD.js +1 -0
  91. package/dist/ui/assets/actionscript-3--17pq3dv.js +1 -0
  92. package/dist/ui/assets/ada-C5qYipkI.js +1 -0
  93. package/dist/ui/assets/andromeeda-vGVdxbeo.js +1 -0
  94. package/dist/ui/assets/angular-html-DrbO3_Xe.js +1 -0
  95. package/dist/ui/assets/angular-ts-CmTVzHJx.js +1 -0
  96. package/dist/ui/assets/apache-U0d_L8uA.js +1 -0
  97. package/dist/ui/assets/apex-CGTLDQj6.js +1 -0
  98. package/dist/ui/assets/apl-BOpCpqXf.js +1 -0
  99. package/dist/ui/assets/applescript-CCn79oCD.js +1 -0
  100. package/dist/ui/assets/ara-4CJ0cIlV.js +1 -0
  101. package/dist/ui/assets/asciidoc-DE70LPWp.js +1 -0
  102. package/dist/ui/assets/asm-Cmm7eHzH.js +1 -0
  103. package/dist/ui/assets/astro-CxPeBwei.js +1 -0
  104. package/dist/ui/assets/aurora-x-CDeNXAV0.js +1 -0
  105. package/dist/ui/assets/awk-BWXHIvNe.js +1 -0
  106. package/dist/ui/assets/ayu-dark-DluEY0Gj.js +1 -0
  107. package/dist/ui/assets/ayu-light-C3h-C4tm.js +1 -0
  108. package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  109. package/dist/ui/assets/ballerina-B7ZEbQpA.js +1 -0
  110. package/dist/ui/assets/bat-Bo4NYOV-.js +1 -0
  111. package/dist/ui/assets/beancount-D-usSTwE.js +1 -0
  112. package/dist/ui/assets/berry-DKpUyyne.js +1 -0
  113. package/dist/ui/assets/bibtex-Ci_nEsc7.js +1 -0
  114. package/dist/ui/assets/bicep-CUHmPFLl.js +1 -0
  115. package/dist/ui/assets/bird2-C2hNVINV.js +1 -0
  116. package/dist/ui/assets/blade-DtsAAG4P.js +1 -0
  117. package/dist/ui/assets/bsl-BkkzgIyY.js +1 -0
  118. package/dist/ui/assets/c-D9hLjNUM.js +1 -0
  119. package/dist/ui/assets/c3-CnJL0r0V.js +1 -0
  120. package/dist/ui/assets/cadence-CQ2zXKGN.js +1 -0
  121. package/dist/ui/assets/cairo-DLTphjLi.js +1 -0
  122. package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
  123. package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
  124. package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
  125. package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
  126. package/dist/ui/assets/clarity-SemFz856.js +1 -0
  127. package/dist/ui/assets/clojure-DqKBuwfJ.js +1 -0
  128. package/dist/ui/assets/cmake-Bj61d0ZC.js +1 -0
  129. package/dist/ui/assets/cobol-C1SWlvZm.js +1 -0
  130. package/dist/ui/assets/codeowners-C8r90Shi.js +1 -0
  131. package/dist/ui/assets/codeql-oeQT6MSM.js +1 -0
  132. package/dist/ui/assets/coffee-B71R3v2U.js +1 -0
  133. package/dist/ui/assets/common-lisp-Cv5bFMCO.js +1 -0
  134. package/dist/ui/assets/coq-BrsZFFmf.js +1 -0
  135. package/dist/ui/assets/cpp--5a4c3v4.js +1 -0
  136. package/dist/ui/assets/crystal-AtqWYtE0.js +1 -0
  137. package/dist/ui/assets/csharp-Ct8U2NOr.js +1 -0
  138. package/dist/ui/assets/css-CbqKSHI-.js +1 -0
  139. package/dist/ui/assets/csv-Dx-8-gkx.js +1 -0
  140. package/dist/ui/assets/cue-CE9AQfxI.js +1 -0
  141. package/dist/ui/assets/cypher-ClKdZ_lG.js +1 -0
  142. package/dist/ui/assets/d-qD-0Kul2.js +1 -0
  143. package/dist/ui/assets/dark-plus-Cs2F2srj.js +1 -0
  144. package/dist/ui/assets/dart-DkHntEIa.js +1 -0
  145. package/dist/ui/assets/dax-BkyTk9wS.js +1 -0
  146. package/dist/ui/assets/desktop-Dlh5hvp9.js +1 -0
  147. package/dist/ui/assets/diff-woXpYk--.js +1 -0
  148. package/dist/ui/assets/docker-IyjqRm3v.js +1 -0
  149. package/dist/ui/assets/dotenv-_5a1GRtc.js +1 -0
  150. package/dist/ui/assets/dracula-BHWKrbxM.js +1 -0
  151. package/dist/ui/assets/dracula-soft-5eyTD99u.js +1 -0
  152. package/dist/ui/assets/dream-maker-DW3nJb8Q.js +1 -0
  153. package/dist/ui/assets/edge-BPwY_RrJ.js +1 -0
  154. package/dist/ui/assets/elixir-DVH2yLJf.js +1 -0
  155. package/dist/ui/assets/elm-BrleA6gS.js +1 -0
  156. package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +1 -0
  157. package/dist/ui/assets/erb-2SHiYe30.js +1 -0
  158. package/dist/ui/assets/erlang-Cphh6RMH.js +1 -0
  159. package/dist/ui/assets/everforest-dark-sB-x3p7T.js +1 -0
  160. package/dist/ui/assets/everforest-light-Df2xbC6M.js +1 -0
  161. package/dist/ui/assets/fennel-DQxkIbk2.js +1 -0
  162. package/dist/ui/assets/fish-BJitypiv.js +1 -0
  163. package/dist/ui/assets/fluent-C03EYrpw.js +1 -0
  164. package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
  165. package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +1 -0
  166. package/dist/ui/assets/fsharp-D13ZGOAj.js +1 -0
  167. package/dist/ui/assets/gdresource-C0sCabJj.js +1 -0
  168. package/dist/ui/assets/gdscript-Cp2uCuqX.js +1 -0
  169. package/dist/ui/assets/gdshader-CBce3t8t.js +1 -0
  170. package/dist/ui/assets/genie-CV2tkWYe.js +1 -0
  171. package/dist/ui/assets/gherkin-DExj1W_8.js +1 -0
  172. package/dist/ui/assets/git-commit-BSykSTBG.js +1 -0
  173. package/dist/ui/assets/git-rebase-Bc7atMaV.js +1 -0
  174. package/dist/ui/assets/github-dark-C-LZuMrd.js +1 -0
  175. package/dist/ui/assets/github-dark-default-DXG-b-1a.js +1 -0
  176. package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  177. package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  178. package/dist/ui/assets/github-light-EUqPIrTm.js +1 -0
  179. package/dist/ui/assets/github-light-default-BXViO-2h.js +1 -0
  180. package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  181. package/dist/ui/assets/gleam-CSRkHgEL.js +1 -0
  182. package/dist/ui/assets/glimmer-js-DXeTDPtW.js +1 -0
  183. package/dist/ui/assets/glimmer-ts-CEOoXHU4.js +1 -0
  184. package/dist/ui/assets/glsl-5-43-Gsg.js +1 -0
  185. package/dist/ui/assets/gn-ilITqXS6.js +1 -0
  186. package/dist/ui/assets/gnuplot-7GGW24-e.js +1 -0
  187. package/dist/ui/assets/go-BJwz_mda.js +1 -0
  188. package/dist/ui/assets/graphql-Bk7Ah1KA.js +1 -0
  189. package/dist/ui/assets/groovy-CacY0gHj.js +1 -0
  190. package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  191. package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  192. package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  193. package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  194. package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  195. package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  196. package/dist/ui/assets/hack-DUHz4rCJ.js +1 -0
  197. package/dist/ui/assets/haml-BPCuuTPR.js +1 -0
  198. package/dist/ui/assets/handlebars-CHxmUsnU.js +1 -0
  199. package/dist/ui/assets/haskell-D8IpX4py.js +1 -0
  200. package/dist/ui/assets/haxe-OTjmBuCE.js +1 -0
  201. package/dist/ui/assets/hcl-Dh228itO.js +1 -0
  202. package/dist/ui/assets/hjson-CxZEssPk.js +1 -0
  203. package/dist/ui/assets/hlsl-Cvrh5tZx.js +1 -0
  204. package/dist/ui/assets/horizon-CE9ld1lL.js +1 -0
  205. package/dist/ui/assets/horizon-bright-Br1oVSNq.js +1 -0
  206. package/dist/ui/assets/houston-CsvMBhTu.js +1 -0
  207. package/dist/ui/assets/html-BBJqizz0.js +1 -0
  208. package/dist/ui/assets/html-derivative-ShTPCcKN.js +1 -0
  209. package/dist/ui/assets/http-VFTyziwA.js +1 -0
  210. package/dist/ui/assets/hurl-B8yxTa4r.js +1 -0
  211. package/dist/ui/assets/hxml-B0Qn7Nwc.js +1 -0
  212. package/dist/ui/assets/hy-CZbG8q4J.js +1 -0
  213. package/dist/ui/assets/imba-DsUTQ-LC.js +1 -0
  214. package/dist/ui/assets/ini-B5eOa1yu.js +1 -0
  215. package/dist/ui/assets/java-BZ5DAgJZ.js +1 -0
  216. package/dist/ui/assets/javascript-C_zuIEaC.js +1 -0
  217. package/dist/ui/assets/jinja-DWd6xfNr.js +1 -0
  218. package/dist/ui/assets/jison-BbY63d1V.js +1 -0
  219. package/dist/ui/assets/json-C4DnajZs.js +1 -0
  220. package/dist/ui/assets/json5-BR5RXkoi.js +1 -0
  221. package/dist/ui/assets/jsonc-CYpm1nAK.js +1 -0
  222. package/dist/ui/assets/jsonl-CmCQp5Yx.js +1 -0
  223. package/dist/ui/assets/jsonnet-CJTPZ8u_.js +1 -0
  224. package/dist/ui/assets/jssm-DXw9l8Rf.js +1 -0
  225. package/dist/ui/assets/jsx-C4AACieZ.js +1 -0
  226. package/dist/ui/assets/julia-sRu7EFMW.js +1 -0
  227. package/dist/ui/assets/just-DpZ9Sx1v.js +1 -0
  228. package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
  229. package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +1 -0
  230. package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +1 -0
  231. package/dist/ui/assets/kdl-CsD5j6eV.js +1 -0
  232. package/dist/ui/assets/kotlin-DhhofPvG.js +1 -0
  233. package/dist/ui/assets/kusto-BUv0MjJC.js +1 -0
  234. package/dist/ui/assets/laserwave-C_8bwKvT.js +1 -0
  235. package/dist/ui/assets/latex-B6a_uum7.js +1 -0
  236. package/dist/ui/assets/lean-CewbzKMR.js +1 -0
  237. package/dist/ui/assets/less-DVTAwKKz.js +1 -0
  238. package/dist/ui/assets/light-plus-DVQuIRkW.js +1 -0
  239. package/dist/ui/assets/liquid-B2sVpjjr.js +1 -0
  240. package/dist/ui/assets/llvm-Cm23YOpf.js +1 -0
  241. package/dist/ui/assets/log-BNLmms1o.js +1 -0
  242. package/dist/ui/assets/logo-Cluzi2Zq.js +1 -0
  243. package/dist/ui/assets/lua-DxJJll61.js +1 -0
  244. package/dist/ui/assets/luau-CNKltnaQ.js +1 -0
  245. package/dist/ui/assets/make-Dixweg8N.js +1 -0
  246. package/dist/ui/assets/markdown-BYOwaDjH.js +1 -0
  247. package/dist/ui/assets/marko-Dx8mw-Wx.js +1 -0
  248. package/dist/ui/assets/material-theme-Bm3Qr25_.js +1 -0
  249. package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +1 -0
  250. package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +1 -0
  251. package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  252. package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  253. package/dist/ui/assets/matlab-D7qyCx1q.js +1 -0
  254. package/dist/ui/assets/mdc-vNKeXEwR.js +1 -0
  255. package/dist/ui/assets/mdx-DQZ5AkYe.js +1 -0
  256. package/dist/ui/assets/mermaid-Bk4SNUv9.js +1 -0
  257. package/dist/ui/assets/min-dark-BSWPekZh.js +1 -0
  258. package/dist/ui/assets/min-light-DDpmG2fV.js +1 -0
  259. package/dist/ui/assets/mipsasm-BMqwQI7S.js +1 -0
  260. package/dist/ui/assets/mojo-BgCJLMeH.js +1 -0
  261. package/dist/ui/assets/monokai-CdkpiU2Y.js +1 -0
  262. package/dist/ui/assets/moonbit-CaWjb8XO.js +1 -0
  263. package/dist/ui/assets/move-B1IS1UjX.js +1 -0
  264. package/dist/ui/assets/narrat-_X_XdTYD.js +1 -0
  265. package/dist/ui/assets/nextflow-Bbiyy34d.js +1 -0
  266. package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +1 -0
  267. package/dist/ui/assets/nginx-DScQAGLT.js +1 -0
  268. package/dist/ui/assets/night-owl-DhmEMT88.js +1 -0
  269. package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +1 -0
  270. package/dist/ui/assets/nim-lAJch9uT.js +1 -0
  271. package/dist/ui/assets/nix-IvuFDN5E.js +1 -0
  272. package/dist/ui/assets/nord-Cb4Vim4T.js +1 -0
  273. package/dist/ui/assets/nushell-DcLAeLz5.js +1 -0
  274. package/dist/ui/assets/objective-c-D1A_Heim.js +1 -0
  275. package/dist/ui/assets/objective-cpp-BsSzOQcm.js +1 -0
  276. package/dist/ui/assets/ocaml-O90oeIOV.js +1 -0
  277. package/dist/ui/assets/odin-B1RWQWA5.js +1 -0
  278. package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +1 -0
  279. package/dist/ui/assets/one-light-D7Lr4KcI.js +1 -0
  280. package/dist/ui/assets/openscad-BUDT5pXO.js +1 -0
  281. package/dist/ui/assets/pascal-4ZHwLPI5.js +1 -0
  282. package/dist/ui/assets/perl-C_GkVo_E.js +1 -0
  283. package/dist/ui/assets/php-DziV3K6J.js +1 -0
  284. package/dist/ui/assets/pierre-dark-CpLgRqie.js +1 -0
  285. package/dist/ui/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
  286. package/dist/ui/assets/pierre-dark-soft-kZQmAZld.js +1 -0
  287. package/dist/ui/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
  288. package/dist/ui/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
  289. package/dist/ui/assets/pierre-light-CoaEpmwp.js +1 -0
  290. package/dist/ui/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
  291. package/dist/ui/assets/pierre-light-soft-lWLdNTOI.js +1 -0
  292. package/dist/ui/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
  293. package/dist/ui/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
  294. package/dist/ui/assets/pkl-ot-7Btpt.js +1 -0
  295. package/dist/ui/assets/plastic-DQwYfKfQ.js +1 -0
  296. package/dist/ui/assets/plsql-DGHpHOYJ.js +1 -0
  297. package/dist/ui/assets/po-BiJDBrnU.js +1 -0
  298. package/dist/ui/assets/poimandres-DRFjx7u4.js +1 -0
  299. package/dist/ui/assets/polar-C7UOKdEL.js +1 -0
  300. package/dist/ui/assets/postcss-BXeXVLqQ.js +1 -0
  301. package/dist/ui/assets/powerquery-DNMTfnFr.js +1 -0
  302. package/dist/ui/assets/powershell-DshXNtvi.js +1 -0
  303. package/dist/ui/assets/prisma-BsRQq5mF.js +1 -0
  304. package/dist/ui/assets/prolog-iXnhIJG7.js +1 -0
  305. package/dist/ui/assets/proto-DB4EqR-F.js +1 -0
  306. package/dist/ui/assets/pug-z75UIWVK.js +1 -0
  307. package/dist/ui/assets/puppet-CDv2pdJW.js +1 -0
  308. package/dist/ui/assets/purescript-9MfHhQsQ.js +1 -0
  309. package/dist/ui/assets/python-gzcpVVnB.js +1 -0
  310. package/dist/ui/assets/qml-Cmm4coz1.js +1 -0
  311. package/dist/ui/assets/qmldir-DCQb3MpD.js +1 -0
  312. package/dist/ui/assets/qss-Fe1Jh2GI.js +1 -0
  313. package/dist/ui/assets/r-Brd0axBE.js +1 -0
  314. package/dist/ui/assets/racket-DcIDlBhZ.js +1 -0
  315. package/dist/ui/assets/raku-B3gFvitq.js +1 -0
  316. package/dist/ui/assets/razor-DSbwmoiu.js +1 -0
  317. package/dist/ui/assets/red-CJ3rzSJv.js +1 -0
  318. package/dist/ui/assets/reg-CRGYupPL.js +1 -0
  319. package/dist/ui/assets/regexp-Bs3Uk-pY.js +1 -0
  320. package/dist/ui/assets/rel-BtDbiS_P.js +1 -0
  321. package/dist/ui/assets/review-payload-CbwCBKB1.js +1580 -0
  322. package/dist/ui/assets/riscv-Ckw8ddFX.js +1 -0
  323. package/dist/ui/assets/ron-VUp2lXgN.js +1 -0
  324. package/dist/ui/assets/rose-pine-BthvhNj6.js +1 -0
  325. package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
  326. package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +1 -0
  327. package/dist/ui/assets/rosmsg-CAekHB0j.js +1 -0
  328. package/dist/ui/assets/rst-ChIyKpUC.js +1 -0
  329. package/dist/ui/assets/ruby-BdAmvOMO.js +1 -0
  330. package/dist/ui/assets/rust-Cfkwpbl8.js +1 -0
  331. package/dist/ui/assets/sas-DpXn8hc5.js +1 -0
  332. package/dist/ui/assets/sass-DXrisJhu.js +1 -0
  333. package/dist/ui/assets/scala-DKOlJaKm.js +1 -0
  334. package/dist/ui/assets/scheme-DQCgrYNe.js +1 -0
  335. package/dist/ui/assets/scss-atX1Uuef.js +1 -0
  336. package/dist/ui/assets/sdbl-bTVj8UrX.js +1 -0
  337. package/dist/ui/assets/shaderlab-TOUzSsQk.js +1 -0
  338. package/dist/ui/assets/shellscript-BqgcAeMK.js +1 -0
  339. package/dist/ui/assets/shellsession-DfQSMRN5.js +1 -0
  340. package/dist/ui/assets/slack-dark-DnToyrRv.js +1 -0
  341. package/dist/ui/assets/slack-ochin-B2OO5cIa.js +1 -0
  342. package/dist/ui/assets/smalltalk-B16xEiuN.js +1 -0
  343. package/dist/ui/assets/snazzy-light-4G7pJPwS.js +1 -0
  344. package/dist/ui/assets/solarized-dark-DV17i1UV.js +1 -0
  345. package/dist/ui/assets/solarized-light-DSh2HLQt.js +1 -0
  346. package/dist/ui/assets/solidity-CKzVLygQ.js +1 -0
  347. package/dist/ui/assets/soy-DzP7zZTB.js +1 -0
  348. package/dist/ui/assets/sparql-D_iOobhT.js +1 -0
  349. package/dist/ui/assets/splunk-BC2Px7Mm.js +1 -0
  350. package/dist/ui/assets/sql-gmaLk66z.js +1 -0
  351. package/dist/ui/assets/ssh-config-BgfXC-Er.js +1 -0
  352. package/dist/ui/assets/stata-CJ0YTMcV.js +1 -0
  353. package/dist/ui/assets/stylus-B6D30XZt.js +1 -0
  354. package/dist/ui/assets/surrealql-LH7FciQz.js +1 -0
  355. package/dist/ui/assets/svelte-BME2PU6V.js +1 -0
  356. package/dist/ui/assets/swift-DonLKvLd.js +1 -0
  357. package/dist/ui/assets/synthwave-84-nFMaYfgc.js +1 -0
  358. package/dist/ui/assets/system-verilog-DJ5XKQeo.js +1 -0
  359. package/dist/ui/assets/systemd-BxMlprV5.js +1 -0
  360. package/dist/ui/assets/talonscript-CohzipZa.js +1 -0
  361. package/dist/ui/assets/tasl-DMoTqEGO.js +1 -0
  362. package/dist/ui/assets/tcl-CZd0xW_V.js +1 -0
  363. package/dist/ui/assets/templ-DHBNIfYW.js +1 -0
  364. package/dist/ui/assets/terraform-DswuEJGm.js +1 -0
  365. package/dist/ui/assets/tex-C8-kPEzO.js +1 -0
  366. package/dist/ui/assets/tokyo-night-oM2G3aXe.js +1 -0
  367. package/dist/ui/assets/toml-CcmNWLt0.js +1 -0
  368. package/dist/ui/assets/ts-tags-CiewV0vR.js +1 -0
  369. package/dist/ui/assets/tsv-sltzmVWM.js +1 -0
  370. package/dist/ui/assets/tsx-CUYPqmnq.js +1 -0
  371. package/dist/ui/assets/turtle-ByJddavk.js +1 -0
  372. package/dist/ui/assets/twig-BTkvsl0b.js +1 -0
  373. package/dist/ui/assets/typescript-DDQMaPwj.js +1 -0
  374. package/dist/ui/assets/typespec-B88KGewJ.js +1 -0
  375. package/dist/ui/assets/typst-DI99ib-x.js +1 -0
  376. package/dist/ui/assets/v-DETTlOr0.js +1 -0
  377. package/dist/ui/assets/vala-zf12oZj6.js +1 -0
  378. package/dist/ui/assets/vb-Djn5o6TS.js +1 -0
  379. package/dist/ui/assets/verilog-CiiDBU1e.js +1 -0
  380. package/dist/ui/assets/vesper-D5bVUKB1.js +1 -0
  381. package/dist/ui/assets/vhdl-BroJfC0k.js +1 -0
  382. package/dist/ui/assets/viml-DvXPmvsu.js +1 -0
  383. package/dist/ui/assets/vitesse-black-fwtXNY1n.js +1 -0
  384. package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +1 -0
  385. package/dist/ui/assets/vitesse-light-VbXTXTou.js +1 -0
  386. package/dist/ui/assets/vue-BH5SEWRH.js +1 -0
  387. package/dist/ui/assets/vue-html-BT7yeYez.js +1 -0
  388. package/dist/ui/assets/vue-vine-Cs5IN2rs.js +1 -0
  389. package/dist/ui/assets/vyper-CgoNMtux.js +1 -0
  390. package/dist/ui/assets/wasm-BnjxR4X6.js +1 -0
  391. package/dist/ui/assets/wasm-ByWQv1Qj.js +1 -0
  392. package/dist/ui/assets/wenyan-C8pVoKbM.js +1 -0
  393. package/dist/ui/assets/wgsl-BsKzXJz4.js +1 -0
  394. package/dist/ui/assets/wikitext-ClFFjSW2.js +1 -0
  395. package/dist/ui/assets/wit-DdvCle-K.js +1 -0
  396. package/dist/ui/assets/wolfram-DLL8P-h_.js +1 -0
  397. package/dist/ui/assets/workspace-app-B_BnSEHO.css +1 -0
  398. package/dist/ui/assets/workspace-app-DSFpnrIC.js +115 -0
  399. package/dist/ui/assets/xml-D3_1BEcO.js +1 -0
  400. package/dist/ui/assets/xsl-BBOCDn4Y.js +1 -0
  401. package/dist/ui/assets/yaml-lThBDT45.js +1 -0
  402. package/dist/ui/assets/zenscript-BnlCZFoB.js +1 -0
  403. package/dist/ui/assets/zig-CMLA9XwU.js +1 -0
  404. package/dist/ui/workspace-app.html +15 -0
  405. package/dist/user-config.js +228 -0
  406. package/dist/verification.js +74 -0
  407. package/dist/workspace-store.js +133 -0
  408. package/dist/workspaces.js +433 -0
  409. package/docs/adr/devspace-x-implementation-adrs.md +159 -0
  410. package/docs/agent-profile-schema.md +203 -0
  411. package/docs/artifact-exchange.md +44 -0
  412. package/docs/assets/devspace-logo-light.png +0 -0
  413. package/docs/assets/devspace-screenshot.png +0 -0
  414. package/docs/assets/v11-review-ui-after.png +0 -0
  415. package/docs/assets/v11-review-ui-before.png +0 -0
  416. package/docs/chatgpt-coding-workflow.md +215 -0
  417. package/docs/configuration.md +217 -0
  418. package/docs/gotchas.md +294 -0
  419. package/docs/local-agent-daemon.md +101 -0
  420. package/docs/security.md +197 -0
  421. package/docs/setup.md +174 -0
  422. package/examples/agents/claude-implementer.md +30 -0
  423. package/examples/agents/codex-explorer.md +27 -0
  424. package/examples/agents/codex-qa-tester.md +29 -0
  425. package/examples/agents/codex-worker.md +25 -0
  426. package/examples/agents/copilot-reviewer.md +25 -0
  427. package/examples/agents/cursor-agent-worker.md +26 -0
  428. package/examples/agents/grok-builder.md +10 -0
  429. package/examples/agents/opencode-explorer.md +27 -0
  430. package/examples/agents/pi-reviewer.md +27 -0
  431. package/package.json +102 -0
  432. package/schema/v1/hearth.schema.json +529 -0
  433. package/scripts/copy-dashboard.mjs +9 -0
  434. package/scripts/fix-node-pty-permissions.mjs +22 -0
  435. package/scripts/generate-config-schema.ts +9 -0
  436. package/skills/subagents/SKILL.md +57 -0
@@ -0,0 +1,195 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { chmodSync, closeSync, linkSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync, } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ export const LOCAL_AGENT_DAEMON_PROTOCOL_VERSION = 4;
5
+ export const LOCAL_AGENT_DAEMON_SOCKET_NAME = "agentd.sock";
6
+ export const LOCAL_AGENT_DAEMON_PID_NAME = "agentd.pid";
7
+ export const LOCAL_AGENT_DAEMON_LOCK_NAME = "agentd.lock";
8
+ export const LOCAL_AGENT_DAEMON_SECRET_NAME = "agentd.secret";
9
+ export const LOCAL_AGENT_DAEMON_LOG_NAME = "agentd.log";
10
+ export function localAgentDaemonPaths(stateDir, platform = process.platform) {
11
+ const resolvedStateDir = resolve(stateDir);
12
+ const socketPath = join(resolvedStateDir, LOCAL_AGENT_DAEMON_SOCKET_NAME);
13
+ return {
14
+ stateDir: resolvedStateDir,
15
+ socketPath,
16
+ pidPath: join(resolvedStateDir, LOCAL_AGENT_DAEMON_PID_NAME),
17
+ lockPath: join(resolvedStateDir, LOCAL_AGENT_DAEMON_LOCK_NAME),
18
+ secretPath: join(resolvedStateDir, LOCAL_AGENT_DAEMON_SECRET_NAME),
19
+ logPath: join(resolvedStateDir, LOCAL_AGENT_DAEMON_LOG_NAME),
20
+ endpoint: platform === "win32"
21
+ ? `\\\\.\\pipe\\hearth-agentd-${hashStateDir(resolvedStateDir)}`
22
+ : socketPath,
23
+ };
24
+ }
25
+ export function ensureLocalAgentDaemonStateDir(stateDir) {
26
+ mkdirSync(stateDir, { recursive: true, mode: 0o700 });
27
+ chmodSync(stateDir, 0o700);
28
+ }
29
+ export class LocalAgentDaemonAlreadyRunningError extends Error {
30
+ pid;
31
+ code = "DAEMON_ALREADY_RUNNING";
32
+ constructor(pid) {
33
+ super(pid ? `Local agent daemon is already running (pid ${pid}).` : "Local agent daemon is already running.");
34
+ this.pid = pid;
35
+ this.name = "LocalAgentDaemonAlreadyRunningError";
36
+ }
37
+ }
38
+ export class LocalAgentDaemonLock {
39
+ paths;
40
+ acquired = false;
41
+ constructor(paths) {
42
+ this.paths = paths;
43
+ }
44
+ acquire() {
45
+ ensureLocalAgentDaemonStateDir(this.paths.stateDir);
46
+ for (let attempt = 0; attempt < 2; attempt += 1) {
47
+ const temporaryPath = `${this.paths.lockPath}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`;
48
+ let published = false;
49
+ try {
50
+ writeFileSecure(temporaryPath, `${process.pid}\n`);
51
+ // Publish the owner record atomically. An empty lock must never be
52
+ // visible to stale-lock recovery between create and write.
53
+ linkSync(temporaryPath, this.paths.lockPath);
54
+ published = true;
55
+ rmSync(temporaryPath, { force: true });
56
+ chmodSync(this.paths.lockPath, 0o600);
57
+ writeFileSecure(this.paths.pidPath, `${process.pid}\n`);
58
+ this.acquired = true;
59
+ return;
60
+ }
61
+ catch (error) {
62
+ rmSync(temporaryPath, { force: true });
63
+ if (published && readDaemonPid(this.paths.lockPath) === process.pid) {
64
+ rmSync(this.paths.lockPath, { force: true });
65
+ }
66
+ if (!isFileExistsError(error))
67
+ throw error;
68
+ const pid = readDaemonPid(this.paths.lockPath);
69
+ if (pid !== undefined && isProcessAlive(pid)) {
70
+ throw new LocalAgentDaemonAlreadyRunningError(pid);
71
+ }
72
+ if (pid === undefined) {
73
+ // An undecodable lock may belong to a process that has not finished
74
+ // publishing its owner record. Refuse to delete it automatically.
75
+ throw new LocalAgentDaemonAlreadyRunningError();
76
+ }
77
+ if (!removeStaleLock(this.paths.lockPath))
78
+ continue;
79
+ }
80
+ }
81
+ throw new LocalAgentDaemonAlreadyRunningError(readDaemonPid(this.paths.lockPath));
82
+ }
83
+ release() {
84
+ if (!this.acquired)
85
+ return;
86
+ this.acquired = false;
87
+ if (readDaemonPid(this.paths.pidPath) === process.pid) {
88
+ rmSync(this.paths.pidPath, { force: true });
89
+ }
90
+ if (readDaemonPid(this.paths.lockPath) === process.pid) {
91
+ rmSync(this.paths.lockPath, { force: true });
92
+ }
93
+ }
94
+ }
95
+ export function ensureLocalAgentDaemonSecret(paths) {
96
+ ensureLocalAgentDaemonStateDir(paths.stateDir);
97
+ try {
98
+ const secret = readFileSync(paths.secretPath, "utf8").trim();
99
+ if (isDaemonSecret(secret))
100
+ return secret;
101
+ }
102
+ catch {
103
+ // Create the secret below.
104
+ }
105
+ const secret = randomBytes(32).toString("hex");
106
+ try {
107
+ const fileDescriptor = openSync(paths.secretPath, "wx", 0o600);
108
+ try {
109
+ writeSync(fileDescriptor, `${secret}\n`);
110
+ chmodSync(paths.secretPath, 0o600);
111
+ return secret;
112
+ }
113
+ finally {
114
+ closeSync(fileDescriptor);
115
+ }
116
+ }
117
+ catch (error) {
118
+ if (!isFileExistsError(error))
119
+ throw error;
120
+ const existing = readFileSync(paths.secretPath, "utf8").trim();
121
+ if (!isDaemonSecret(existing))
122
+ throw new Error("Local agent daemon secret is invalid.");
123
+ return existing;
124
+ }
125
+ }
126
+ export function readLocalAgentDaemonSecret(paths) {
127
+ try {
128
+ const secret = readFileSync(paths.secretPath, "utf8").trim();
129
+ return isDaemonSecret(secret) ? secret : undefined;
130
+ }
131
+ catch {
132
+ return undefined;
133
+ }
134
+ }
135
+ export function removeLocalAgentDaemonFiles(paths) {
136
+ rmSync(paths.pidPath, { force: true });
137
+ if (process.platform !== "win32")
138
+ rmSync(paths.socketPath, { force: true });
139
+ }
140
+ export function readDaemonPid(pidPath) {
141
+ try {
142
+ const value = readFileSync(pidPath, "utf8").trim();
143
+ if (!/^\d+$/.test(value))
144
+ return undefined;
145
+ const pid = Number(value);
146
+ return Number.isSafeInteger(pid) && pid > 0 ? pid : undefined;
147
+ }
148
+ catch {
149
+ return undefined;
150
+ }
151
+ }
152
+ export function isProcessAlive(pid) {
153
+ try {
154
+ process.kill(pid, 0);
155
+ return true;
156
+ }
157
+ catch (error) {
158
+ return error.code === "EPERM";
159
+ }
160
+ }
161
+ function writeFileSecure(path, content) {
162
+ const fileDescriptor = openSync(path, "w", 0o600);
163
+ try {
164
+ writeSync(fileDescriptor, content);
165
+ chmodSync(path, 0o600);
166
+ }
167
+ finally {
168
+ closeSync(fileDescriptor);
169
+ }
170
+ }
171
+ function isFileExistsError(error) {
172
+ return error.code === "EEXIST";
173
+ }
174
+ function removeStaleLock(path) {
175
+ const stalePath = `${path}.stale-${process.pid}-${randomBytes(8).toString("hex")}`;
176
+ try {
177
+ // Rename moves the exact lock we inspected out of the ownership path. If
178
+ // another contender publishes a new lock after this point, it is never
179
+ // removed with the stale one.
180
+ renameSync(path, stalePath);
181
+ rmSync(stalePath, { force: true });
182
+ return true;
183
+ }
184
+ catch (error) {
185
+ if (error.code === "ENOENT")
186
+ return false;
187
+ throw error;
188
+ }
189
+ }
190
+ function isDaemonSecret(secret) {
191
+ return /^[0-9a-f]{64}$/i.test(secret);
192
+ }
193
+ function hashStateDir(stateDir) {
194
+ return createHash("sha256").update(stateDir).digest("hex").slice(0, 24);
195
+ }
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ import { loadConfig } from "./config.js";
3
+ import { createLocalAgentDrivers } from "./local-agent-adapters.js";
4
+ import { loadLocalAgentProfiles } from "./local-agent-profiles.js";
5
+ import { LocalAgentDaemon, writeLocalAgentDaemonLog } from "./local-agent-daemon.js";
6
+ import { LocalAgentDaemonAlreadyRunningError, localAgentDaemonPaths, } from "./local-agent-daemon-lifecycle.js";
7
+ import { LocalAgentManager } from "./local-agent-manager.js";
8
+ import { LocalAgentRuntimePool } from "./local-agent-runtime-pool.js";
9
+ import { LocalAgentStore } from "./local-agent-store.js";
10
+ const config = loadConfig();
11
+ const DEFAULT_DAEMON_SHUTDOWN_TIMEOUT_MS = 10_000;
12
+ const paths = localAgentDaemonPaths(config.stateDir);
13
+ const log = (level, event, fields) => writeLocalAgentDaemonLog(paths, level, event, fields);
14
+ const store = new LocalAgentStore(paths.stateDir);
15
+ const manager = new LocalAgentManager({
16
+ store,
17
+ drivers: createLocalAgentDrivers(),
18
+ pool: new LocalAgentRuntimePool({ logger: log }),
19
+ loadProfiles: (workspaceRoot) => loadLocalAgentProfiles(config, workspaceRoot, { includeDisabled: true }),
20
+ agentDir: config.agentDir,
21
+ allowedRoots: config.allowedRoots,
22
+ logger: log,
23
+ subagents: config.subagents,
24
+ });
25
+ const daemon = new LocalAgentDaemon({
26
+ stateDir: paths.stateDir,
27
+ manager,
28
+ onLockAcquired: () => {
29
+ const reconciled = manager.reconcileActiveRuns();
30
+ if (reconciled.isErr())
31
+ throw reconciled.error;
32
+ },
33
+ onClosed: () => { if (!shuttingDown)
34
+ process.exit(0); },
35
+ idleShutdownMs: parseIdleShutdownMs(process.env.HEARTH_AGENTD_IDLE_TIMEOUT_MS),
36
+ });
37
+ let shuttingDown = false;
38
+ const shutdown = () => {
39
+ if (shuttingDown)
40
+ return;
41
+ shuttingDown = true;
42
+ const forceTimer = setTimeout(() => {
43
+ log("error", "daemon_forced_shutdown", {
44
+ activeTurns: manager.activeTurnCount,
45
+ runtimeCount: manager.runtimeCount,
46
+ });
47
+ // Active records intentionally remain durable. The next daemon startup
48
+ // reconciles them to error while preserving provider continuation data.
49
+ process.exit(1);
50
+ }, parseShutdownTimeoutMs(process.env.HEARTH_AGENTD_SHUTDOWN_TIMEOUT_MS));
51
+ forceTimer.unref();
52
+ void daemon.close().finally(() => process.exit(0));
53
+ };
54
+ process.once("SIGINT", shutdown);
55
+ process.once("SIGTERM", shutdown);
56
+ try {
57
+ await daemon.start();
58
+ }
59
+ catch (error) {
60
+ if (error instanceof LocalAgentDaemonAlreadyRunningError) {
61
+ await manager.close();
62
+ process.exit(0);
63
+ }
64
+ log("error", "daemon_start_failed", { error: error instanceof Error ? error.message : String(error) });
65
+ await manager.close();
66
+ console.error(error instanceof Error ? error.message : String(error));
67
+ process.exit(1);
68
+ }
69
+ function parseIdleShutdownMs(value) {
70
+ if (value === undefined || value.trim() === "")
71
+ return 30_000;
72
+ const parsed = Number(value);
73
+ if (!Number.isFinite(parsed) || parsed < 0) {
74
+ throw new Error("HEARTH_AGENTD_IDLE_TIMEOUT_MS must be a non-negative duration.");
75
+ }
76
+ return parsed;
77
+ }
78
+ function parseShutdownTimeoutMs(value) {
79
+ if (value === undefined || value.trim() === "")
80
+ return DEFAULT_DAEMON_SHUTDOWN_TIMEOUT_MS;
81
+ const parsed = Number(value);
82
+ if (!Number.isFinite(parsed) || parsed < 0) {
83
+ throw new Error("HEARTH_AGENTD_SHUTDOWN_TIMEOUT_MS must be a non-negative duration.");
84
+ }
85
+ return parsed;
86
+ }
@@ -0,0 +1,302 @@
1
+ import { LOCAL_AGENT_DAEMON_PROTOCOL_VERSION } from "./local-agent-daemon-lifecycle.js";
2
+ export function encodeLocalAgentDaemonRequest(request) {
3
+ return `${JSON.stringify(request)}\n`;
4
+ }
5
+ export function encodeLocalAgentDaemonResponse(response) {
6
+ return `${JSON.stringify(response)}\n`;
7
+ }
8
+ export function decodeLocalAgentDaemonRequest(value) {
9
+ const record = asRecord(value);
10
+ const requestId = requiredString(record?.requestId, "requestId");
11
+ const protocolVersion = requiredInteger(record?.protocolVersion, "protocolVersion");
12
+ const authToken = requiredString(record?.authToken, "authToken");
13
+ const method = requiredString(record?.method, "method");
14
+ const params = record?.params;
15
+ switch (method) {
16
+ case "hello":
17
+ case "daemon.status":
18
+ case "daemon.stop":
19
+ return { requestId, protocolVersion, authToken, method, params: decodeEmptyParams(params) };
20
+ case "agent.start":
21
+ return {
22
+ requestId,
23
+ protocolVersion,
24
+ authToken,
25
+ method,
26
+ params: decodeStartInput(params),
27
+ };
28
+ case "agent.continue":
29
+ return {
30
+ requestId,
31
+ protocolVersion,
32
+ authToken,
33
+ method,
34
+ params: decodeContinueInput(params),
35
+ };
36
+ case "agent.get":
37
+ return {
38
+ requestId,
39
+ protocolVersion,
40
+ method,
41
+ authToken,
42
+ params: {
43
+ id: requiredString(asRecord(params)?.id, "id"),
44
+ scope: decodeWorkspaceScope(asRecord(params)?.scope),
45
+ },
46
+ };
47
+ case "agent.list":
48
+ return {
49
+ requestId,
50
+ protocolVersion,
51
+ authToken,
52
+ method,
53
+ params: decodeListScope(params),
54
+ };
55
+ case "agent.pause":
56
+ case "agent.stop":
57
+ return {
58
+ requestId,
59
+ protocolVersion,
60
+ authToken,
61
+ method,
62
+ params: decodeLifecycleInput(params),
63
+ };
64
+ case "agent.resume":
65
+ return {
66
+ requestId,
67
+ protocolVersion,
68
+ authToken,
69
+ method,
70
+ params: decodeResumeInput(params),
71
+ };
72
+ case "daemon.logs":
73
+ return {
74
+ requestId,
75
+ protocolVersion,
76
+ authToken,
77
+ method,
78
+ params: decodeLogsParams(params),
79
+ };
80
+ default:
81
+ throw new LocalAgentDaemonProtocolError("UNKNOWN_METHOD", `Unknown daemon method: ${method}`);
82
+ }
83
+ }
84
+ export function decodeLocalAgentDaemonResponse(value) {
85
+ const record = asRecord(value);
86
+ const requestId = requiredString(record?.requestId, "requestId");
87
+ const protocolVersion = requiredInteger(record?.protocolVersion, "protocolVersion");
88
+ if (record?.ok === true) {
89
+ return { requestId, protocolVersion, ok: true, result: record.result };
90
+ }
91
+ if (record?.ok === false) {
92
+ const error = asRecord(record.error);
93
+ return {
94
+ requestId,
95
+ protocolVersion,
96
+ ok: false,
97
+ error: {
98
+ code: requiredString(error?.code, "error.code"),
99
+ message: requiredString(error?.message, "error.message"),
100
+ retryable: optionalBoolean(error?.retryable),
101
+ provider: optionalString(error?.provider),
102
+ agentId: optionalString(error?.agentId),
103
+ workspaceId: optionalString(error?.workspaceId),
104
+ operation: optionalString(error?.operation),
105
+ target: optionalString(error?.target),
106
+ },
107
+ };
108
+ }
109
+ throw new LocalAgentDaemonProtocolError("INVALID_RESPONSE", "Daemon returned an invalid response.");
110
+ }
111
+ export function decodeAgentRecord(value) {
112
+ const record = asRecord(value);
113
+ const status = requiredString(record?.status, "status");
114
+ if (!isLocalAgentStatus(status))
115
+ throw new LocalAgentDaemonProtocolError("INVALID_RECORD", "Invalid agent status.");
116
+ return {
117
+ id: requiredString(record?.id, "id"),
118
+ workspaceId: optionalString(record?.workspaceId),
119
+ workspaceRoot: requiredString(record?.workspaceRoot, "workspaceRoot"),
120
+ profileName: requiredString(record?.profileName, "profileName"),
121
+ provider: requiredString(record?.provider, "provider"),
122
+ model: optionalString(record?.model),
123
+ effort: optionalString(record?.effort),
124
+ providerSessionId: optionalString(record?.providerSessionId),
125
+ status,
126
+ latestResponse: optionalContentString(record?.latestResponse),
127
+ latestOutput: optionalContentString(record?.latestOutput),
128
+ error: optionalContentString(record?.error),
129
+ errorCode: optionalString(record?.errorCode),
130
+ errorRetryable: optionalBoolean(record?.errorRetryable),
131
+ createdAt: requiredString(record?.createdAt, "createdAt"),
132
+ updatedAt: requiredString(record?.updatedAt, "updatedAt"),
133
+ };
134
+ }
135
+ export function decodeAgentRecordList(value) {
136
+ if (!Array.isArray(value))
137
+ throw new LocalAgentDaemonProtocolError("INVALID_RESULT", "Daemon returned an invalid agent list.");
138
+ return value.map(decodeAgentRecord);
139
+ }
140
+ export function decodeDaemonStatus(value) {
141
+ const record = asRecord(value);
142
+ const state = requiredString(record?.state, "state");
143
+ if (state !== "ready" && state !== "stopping") {
144
+ throw new LocalAgentDaemonProtocolError("INVALID_RESULT", "Daemon returned an invalid status.");
145
+ }
146
+ return {
147
+ state,
148
+ protocolVersion: requiredInteger(record?.protocolVersion, "protocolVersion"),
149
+ pid: requiredInteger(record?.pid, "pid"),
150
+ endpoint: requiredString(record?.endpoint, "endpoint"),
151
+ startedAt: requiredString(record?.startedAt, "startedAt"),
152
+ activeTurns: requiredInteger(record?.activeTurns, "activeTurns"),
153
+ runtimeCount: requiredInteger(record?.runtimeCount, "runtimeCount"),
154
+ clientConnections: requiredInteger(record?.clientConnections, "clientConnections"),
155
+ };
156
+ }
157
+ export function decodeDaemonLogs(value) {
158
+ if (typeof value !== "string")
159
+ throw new LocalAgentDaemonProtocolError("INVALID_RESULT", "Daemon returned invalid logs.");
160
+ return value;
161
+ }
162
+ export class LocalAgentDaemonProtocolError extends Error {
163
+ code;
164
+ constructor(code, message, options) {
165
+ super(message, options);
166
+ this.code = code;
167
+ this.name = "LocalAgentDaemonProtocolError";
168
+ }
169
+ }
170
+ function decodeEmptyParams(value) {
171
+ if (value === undefined)
172
+ return {};
173
+ const record = asRecord(value);
174
+ if (!record || Object.keys(record).length > 0) {
175
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", "This daemon method does not accept parameters.");
176
+ }
177
+ return {};
178
+ }
179
+ function decodeStartInput(value) {
180
+ const record = asRecord(value);
181
+ return {
182
+ target: requiredString(record?.target, "target"),
183
+ prompt: requiredContentString(record?.prompt, "prompt"),
184
+ workspaceRoot: requiredString(record?.workspaceRoot, "workspaceRoot"),
185
+ workspaceId: optionalString(record?.workspaceId),
186
+ model: optionalString(record?.model),
187
+ effort: optionalString(record?.effort),
188
+ writeMode: decodeWriteMode(record?.writeMode),
189
+ };
190
+ }
191
+ function decodeContinueInput(value) {
192
+ const record = asRecord(value);
193
+ const overrides = asRecord(record?.overrides);
194
+ return {
195
+ id: requiredString(record?.id, "id"),
196
+ prompt: requiredContentString(record?.prompt, "prompt"),
197
+ scope: decodeWorkspaceScope(record?.scope),
198
+ ...(overrides ? { overrides: {
199
+ model: optionalString(overrides.model),
200
+ effort: optionalString(overrides.effort),
201
+ writeMode: decodeWriteMode(overrides.writeMode),
202
+ } } : {}),
203
+ };
204
+ }
205
+ function decodeWorkspaceScope(value) {
206
+ const record = asRecord(value);
207
+ if (!record)
208
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", "Workspace scope is required.");
209
+ return {
210
+ workspaceId: optionalString(record.workspaceId),
211
+ workspaceRoot: requiredString(record.workspaceRoot, "scope.workspaceRoot"),
212
+ };
213
+ }
214
+ function decodeListScope(value) {
215
+ return decodeWorkspaceScope(value);
216
+ }
217
+ function decodeLogsParams(value) {
218
+ if (value === undefined)
219
+ return {};
220
+ const record = asRecord(value);
221
+ if (!record)
222
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", "Log options must be an object.");
223
+ const lines = record.lines;
224
+ if (lines === undefined)
225
+ return {};
226
+ if (typeof lines !== "number" || !Number.isInteger(lines) || lines < 1 || lines > 10_000) {
227
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", "Log lines must be an integer between 1 and 10000.");
228
+ }
229
+ return { lines };
230
+ }
231
+ function decodeLifecycleInput(value) {
232
+ const record = asRecord(value);
233
+ return {
234
+ id: requiredString(record?.id, "id"),
235
+ scope: decodeWorkspaceScope(record?.scope),
236
+ force: optionalBoolean(record?.force),
237
+ };
238
+ }
239
+ function decodeResumeInput(value) {
240
+ const record = asRecord(value);
241
+ const overrides = asRecord(record?.overrides);
242
+ return {
243
+ id: requiredString(record?.id, "id"),
244
+ scope: decodeWorkspaceScope(record?.scope),
245
+ prompt: optionalContentString(record?.prompt),
246
+ ...(overrides ? { overrides: {
247
+ model: optionalString(overrides.model),
248
+ effort: optionalString(overrides.effort),
249
+ writeMode: decodeWriteMode(overrides.writeMode),
250
+ } } : {}),
251
+ };
252
+ }
253
+ function decodeWriteMode(value) {
254
+ if (value === undefined)
255
+ return undefined;
256
+ if (value === "read_only" || value === "allowed" || value === "full_access")
257
+ return value;
258
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", "Invalid write mode.");
259
+ }
260
+ function isLocalAgentStatus(value) {
261
+ return value === "starting" || value === "running" || value === "idle" || value === "paused" || value === "error" || value === "stopped";
262
+ }
263
+ function requiredString(value, field) {
264
+ const result = optionalString(value);
265
+ if (!result)
266
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", `Missing ${field}.`);
267
+ return result;
268
+ }
269
+ function requiredContentString(value, field) {
270
+ const result = optionalContentString(value);
271
+ if (result === undefined)
272
+ throw new LocalAgentDaemonProtocolError("INVALID_PARAMS", `Missing ${field}.`);
273
+ return result;
274
+ }
275
+ function requiredInteger(value, field) {
276
+ if (typeof value !== "number" || !Number.isSafeInteger(value)) {
277
+ throw new LocalAgentDaemonProtocolError("INVALID_PROTOCOL", `Invalid ${field}.`);
278
+ }
279
+ return value;
280
+ }
281
+ function optionalString(value) {
282
+ if (typeof value !== "string")
283
+ return undefined;
284
+ const trimmed = value.trim();
285
+ return trimmed || undefined;
286
+ }
287
+ function optionalContentString(value) {
288
+ if (typeof value !== "string" || !value.trim())
289
+ return undefined;
290
+ return value;
291
+ }
292
+ function optionalBoolean(value) {
293
+ return typeof value === "boolean" ? value : undefined;
294
+ }
295
+ function asRecord(value) {
296
+ if (!value || typeof value !== "object" || Array.isArray(value))
297
+ return undefined;
298
+ return value;
299
+ }
300
+ export function supportedDaemonProtocolVersion() {
301
+ return LOCAL_AGENT_DAEMON_PROTOCOL_VERSION;
302
+ }