@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,294 @@
1
+ # Troubleshooting Gotchas
2
+
3
+ This page collects the setup issues users are most likely to hit.
4
+
5
+ ## `hearth` Command Not Found
6
+
7
+ Use `npx`:
8
+
9
+ ```bash
10
+ npx @sunshinelife83/hearth init
11
+ npx @sunshinelife83/hearth serve
12
+ ```
13
+
14
+ If you installed globally, confirm npm's global bin directory is on `PATH`.
15
+
16
+ ## Unsupported Node Version
17
+
18
+ Hearth requires Node `>=22.19 <27`.
19
+
20
+ Check:
21
+
22
+ ```bash
23
+ node --version
24
+ ```
25
+
26
+ Install Node 22 LTS with your preferred version manager such as `nvm`, `fnm`, or
27
+ `mise`.
28
+
29
+ ## `better-sqlite3` Could Not Load
30
+
31
+ This usually means native dependencies were installed under a different Node
32
+ runtime.
33
+
34
+ Try:
35
+
36
+ ```bash
37
+ npm rebuild better-sqlite3
38
+ ```
39
+
40
+ Then run:
41
+
42
+ ```bash
43
+ npx @sunshinelife83/hearth doctor
44
+ ```
45
+
46
+ Release starts run a native dependency check before launching.
47
+
48
+ ## Public URL Includes `/mcp`
49
+
50
+ Use the origin for setup:
51
+
52
+ ```text
53
+ https://your-tunnel-host.example.com
54
+ ```
55
+
56
+ Use the MCP endpoint in the client:
57
+
58
+ ```text
59
+ https://your-tunnel-host.example.com/mcp
60
+ ```
61
+
62
+ If you saved the wrong value:
63
+
64
+ ```bash
65
+ npx @sunshinelife83/hearth config set publicBaseUrl https://your-tunnel-host.example.com
66
+ ```
67
+
68
+ ## Reverse Proxy `/mcp` Returns 404
69
+ Proxy the whole Hearth server from the root of your tunnel or reverse proxy.
70
+
71
+ Do not mount only `/mcp`: some proxies strip a configured mount path before
72
+ proxying to the local service, so a public `/mcp` request can otherwise arrive
73
+ at Hearth as `/`. Hearth also needs OAuth routes outside `/mcp`, so serving
74
+ the whole local origin is the correct setup.
75
+
76
+ ## Tunnel URL Changed
77
+
78
+ Temporary tunnels often change URLs between runs.
79
+
80
+ Update the configured URL:
81
+
82
+ ```bash
83
+ npx @sunshinelife83/hearth config set publicBaseUrl https://new-tunnel.example.com
84
+ ```
85
+
86
+ For a stable URL:
87
+
88
+ ```bash
89
+ npx @sunshinelife83/hearth config set publicBaseUrl https://hearth.example.com
90
+ ```
91
+
92
+ ## Host Header Or 403 Problems
93
+
94
+ Hearth derives allowed hosts from the configured public URL.
95
+
96
+ Run:
97
+
98
+ ```bash
99
+ npx @sunshinelife83/hearth doctor
100
+ ```
101
+
102
+ Confirm the public URL hostname appears in allowed hosts. If you changed tunnel
103
+ URLs, update `publicBaseUrl`.
104
+
105
+ For intentional local debugging only, set `server.allowedHosts` to `["*"]` in
106
+ `~/.hearth/config.jsonc`.
107
+
108
+ ## OAuth Redirect Host Rejected
109
+
110
+ By default, Hearth allows redirects for:
111
+
112
+ ```text
113
+ chatgpt.com (and subdomains)
114
+ claude.ai (and subdomains)
115
+ anthropic.com (and subdomains)
116
+ localhost
117
+ 127.0.0.1
118
+ ```
119
+
120
+ If another MCP client uses a different redirect host, add it to
121
+ `oauth.allowedRedirectHosts` in `~/.hearth/config.jsonc`. Subdomains of a
122
+ listed host are accepted automatically.
123
+
124
+ ## Owner Password Not Accepted
125
+
126
+ Make sure you are entering the Owner password from:
127
+
128
+ ```text
129
+ ~/.hearth/auth.json
130
+ ```
131
+
132
+ To regenerate setup:
133
+
134
+ ```bash
135
+ npx @sunshinelife83/hearth init --force
136
+ (`--force` now rotates the Owner password and prints the new value in ChatGPT setups; existing access tokens stay valid until they expire — revoke them via the OAuth revocation endpoint if needed)
137
+ ```
138
+
139
+ ## Unknown `workspaceId`
140
+
141
+ `workspaceId` values are session identifiers. If the server restarts and the
142
+ client receives an unknown workspace error, call `open_workspace` again for that
143
+ project.
144
+
145
+ Workspace session metadata is persisted. ChatGPT may provide optional
146
+ conversation metadata that lets Hearth resume the same checkout workspace for
147
+ the same project in that conversation; repeated opens reuse the `workspaceId`
148
+ and do not repeat context already provided for that reused checkout. Worktree
149
+ mode always creates a new isolated workspace with its own complete context.
150
+ Hosts without supported conversation metadata receive a normal new workspace.
151
+ In all cases, continue passing the `workspaceId` returned by `open_workspace` to
152
+ later tools. Other MCP hosts use this explicit workspace workflow as well.
153
+
154
+ To review work, call `show_changes` once after the final related file change. It
155
+ shows the combined changes and advances the review point automatically.
156
+
157
+ ## Data Retention
158
+
159
+ Hearth does not currently prune workspace sessions, conversation bindings,
160
+ or review refs. A future product retention policy will define safe cleanup for
161
+ these records; no automatic deletion is performed today.
162
+
163
+ ## MCP Workspace Path Rejected
164
+
165
+ The path passed to `open_workspace` must be inside one of the allowed roots
166
+ configured during ChatGPT setup. Direct `hearth agents` commands instead use
167
+ the current local project and are not gated by MCP allowed roots.
168
+
169
+ Run:
170
+
171
+ ```bash
172
+ npx @sunshinelife83/hearth config get
173
+ ```
174
+
175
+ Then either open a project under an allowed root or rerun setup:
176
+
177
+ ```bash
178
+ npx @sunshinelife83/hearth init --force
179
+ ```
180
+
181
+ ## Worktree Mode Fails
182
+
183
+ Worktree mode requires:
184
+
185
+ - Git installed
186
+ - the path is inside a Git repository
187
+ - the repository has at least one commit
188
+ - the requested `baseRef` resolves to a commit
189
+
190
+ For a new repository, create the first commit or use checkout mode.
191
+
192
+ Uncommitted source checkout changes are not copied into the managed worktree.
193
+ Commit, stash, or ask the model to work in checkout mode if those changes are
194
+ needed.
195
+
196
+ ## Windows Shell Commands Fail
197
+
198
+ Hearth shell execution requires Bash. Native PowerShell and `cmd.exe` command
199
+ execution are not supported yet.
200
+
201
+ Install Git for Windows and use Git Bash, or use WSL, MSYS2, or Cygwin Bash.
202
+
203
+ Run:
204
+
205
+ ```bash
206
+ npx @sunshinelife83/hearth doctor
207
+ ```
208
+
209
+ Confirm Bash is detected.
210
+
211
+ ## Skills Do Not Appear
212
+
213
+ Skills are enabled by default. Confirm `skills.enabled` is `true` in
214
+ `~/.hearth/config.jsonc`.
215
+
216
+ Hearth looks in standard Agent Skills locations:
217
+
218
+ - `~/.agents/skills`
219
+ - project `.agents/skills`
220
+ - `~/.hearth/skills`
221
+
222
+ It also checks compatibility and custom paths:
223
+
224
+ - the bundled `subagents` skill when Subagents are enabled, unless `~/.hearth/skills/subagents/SKILL.md` exists
225
+ - `skills.agentDir/skills`, defaulting to `~/.codex/skills`
226
+ - additional paths from `skills.paths`
227
+
228
+ When Subagents are enabled, Hearth loads agent profiles from
229
+ `~/.hearth/agents/*.md` and project `.hearth/agents/*.md`, then exposes a
230
+ compact profile catalog through `open_workspace`. The bundled
231
+ `subagents` skill keeps the model-facing workflow to
232
+ `hearth agents targets`, `hearth agents ls`, `hearth agents run`,
233
+ `hearth agents continue`, and `hearth agents show`.
234
+ Those commands automatically manage the internal local agent daemon; `hearth
235
+ serve` is not a prerequisite.
236
+ `hearth agents ls` lists existing subagent sessions, not profile
237
+ definitions.
238
+
239
+ For a Coding Agent, run the installation command printed by
240
+ `hearth init`:
241
+
242
+ ```bash
243
+ npx skills add Waishnav/hearth --skill subagents --global
244
+ ```
245
+
246
+ The Skills CLI handles agent discovery and installation. Hearth setup does
247
+ not copy files into agent skill directories.
248
+
249
+ Packaged agent profile examples under `examples/agents/` are starter templates.
250
+ Copy or adapt them into one of the active profile directories before use.
251
+
252
+ Legacy project paths such as `.pi/skills` can be added to `skills.paths` when needed.
253
+
254
+ If a skill appears in `open_workspace`, the model should read that skill's
255
+ `SKILL.md` before following it. Hearth permits reads within advertised skill
256
+ directories without tracking whether `SKILL.md` was read first.
257
+
258
+ ## Review Card Does Not Appear
259
+
260
+ Hearth attaches widget UI only to `open_workspace` and `show_changes`.
261
+ Ordinary reads, edits, and commands intentionally render as normal tool results
262
+ to avoid one iframe per call. Plain MCP clients may ignore ChatGPT Apps widget
263
+ metadata and only show text results; `show_changes` remains available there.
264
+
265
+ If both cards are missing in ChatGPT, confirm that `ui.enabled` is not `false`
266
+ in `~/.hearth/config.jsonc` and reconnect the MCP server.
267
+
268
+ Historical `show_changes` cards use the `reviewRef` in their structured result
269
+ to recover the exact Git-backed review when a host reloads the app without its
270
+ original result metadata. `open_workspace` can rebuild its card directly from
271
+ its structured result.
272
+
273
+ ## OpenCode Backend Fails With "Unexpected Server Error"
274
+
275
+ If every opencode turn fails with `PROVIDER_EXECUTION_ERROR: ... Unexpected
276
+ server error` while `opencode run` in a terminal works, the opencode server's
277
+ local database (`~/.local/share/opencode/opencode.db`) is in a broken state:
278
+ sessions created through the API land outside the table that message inserts
279
+ reference, so every prompt and agent-switch is rejected. Hearth cannot repair
280
+ another program's database.
281
+
282
+ Confirm it without touching your data:
283
+
284
+ ```bash
285
+ mkdir -p /tmp/oc-fresh-data && XDG_DATA_HOME=/tmp/oc-fresh-data opencode serve --hostname=127.0.0.1 --port=18927 &
286
+ # dispatch one opencode turn through Hearth with XDG_DATA_HOME set for the daemon,
287
+ # or simply: if a fresh data dir works, the old database is the cause.
288
+ ```
289
+
290
+ Remedies: back up then reset the opencode database (you lose TUI session
291
+ history), or use the `codex` backend, which is unaffected. Hearth-side, every
292
+ opencode runtime now gets its own server port (no shared-4096 collisions),
293
+ redundant agent switches are skipped, and provider failures carry the
294
+ underlying cause text instead of a bare "execution failed".
@@ -0,0 +1,101 @@
1
+ # Local agent daemon
2
+
3
+ Local agent execution is owned by an on-demand `hearth-agentd` process, not
4
+ by the MCP server and not by an individual CLI invocation. The daemon is an
5
+ internal implementation detail: the normal workflow remains:
6
+
7
+ ```text
8
+ hearth agents run/continue/show/ls
9
+
10
+
11
+ hearth-agentd
12
+
13
+ ├── LocalAgentManager
14
+ ├── LocalAgentStore
15
+ ├── LocalAgentRuntimePool
16
+ └── provider runtimes
17
+ ```
18
+
19
+ The CLI starts the daemon automatically when an agent command needs it. The
20
+ MCP server can use the same local client when an MCP operation needs agent
21
+ functionality, but `hearth serve` is not required for local-agent execution.
22
+ The daemon is scoped to one Hearth `stateDir`, so one SQLite store and one
23
+ runtime owner serve all clients using that configuration.
24
+
25
+ Communication uses a private Unix domain socket on Linux/macOS or a named pipe
26
+ on Windows. The endpoint is not exposed through the public MCP HTTP port.
27
+ Provider session identifiers and logical agent records are durable; live
28
+ provider runtimes are disposable and may be recreated after a daemon restart.
29
+ Expected subagent failures cross the daemon boundary as structured error codes,
30
+ not message-string conventions. Agent records in `error` state retain the safe
31
+ message plus `errorCode` and `errorRetryable` fields so callers can distinguish
32
+ provider cancellation, provider availability, workspace conflicts, daemon
33
+ timeouts, and similar recovery categories after a background turn completes.
34
+ Internal provider causes are kept out of the daemon payload and persisted JSON.
35
+
36
+ The implementation treats `better-result` as the application-failure boundary,
37
+ not as a replacement for every exception. Expected target, scope, provider,
38
+ store, and daemon failures return typed Results. Sequential fallible setup uses
39
+ `Result.gen` when it makes the success path clearer, small Result-to-Result
40
+ transformations use `map`/`andThen`, and error policy at serialization or IPC
41
+ boundaries uses exhaustive tagged-error matching. Programmer defects and broken
42
+ invariants remain exceptions; cleanup and shutdown also stay best-effort so a
43
+ secondary release failure cannot replace the primary agent failure.
44
+
45
+ The daemon state directory contains the socket or pipe identity, an atomic
46
+ lock, a PID marker, and diagnostic logs. A second client cannot start another
47
+ daemon for the same state directory. Stale lock and socket files are recovered
48
+ only after the recorded PID is no longer alive.
49
+
50
+ The daemon is started on demand and may exit after its active turns, clients,
51
+ and warm runtime idle periods have ended. Users do not need to manage it during
52
+ normal operation. Diagnostic commands are available for startup, process, and
53
+ cleanup problems:
54
+
55
+ ```bash
56
+ hearth agents daemon status
57
+ hearth agents daemon stop
58
+ hearth agents daemon logs
59
+ ```
60
+
61
+ Agent commands accept `--json` when a machine-readable response is needed.
62
+ They emit one compact JSON value. `run` and `continue` return only the logical
63
+ agent ID and status, `ls` returns session summaries, and `show` returns the
64
+ response or structured failure for one agent. Internal workspace paths,
65
+ provider session IDs, timestamps, and prior responses are not included in list
66
+ or receipt output. Immediate failures are emitted as
67
+ `{ error: { code, message, retryable, ... } }` with a non-zero exit code.
68
+ Successful `daemon status` and `daemon stop` output the daemon status object,
69
+ and successful `daemon logs` output is `{ "logs": "<text>" }`.
70
+
71
+ Agent identity is explicit at the client boundary. `agents run` starts a new
72
+ logical agent from a profile or provider; `agents continue <id>` continues an
73
+ existing logical agent. Provider session IDs are never accepted as logical
74
+ agent IDs, and the daemon does not resolve ambiguous prefixes.
75
+
76
+ Shutdown gives active turns a bounded graceful window. If that window expires,
77
+ the process exits with active records left durable; the next daemon startup
78
+ reconciles stale `starting` and `running` records to `error` without discarding
79
+ their `providerSessionId` or `latestResponse`.
80
+
81
+ ## Hearth additions (protocol v4)
82
+
83
+ The daemon protocol moved to version 4 with full agent lifecycle methods,
84
+ exposed to MCP clients through the `agent_*` tools:
85
+
86
+ | Method | Purpose |
87
+ |---|---|
88
+ | `agent.pause` `{ id, scope, force? }` | Pause an agent. Instant between turns; with `force` the running turn is interrupted by closing its runtime. Status becomes `paused`. |
89
+ | `agent.resume` `{ id, scope, prompt?, overrides? }` | Start a new turn on the durable provider session from `paused` (also `idle`/`error`). |
90
+ | `agent.stop` `{ id, scope, force? }` | Stop an agent; `force` interrupts a running turn. Terminal status `stopped`. |
91
+ | `agent.cancel` (client-side) | `stop` with `force: true`. |
92
+
93
+ `agent.get` responses now include `latestOutput` — the bounded tail (64 KB) of
94
+ the in-flight turn's incremental assistant output, streamed from providers
95
+ that support it (ACP agents, Codex, Claude). Pi and OpenCode report output
96
+ only when the turn completes (provider limitation, documented in
97
+ docs/adr/hearth-x-implementation-adrs.md, ADR-017).
98
+
99
+ Cancellation closes the agent's runtime immediately (`agent_cancelled` close
100
+ reason); a turn that completes successfully after a stop/pause request never
101
+ restores `idle` — the requested terminal status wins.
@@ -0,0 +1,197 @@
1
+ # Security Model
2
+
3
+ Hearth exposes local coding capabilities over MCP. Treat it as remote access
4
+ to your development machine.
5
+
6
+ The security model is simple:
7
+
8
+ - you choose a narrow filesystem allowlist
9
+ - the MCP endpoint requires OAuth approval with your Owner password
10
+ - Host headers are allowlisted from the configured public URL
11
+ - every coding action happens through explicit MCP tool calls
12
+
13
+ ## Filesystem Allowlist
14
+
15
+ Hearth only opens workspaces under configured roots.
16
+
17
+ Good examples:
18
+
19
+ ```text
20
+ ~/work
21
+ ~/personal/open-source
22
+ ```
23
+
24
+ Avoid broad roots:
25
+
26
+ ```text
27
+ ~
28
+ /
29
+ C:\
30
+ ```
31
+
32
+ The narrower the root, the easier it is to reason about what the MCP client can
33
+ reach.
34
+
35
+ ## Owner Password
36
+
37
+ `hearth init` generates an Owner password and stores it in:
38
+
39
+ ```text
40
+ ~/.hearth/auth.json
41
+ ```
42
+
43
+ When an MCP client connects, Hearth shows an approval page. Enter the Owner
44
+ password only when you intentionally want that client to access this server.
45
+
46
+ For env-driven deployments, set a long random value:
47
+
48
+ ```bash
49
+ HEARTH_OAUTH_OWNER_TOKEN="$(openssl rand -base64 32)"
50
+ ```
51
+
52
+ ## Public URL And Host Allowlist
53
+
54
+ Hearth needs `server.publicBaseUrl` in `config.jsonc` so MCP clients can
55
+ discover OAuth metadata and connect to the correct resource.
56
+
57
+ The value should be the origin only:
58
+
59
+ ```text
60
+ https://your-tunnel-host.example.com
61
+ ```
62
+
63
+ Do not include `/mcp` in `server.publicBaseUrl`.
64
+
65
+ By default, Hearth derives allowed Host headers from the local host and public
66
+ URL. Put `"*"` in `server.allowedHosts` only for intentional local debugging.
67
+
68
+ ## Machine Identity Is Diagnostic, Not A Security Boundary
69
+
70
+ `hearth id` prints a stable random label (`hearth-xxxx`) stored in the state
71
+ directory (`machine.json`). It helps the owner recognize which PC a banner,
72
+ dashboard, approval page, `/healthz` response, or log line came from.
73
+
74
+ It does not authenticate the machine: copying the state directory copies the
75
+ identity, so it cannot prove which physical PC answered, cannot prevent URL
76
+ reuse across PCs, and cannot stop cloning. Keep one public URL per PC as
77
+ operational hygiene, and rely on the Owner password plus OAuth tokens — not
78
+ the label — for access decisions.
79
+
80
+ Future direction: a per-device keypair whose private key never leaves the PC
81
+ (`0600` in the state directory) and whose public fingerprint is shown in
82
+ `hearth id`, `/healthz`, the dashboard, and approvals, so audit entries can
83
+ bind to an unclonable key.
84
+
85
+ ## Tunnels
86
+
87
+ Hearth does not manage tunnels. Your tunnel or reverse proxy should point to:
88
+
89
+ ```text
90
+ http://127.0.0.1:7176
91
+ ```
92
+
93
+ Prefer adding an identity-aware proxy in front of public tunnels. Hearth
94
+ OAuth still protects the MCP endpoint, but the tunnel URL should not be
95
+ treated as a secret.
96
+
97
+ ## Shell Access
98
+
99
+ The shell tool is powerful by design. It is meant for tests, builds, git, and
100
+ package scripts.
101
+
102
+ Filesystem path containment applies to Hearth file tools. Shell commands run
103
+ as local commands and can do what your user account can do. This is why the MCP
104
+ client must be trusted and the Owner password must stay private.
105
+
106
+ ## Worktrees
107
+
108
+ Managed worktrees reduce accidental edits to your active checkout, but they are
109
+ not a security boundary. They are a workflow boundary for isolated coding
110
+ sessions.
111
+
112
+ ## Native File Download
113
+
114
+ Native file download is an opt-in, one-shot transfer into an already-open
115
+ workspace. `download_artifact` accepts the MCP host's native file value, the
116
+ `workspaceId` returned by `open_workspace`, and an unused relative destination
117
+ path. It returns only the workspace-relative path and does not create a
118
+ persistent artifact service or reusable artifact ID.
119
+
120
+ Hearth accepts only the documented native-file object and trusted OpenAI
121
+ download hosts and redirects. Arbitrary URL strings, local source paths,
122
+ credentials, malformed references, and unknown object fields are rejected.
123
+
124
+ Absolute paths, traversal, symlinked parents, and existing destinations also
125
+ fail closed. Downloads stream under the configured per-file limit and are
126
+ published without overwrite as owner-only files. Hearth does not extract or
127
+ execute transferred content.
128
+
129
+ ## Logs
130
+
131
+ By default, Hearth logs requests and tool calls. Shell command previews are
132
+ disabled unless `logging.shellCommands` is `true`.
133
+
134
+ Do not enable shell command logging if commands may contain secrets.
135
+
136
+ Artifact tool logs contain bounded workspace ID, validated hostname,
137
+ workspace-relative output path, byte count, hash, duration, and status metadata.
138
+ `download_artifact` does not log the opaque file value. Raw content, connector
139
+ references, native file IDs, bearer credentials, presigned URLs, host paths,
140
+ temporary paths, and base64 chunks are never included in tool logs or tool
141
+ results.
142
+
143
+ ## Command policy and environment filtering (Hearth)
144
+ Model-invoked shell tools (`exec_command`, `bash`) pass through a policy gate
145
+ before any process spawns:
146
+
147
+ - **Tier 0** — inspection (`git status`, `ls`, `grep`, ...): allowed in every mode.
148
+ - **Tier 1** — ordinary workspace work (builds, tests, local edits): allowed above readonly.
149
+ - **Tier 2** — outside-effect commands (network fetches, package installs, recursive
150
+ deletes, `git push`, permission changes, cloud CLIs): denied in readonly, require an
151
+ explicit `approvedByUser` claim in `supervised` mode (after the user approves in the
152
+ conversation; the claim is audited), and run freely in `autonomous` mode after a
153
+ best-effort git snapshot.
154
+ - **Tier 3** — always blocked with no approval path: privilege escalation (`sudo`, `su`),
155
+ system/power management, service managers, cron, piping remote scripts into a shell,
156
+ SSH remote execution, and shell-profile tampering.
157
+
158
+ Set the mode with `execution.mode` in `config.jsonc` (`readonly`, `supervised` — the
159
+ default — or `autonomous`). Every decision is logged as a `policy_decision` event.
160
+
161
+ Commands executed by model-invoked shell tools inherit a conservative environment
162
+ allowlist instead of the full user environment, so model-run commands cannot read
163
+ API keys or cloud credentials from the environment (escape hatches:
164
+ `execution.envAllowAll`, `execution.envAllowlist`). Provider CLIs started by the
165
+ subagent layer keep the full environment by design and are constrained by the
166
+ allowed-roots enforcement described in
167
+ docs/adr/hearth-x-implementation-adrs.md (ADR-014/015).
168
+
169
+ Workspace snapshots (`create_snapshot`, `list_snapshots`, `rollback_snapshot`) capture
170
+ the working tree as git refs under `refs/hearth/snapshots/...`; rollback restores
171
+ content without touching HEAD and is subject to the same tier-2 policy.
172
+
173
+ The OAuth consent page is CSRF-protected (HMAC bound to the authorization request,
174
+ `frame-ancestors 'none'`), and the auth endpoints are rate limited (`/authorize`,
175
+ `/register`, `/token`, plus a dedicated failure counter for the owner password).
176
+ Enable `server.trustProxy` when running behind a tunnel so rate-limit keys use the
177
+ real client IP.
178
+
179
+ ## OS sandbox (platform honesty)
180
+
181
+ Autonomous shell execution and verification gates are wrapped in an OS sandbox
182
+ when an adapter is available. The sandbox is a hardening layer on top of the
183
+ policy engine, never the only boundary.
184
+
185
+ | Platform | Adapter | What it actually provides |
186
+ |---|---|---|
187
+ | Linux | bubblewrap (`bwrap`) | Read-only root bind, workspace + `/tmp` writable, optional `--unshare-net`. Real filesystem containment. |
188
+ | macOS | `sandbox-exec` (seatbelt) | Profile denying writes outside the workspace and temp dirs. Approximate; not a strict container. |
189
+ | Windows | none | No equivalent exists here. Containers are the recommended hardening path. |
190
+
191
+ Fail-closed default: `execution.requireSandboxForAutonomous` defaults to
192
+ `true`, so autonomous tier-2 commands are **denied** (with instructions) when
193
+ no adapter is available — notably on Windows — instead of running silently
194
+ unsandboxed. Opt out explicitly (`execution.requireSandboxForAutonomous:
195
+ false`, globally or per workspace profile) only when you accept unsandboxed
196
+ autonomy. Per-workspace `sandbox: "auto" | "none"` and `sandboxNetwork:
197
+ "allow" | "deny"` override the global setting for one workspace only.