@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.
- package/LICENSE +21 -0
- package/README.md +323 -0
- package/bin/hearth-agentd.js +4 -0
- package/bin/hearth.js +4 -0
- package/bin/run-entrypoint.js +20 -0
- package/dist/agent-tools.js +738 -0
- package/dist/app-version.js +16 -0
- package/dist/apply-patch.js +402 -0
- package/dist/artifact-error.js +8 -0
- package/dist/artifact-tools.js +377 -0
- package/dist/cli-workspace.js +36 -0
- package/dist/cli.js +1086 -0
- package/dist/config-migration.js +82 -0
- package/dist/config-schema.js +136 -0
- package/dist/config.js +115 -0
- package/dist/context/context-tools.js +150 -0
- package/dist/context/repo-map.js +102 -0
- package/dist/dashboard/app.js +226 -0
- package/dist/dashboard/index.html +45 -0
- package/dist/dashboard/landing.html +57 -0
- package/dist/dashboard/styles.css +23 -0
- package/dist/dashboard.js +271 -0
- package/dist/db/client.js +29 -0
- package/dist/db/migrations.js +262 -0
- package/dist/db/schema.js +85 -0
- package/dist/device-tokens.js +61 -0
- package/dist/git-worktrees.js +134 -0
- package/dist/git.js +41 -0
- package/dist/incoming-artifacts.js +378 -0
- package/dist/local-agent-acp.js +768 -0
- package/dist/local-agent-adapters.js +20 -0
- package/dist/local-agent-availability.js +92 -0
- package/dist/local-agent-catalog.js +51 -0
- package/dist/local-agent-claude.js +334 -0
- package/dist/local-agent-client.js +519 -0
- package/dist/local-agent-codex.js +532 -0
- package/dist/local-agent-config.js +34 -0
- package/dist/local-agent-daemon-lifecycle.js +195 -0
- package/dist/local-agent-daemon-main.js +86 -0
- package/dist/local-agent-daemon-protocol.js +302 -0
- package/dist/local-agent-daemon.js +407 -0
- package/dist/local-agent-errors.js +378 -0
- package/dist/local-agent-grok.js +202 -0
- package/dist/local-agent-manager.js +715 -0
- package/dist/local-agent-opencode.js +463 -0
- package/dist/local-agent-path.js +24 -0
- package/dist/local-agent-pi-sandbox.js +472 -0
- package/dist/local-agent-pi.js +298 -0
- package/dist/local-agent-presentation.js +104 -0
- package/dist/local-agent-profiles.js +127 -0
- package/dist/local-agent-runtime-pool.js +481 -0
- package/dist/local-agent-runtime.js +1 -0
- package/dist/local-agent-store.js +193 -0
- package/dist/local-agent-targets.js +97 -0
- package/dist/logger.js +97 -0
- package/dist/machine-id.js +35 -0
- package/dist/mcp-modern-server.js +65 -0
- package/dist/oauth-provider.js +331 -0
- package/dist/oauth-store.js +144 -0
- package/dist/onboarding.js +35 -0
- package/dist/orchestration/brief.js +70 -0
- package/dist/orchestration/lanes.js +145 -0
- package/dist/orchestration/result.js +46 -0
- package/dist/orchestration/scope.js +61 -0
- package/dist/pi-tools.js +58 -0
- package/dist/policy/command-policy.js +104 -0
- package/dist/policy/env-allowlist.js +96 -0
- package/dist/policy/sandbox.js +68 -0
- package/dist/policy/workspace-profiles.js +47 -0
- package/dist/process-journal.js +116 -0
- package/dist/process-platform.js +49 -0
- package/dist/process-sessions.js +388 -0
- package/dist/rate-limit.js +77 -0
- package/dist/request-meta.js +9 -0
- package/dist/review-checkpoints.js +349 -0
- package/dist/roots.js +37 -0
- package/dist/server-shutdown.js +12 -0
- package/dist/server.js +980 -0
- package/dist/skills.js +84 -0
- package/dist/snapshot-manager.js +123 -0
- package/dist/stdio-server.js +80 -0
- package/dist/task-store.js +203 -0
- package/dist/task-tools.js +455 -0
- package/dist/tool-surfaces/claude.js +220 -0
- package/dist/tool-surfaces/codex.js +255 -0
- package/dist/tool-surfaces/index.js +15 -0
- package/dist/tool-surfaces/shared.js +228 -0
- package/dist/tool-surfaces/types.js +27 -0
- package/dist/ui/.vite/manifest.json +2544 -0
- package/dist/ui/assets/abap-CLvhMVsD.js +1 -0
- package/dist/ui/assets/actionscript-3--17pq3dv.js +1 -0
- package/dist/ui/assets/ada-C5qYipkI.js +1 -0
- package/dist/ui/assets/andromeeda-vGVdxbeo.js +1 -0
- package/dist/ui/assets/angular-html-DrbO3_Xe.js +1 -0
- package/dist/ui/assets/angular-ts-CmTVzHJx.js +1 -0
- package/dist/ui/assets/apache-U0d_L8uA.js +1 -0
- package/dist/ui/assets/apex-CGTLDQj6.js +1 -0
- package/dist/ui/assets/apl-BOpCpqXf.js +1 -0
- package/dist/ui/assets/applescript-CCn79oCD.js +1 -0
- package/dist/ui/assets/ara-4CJ0cIlV.js +1 -0
- package/dist/ui/assets/asciidoc-DE70LPWp.js +1 -0
- package/dist/ui/assets/asm-Cmm7eHzH.js +1 -0
- package/dist/ui/assets/astro-CxPeBwei.js +1 -0
- package/dist/ui/assets/aurora-x-CDeNXAV0.js +1 -0
- package/dist/ui/assets/awk-BWXHIvNe.js +1 -0
- package/dist/ui/assets/ayu-dark-DluEY0Gj.js +1 -0
- package/dist/ui/assets/ayu-light-C3h-C4tm.js +1 -0
- package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +1 -0
- package/dist/ui/assets/ballerina-B7ZEbQpA.js +1 -0
- package/dist/ui/assets/bat-Bo4NYOV-.js +1 -0
- package/dist/ui/assets/beancount-D-usSTwE.js +1 -0
- package/dist/ui/assets/berry-DKpUyyne.js +1 -0
- package/dist/ui/assets/bibtex-Ci_nEsc7.js +1 -0
- package/dist/ui/assets/bicep-CUHmPFLl.js +1 -0
- package/dist/ui/assets/bird2-C2hNVINV.js +1 -0
- package/dist/ui/assets/blade-DtsAAG4P.js +1 -0
- package/dist/ui/assets/bsl-BkkzgIyY.js +1 -0
- package/dist/ui/assets/c-D9hLjNUM.js +1 -0
- package/dist/ui/assets/c3-CnJL0r0V.js +1 -0
- package/dist/ui/assets/cadence-CQ2zXKGN.js +1 -0
- package/dist/ui/assets/cairo-DLTphjLi.js +1 -0
- package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
- package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
- package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
- package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
- package/dist/ui/assets/clarity-SemFz856.js +1 -0
- package/dist/ui/assets/clojure-DqKBuwfJ.js +1 -0
- package/dist/ui/assets/cmake-Bj61d0ZC.js +1 -0
- package/dist/ui/assets/cobol-C1SWlvZm.js +1 -0
- package/dist/ui/assets/codeowners-C8r90Shi.js +1 -0
- package/dist/ui/assets/codeql-oeQT6MSM.js +1 -0
- package/dist/ui/assets/coffee-B71R3v2U.js +1 -0
- package/dist/ui/assets/common-lisp-Cv5bFMCO.js +1 -0
- package/dist/ui/assets/coq-BrsZFFmf.js +1 -0
- package/dist/ui/assets/cpp--5a4c3v4.js +1 -0
- package/dist/ui/assets/crystal-AtqWYtE0.js +1 -0
- package/dist/ui/assets/csharp-Ct8U2NOr.js +1 -0
- package/dist/ui/assets/css-CbqKSHI-.js +1 -0
- package/dist/ui/assets/csv-Dx-8-gkx.js +1 -0
- package/dist/ui/assets/cue-CE9AQfxI.js +1 -0
- package/dist/ui/assets/cypher-ClKdZ_lG.js +1 -0
- package/dist/ui/assets/d-qD-0Kul2.js +1 -0
- package/dist/ui/assets/dark-plus-Cs2F2srj.js +1 -0
- package/dist/ui/assets/dart-DkHntEIa.js +1 -0
- package/dist/ui/assets/dax-BkyTk9wS.js +1 -0
- package/dist/ui/assets/desktop-Dlh5hvp9.js +1 -0
- package/dist/ui/assets/diff-woXpYk--.js +1 -0
- package/dist/ui/assets/docker-IyjqRm3v.js +1 -0
- package/dist/ui/assets/dotenv-_5a1GRtc.js +1 -0
- package/dist/ui/assets/dracula-BHWKrbxM.js +1 -0
- package/dist/ui/assets/dracula-soft-5eyTD99u.js +1 -0
- package/dist/ui/assets/dream-maker-DW3nJb8Q.js +1 -0
- package/dist/ui/assets/edge-BPwY_RrJ.js +1 -0
- package/dist/ui/assets/elixir-DVH2yLJf.js +1 -0
- package/dist/ui/assets/elm-BrleA6gS.js +1 -0
- package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +1 -0
- package/dist/ui/assets/erb-2SHiYe30.js +1 -0
- package/dist/ui/assets/erlang-Cphh6RMH.js +1 -0
- package/dist/ui/assets/everforest-dark-sB-x3p7T.js +1 -0
- package/dist/ui/assets/everforest-light-Df2xbC6M.js +1 -0
- package/dist/ui/assets/fennel-DQxkIbk2.js +1 -0
- package/dist/ui/assets/fish-BJitypiv.js +1 -0
- package/dist/ui/assets/fluent-C03EYrpw.js +1 -0
- package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
- package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +1 -0
- package/dist/ui/assets/fsharp-D13ZGOAj.js +1 -0
- package/dist/ui/assets/gdresource-C0sCabJj.js +1 -0
- package/dist/ui/assets/gdscript-Cp2uCuqX.js +1 -0
- package/dist/ui/assets/gdshader-CBce3t8t.js +1 -0
- package/dist/ui/assets/genie-CV2tkWYe.js +1 -0
- package/dist/ui/assets/gherkin-DExj1W_8.js +1 -0
- package/dist/ui/assets/git-commit-BSykSTBG.js +1 -0
- package/dist/ui/assets/git-rebase-Bc7atMaV.js +1 -0
- package/dist/ui/assets/github-dark-C-LZuMrd.js +1 -0
- package/dist/ui/assets/github-dark-default-DXG-b-1a.js +1 -0
- package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
- package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
- package/dist/ui/assets/github-light-EUqPIrTm.js +1 -0
- package/dist/ui/assets/github-light-default-BXViO-2h.js +1 -0
- package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +1 -0
- package/dist/ui/assets/gleam-CSRkHgEL.js +1 -0
- package/dist/ui/assets/glimmer-js-DXeTDPtW.js +1 -0
- package/dist/ui/assets/glimmer-ts-CEOoXHU4.js +1 -0
- package/dist/ui/assets/glsl-5-43-Gsg.js +1 -0
- package/dist/ui/assets/gn-ilITqXS6.js +1 -0
- package/dist/ui/assets/gnuplot-7GGW24-e.js +1 -0
- package/dist/ui/assets/go-BJwz_mda.js +1 -0
- package/dist/ui/assets/graphql-Bk7Ah1KA.js +1 -0
- package/dist/ui/assets/groovy-CacY0gHj.js +1 -0
- package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
- package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
- package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
- package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
- package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
- package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
- package/dist/ui/assets/hack-DUHz4rCJ.js +1 -0
- package/dist/ui/assets/haml-BPCuuTPR.js +1 -0
- package/dist/ui/assets/handlebars-CHxmUsnU.js +1 -0
- package/dist/ui/assets/haskell-D8IpX4py.js +1 -0
- package/dist/ui/assets/haxe-OTjmBuCE.js +1 -0
- package/dist/ui/assets/hcl-Dh228itO.js +1 -0
- package/dist/ui/assets/hjson-CxZEssPk.js +1 -0
- package/dist/ui/assets/hlsl-Cvrh5tZx.js +1 -0
- package/dist/ui/assets/horizon-CE9ld1lL.js +1 -0
- package/dist/ui/assets/horizon-bright-Br1oVSNq.js +1 -0
- package/dist/ui/assets/houston-CsvMBhTu.js +1 -0
- package/dist/ui/assets/html-BBJqizz0.js +1 -0
- package/dist/ui/assets/html-derivative-ShTPCcKN.js +1 -0
- package/dist/ui/assets/http-VFTyziwA.js +1 -0
- package/dist/ui/assets/hurl-B8yxTa4r.js +1 -0
- package/dist/ui/assets/hxml-B0Qn7Nwc.js +1 -0
- package/dist/ui/assets/hy-CZbG8q4J.js +1 -0
- package/dist/ui/assets/imba-DsUTQ-LC.js +1 -0
- package/dist/ui/assets/ini-B5eOa1yu.js +1 -0
- package/dist/ui/assets/java-BZ5DAgJZ.js +1 -0
- package/dist/ui/assets/javascript-C_zuIEaC.js +1 -0
- package/dist/ui/assets/jinja-DWd6xfNr.js +1 -0
- package/dist/ui/assets/jison-BbY63d1V.js +1 -0
- package/dist/ui/assets/json-C4DnajZs.js +1 -0
- package/dist/ui/assets/json5-BR5RXkoi.js +1 -0
- package/dist/ui/assets/jsonc-CYpm1nAK.js +1 -0
- package/dist/ui/assets/jsonl-CmCQp5Yx.js +1 -0
- package/dist/ui/assets/jsonnet-CJTPZ8u_.js +1 -0
- package/dist/ui/assets/jssm-DXw9l8Rf.js +1 -0
- package/dist/ui/assets/jsx-C4AACieZ.js +1 -0
- package/dist/ui/assets/julia-sRu7EFMW.js +1 -0
- package/dist/ui/assets/just-DpZ9Sx1v.js +1 -0
- package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
- package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +1 -0
- package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +1 -0
- package/dist/ui/assets/kdl-CsD5j6eV.js +1 -0
- package/dist/ui/assets/kotlin-DhhofPvG.js +1 -0
- package/dist/ui/assets/kusto-BUv0MjJC.js +1 -0
- package/dist/ui/assets/laserwave-C_8bwKvT.js +1 -0
- package/dist/ui/assets/latex-B6a_uum7.js +1 -0
- package/dist/ui/assets/lean-CewbzKMR.js +1 -0
- package/dist/ui/assets/less-DVTAwKKz.js +1 -0
- package/dist/ui/assets/light-plus-DVQuIRkW.js +1 -0
- package/dist/ui/assets/liquid-B2sVpjjr.js +1 -0
- package/dist/ui/assets/llvm-Cm23YOpf.js +1 -0
- package/dist/ui/assets/log-BNLmms1o.js +1 -0
- package/dist/ui/assets/logo-Cluzi2Zq.js +1 -0
- package/dist/ui/assets/lua-DxJJll61.js +1 -0
- package/dist/ui/assets/luau-CNKltnaQ.js +1 -0
- package/dist/ui/assets/make-Dixweg8N.js +1 -0
- package/dist/ui/assets/markdown-BYOwaDjH.js +1 -0
- package/dist/ui/assets/marko-Dx8mw-Wx.js +1 -0
- package/dist/ui/assets/material-theme-Bm3Qr25_.js +1 -0
- package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +1 -0
- package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +1 -0
- package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +1 -0
- package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +1 -0
- package/dist/ui/assets/matlab-D7qyCx1q.js +1 -0
- package/dist/ui/assets/mdc-vNKeXEwR.js +1 -0
- package/dist/ui/assets/mdx-DQZ5AkYe.js +1 -0
- package/dist/ui/assets/mermaid-Bk4SNUv9.js +1 -0
- package/dist/ui/assets/min-dark-BSWPekZh.js +1 -0
- package/dist/ui/assets/min-light-DDpmG2fV.js +1 -0
- package/dist/ui/assets/mipsasm-BMqwQI7S.js +1 -0
- package/dist/ui/assets/mojo-BgCJLMeH.js +1 -0
- package/dist/ui/assets/monokai-CdkpiU2Y.js +1 -0
- package/dist/ui/assets/moonbit-CaWjb8XO.js +1 -0
- package/dist/ui/assets/move-B1IS1UjX.js +1 -0
- package/dist/ui/assets/narrat-_X_XdTYD.js +1 -0
- package/dist/ui/assets/nextflow-Bbiyy34d.js +1 -0
- package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +1 -0
- package/dist/ui/assets/nginx-DScQAGLT.js +1 -0
- package/dist/ui/assets/night-owl-DhmEMT88.js +1 -0
- package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +1 -0
- package/dist/ui/assets/nim-lAJch9uT.js +1 -0
- package/dist/ui/assets/nix-IvuFDN5E.js +1 -0
- package/dist/ui/assets/nord-Cb4Vim4T.js +1 -0
- package/dist/ui/assets/nushell-DcLAeLz5.js +1 -0
- package/dist/ui/assets/objective-c-D1A_Heim.js +1 -0
- package/dist/ui/assets/objective-cpp-BsSzOQcm.js +1 -0
- package/dist/ui/assets/ocaml-O90oeIOV.js +1 -0
- package/dist/ui/assets/odin-B1RWQWA5.js +1 -0
- package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +1 -0
- package/dist/ui/assets/one-light-D7Lr4KcI.js +1 -0
- package/dist/ui/assets/openscad-BUDT5pXO.js +1 -0
- package/dist/ui/assets/pascal-4ZHwLPI5.js +1 -0
- package/dist/ui/assets/perl-C_GkVo_E.js +1 -0
- package/dist/ui/assets/php-DziV3K6J.js +1 -0
- package/dist/ui/assets/pierre-dark-CpLgRqie.js +1 -0
- package/dist/ui/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
- package/dist/ui/assets/pierre-dark-soft-kZQmAZld.js +1 -0
- package/dist/ui/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
- package/dist/ui/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
- package/dist/ui/assets/pierre-light-CoaEpmwp.js +1 -0
- package/dist/ui/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
- package/dist/ui/assets/pierre-light-soft-lWLdNTOI.js +1 -0
- package/dist/ui/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
- package/dist/ui/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
- package/dist/ui/assets/pkl-ot-7Btpt.js +1 -0
- package/dist/ui/assets/plastic-DQwYfKfQ.js +1 -0
- package/dist/ui/assets/plsql-DGHpHOYJ.js +1 -0
- package/dist/ui/assets/po-BiJDBrnU.js +1 -0
- package/dist/ui/assets/poimandres-DRFjx7u4.js +1 -0
- package/dist/ui/assets/polar-C7UOKdEL.js +1 -0
- package/dist/ui/assets/postcss-BXeXVLqQ.js +1 -0
- package/dist/ui/assets/powerquery-DNMTfnFr.js +1 -0
- package/dist/ui/assets/powershell-DshXNtvi.js +1 -0
- package/dist/ui/assets/prisma-BsRQq5mF.js +1 -0
- package/dist/ui/assets/prolog-iXnhIJG7.js +1 -0
- package/dist/ui/assets/proto-DB4EqR-F.js +1 -0
- package/dist/ui/assets/pug-z75UIWVK.js +1 -0
- package/dist/ui/assets/puppet-CDv2pdJW.js +1 -0
- package/dist/ui/assets/purescript-9MfHhQsQ.js +1 -0
- package/dist/ui/assets/python-gzcpVVnB.js +1 -0
- package/dist/ui/assets/qml-Cmm4coz1.js +1 -0
- package/dist/ui/assets/qmldir-DCQb3MpD.js +1 -0
- package/dist/ui/assets/qss-Fe1Jh2GI.js +1 -0
- package/dist/ui/assets/r-Brd0axBE.js +1 -0
- package/dist/ui/assets/racket-DcIDlBhZ.js +1 -0
- package/dist/ui/assets/raku-B3gFvitq.js +1 -0
- package/dist/ui/assets/razor-DSbwmoiu.js +1 -0
- package/dist/ui/assets/red-CJ3rzSJv.js +1 -0
- package/dist/ui/assets/reg-CRGYupPL.js +1 -0
- package/dist/ui/assets/regexp-Bs3Uk-pY.js +1 -0
- package/dist/ui/assets/rel-BtDbiS_P.js +1 -0
- package/dist/ui/assets/review-payload-CbwCBKB1.js +1580 -0
- package/dist/ui/assets/riscv-Ckw8ddFX.js +1 -0
- package/dist/ui/assets/ron-VUp2lXgN.js +1 -0
- package/dist/ui/assets/rose-pine-BthvhNj6.js +1 -0
- package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
- package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +1 -0
- package/dist/ui/assets/rosmsg-CAekHB0j.js +1 -0
- package/dist/ui/assets/rst-ChIyKpUC.js +1 -0
- package/dist/ui/assets/ruby-BdAmvOMO.js +1 -0
- package/dist/ui/assets/rust-Cfkwpbl8.js +1 -0
- package/dist/ui/assets/sas-DpXn8hc5.js +1 -0
- package/dist/ui/assets/sass-DXrisJhu.js +1 -0
- package/dist/ui/assets/scala-DKOlJaKm.js +1 -0
- package/dist/ui/assets/scheme-DQCgrYNe.js +1 -0
- package/dist/ui/assets/scss-atX1Uuef.js +1 -0
- package/dist/ui/assets/sdbl-bTVj8UrX.js +1 -0
- package/dist/ui/assets/shaderlab-TOUzSsQk.js +1 -0
- package/dist/ui/assets/shellscript-BqgcAeMK.js +1 -0
- package/dist/ui/assets/shellsession-DfQSMRN5.js +1 -0
- package/dist/ui/assets/slack-dark-DnToyrRv.js +1 -0
- package/dist/ui/assets/slack-ochin-B2OO5cIa.js +1 -0
- package/dist/ui/assets/smalltalk-B16xEiuN.js +1 -0
- package/dist/ui/assets/snazzy-light-4G7pJPwS.js +1 -0
- package/dist/ui/assets/solarized-dark-DV17i1UV.js +1 -0
- package/dist/ui/assets/solarized-light-DSh2HLQt.js +1 -0
- package/dist/ui/assets/solidity-CKzVLygQ.js +1 -0
- package/dist/ui/assets/soy-DzP7zZTB.js +1 -0
- package/dist/ui/assets/sparql-D_iOobhT.js +1 -0
- package/dist/ui/assets/splunk-BC2Px7Mm.js +1 -0
- package/dist/ui/assets/sql-gmaLk66z.js +1 -0
- package/dist/ui/assets/ssh-config-BgfXC-Er.js +1 -0
- package/dist/ui/assets/stata-CJ0YTMcV.js +1 -0
- package/dist/ui/assets/stylus-B6D30XZt.js +1 -0
- package/dist/ui/assets/surrealql-LH7FciQz.js +1 -0
- package/dist/ui/assets/svelte-BME2PU6V.js +1 -0
- package/dist/ui/assets/swift-DonLKvLd.js +1 -0
- package/dist/ui/assets/synthwave-84-nFMaYfgc.js +1 -0
- package/dist/ui/assets/system-verilog-DJ5XKQeo.js +1 -0
- package/dist/ui/assets/systemd-BxMlprV5.js +1 -0
- package/dist/ui/assets/talonscript-CohzipZa.js +1 -0
- package/dist/ui/assets/tasl-DMoTqEGO.js +1 -0
- package/dist/ui/assets/tcl-CZd0xW_V.js +1 -0
- package/dist/ui/assets/templ-DHBNIfYW.js +1 -0
- package/dist/ui/assets/terraform-DswuEJGm.js +1 -0
- package/dist/ui/assets/tex-C8-kPEzO.js +1 -0
- package/dist/ui/assets/tokyo-night-oM2G3aXe.js +1 -0
- package/dist/ui/assets/toml-CcmNWLt0.js +1 -0
- package/dist/ui/assets/ts-tags-CiewV0vR.js +1 -0
- package/dist/ui/assets/tsv-sltzmVWM.js +1 -0
- package/dist/ui/assets/tsx-CUYPqmnq.js +1 -0
- package/dist/ui/assets/turtle-ByJddavk.js +1 -0
- package/dist/ui/assets/twig-BTkvsl0b.js +1 -0
- package/dist/ui/assets/typescript-DDQMaPwj.js +1 -0
- package/dist/ui/assets/typespec-B88KGewJ.js +1 -0
- package/dist/ui/assets/typst-DI99ib-x.js +1 -0
- package/dist/ui/assets/v-DETTlOr0.js +1 -0
- package/dist/ui/assets/vala-zf12oZj6.js +1 -0
- package/dist/ui/assets/vb-Djn5o6TS.js +1 -0
- package/dist/ui/assets/verilog-CiiDBU1e.js +1 -0
- package/dist/ui/assets/vesper-D5bVUKB1.js +1 -0
- package/dist/ui/assets/vhdl-BroJfC0k.js +1 -0
- package/dist/ui/assets/viml-DvXPmvsu.js +1 -0
- package/dist/ui/assets/vitesse-black-fwtXNY1n.js +1 -0
- package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +1 -0
- package/dist/ui/assets/vitesse-light-VbXTXTou.js +1 -0
- package/dist/ui/assets/vue-BH5SEWRH.js +1 -0
- package/dist/ui/assets/vue-html-BT7yeYez.js +1 -0
- package/dist/ui/assets/vue-vine-Cs5IN2rs.js +1 -0
- package/dist/ui/assets/vyper-CgoNMtux.js +1 -0
- package/dist/ui/assets/wasm-BnjxR4X6.js +1 -0
- package/dist/ui/assets/wasm-ByWQv1Qj.js +1 -0
- package/dist/ui/assets/wenyan-C8pVoKbM.js +1 -0
- package/dist/ui/assets/wgsl-BsKzXJz4.js +1 -0
- package/dist/ui/assets/wikitext-ClFFjSW2.js +1 -0
- package/dist/ui/assets/wit-DdvCle-K.js +1 -0
- package/dist/ui/assets/wolfram-DLL8P-h_.js +1 -0
- package/dist/ui/assets/workspace-app-B_BnSEHO.css +1 -0
- package/dist/ui/assets/workspace-app-DSFpnrIC.js +115 -0
- package/dist/ui/assets/xml-D3_1BEcO.js +1 -0
- package/dist/ui/assets/xsl-BBOCDn4Y.js +1 -0
- package/dist/ui/assets/yaml-lThBDT45.js +1 -0
- package/dist/ui/assets/zenscript-BnlCZFoB.js +1 -0
- package/dist/ui/assets/zig-CMLA9XwU.js +1 -0
- package/dist/ui/workspace-app.html +15 -0
- package/dist/user-config.js +228 -0
- package/dist/verification.js +74 -0
- package/dist/workspace-store.js +133 -0
- package/dist/workspaces.js +433 -0
- package/docs/adr/devspace-x-implementation-adrs.md +159 -0
- package/docs/agent-profile-schema.md +203 -0
- package/docs/artifact-exchange.md +44 -0
- package/docs/assets/devspace-logo-light.png +0 -0
- package/docs/assets/devspace-screenshot.png +0 -0
- package/docs/assets/v11-review-ui-after.png +0 -0
- package/docs/assets/v11-review-ui-before.png +0 -0
- package/docs/chatgpt-coding-workflow.md +215 -0
- package/docs/configuration.md +217 -0
- package/docs/gotchas.md +294 -0
- package/docs/local-agent-daemon.md +101 -0
- package/docs/security.md +197 -0
- package/docs/setup.md +174 -0
- package/examples/agents/claude-implementer.md +30 -0
- package/examples/agents/codex-explorer.md +27 -0
- package/examples/agents/codex-qa-tester.md +29 -0
- package/examples/agents/codex-worker.md +25 -0
- package/examples/agents/copilot-reviewer.md +25 -0
- package/examples/agents/cursor-agent-worker.md +26 -0
- package/examples/agents/grok-builder.md +10 -0
- package/examples/agents/opencode-explorer.md +27 -0
- package/examples/agents/pi-reviewer.md +27 -0
- package/package.json +102 -0
- package/schema/v1/hearth.schema.json +529 -0
- package/scripts/copy-dashboard.mjs +9 -0
- package/scripts/fix-node-pty-permissions.mjs +22 -0
- package/scripts/generate-config-schema.ts +9 -0
- package/skills/subagents/SKILL.md +57 -0
package/docs/gotchas.md
ADDED
|
@@ -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.
|
package/docs/security.md
ADDED
|
@@ -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.
|