@crouton-kit/crouter 0.3.32 → 0.3.33
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/README.md +8 -0
- package/dist/build-root.js +1 -0
- package/dist/builtin-memory/crouter-development/marketplaces.md +2 -2
- package/dist/builtin-memory/crouter-development/personas/base-prompt.md +2 -2
- package/dist/builtin-memory/crouter-development/personas/orchestrator-prompt.md +5 -5
- package/dist/builtin-memory/crouter-development/personas.md +3 -4
- package/dist/builtin-memory/crouter-development/plugins.md +18 -18
- package/dist/builtin-memory/design.md +4 -1
- package/dist/builtin-memory/development.md +4 -1
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/nodes-and-canvas.md +6 -6
- package/dist/builtin-memory/internal/storage-tiers.md +5 -5
- package/dist/builtin-memory/planning.md +4 -1
- package/dist/builtin-memory/product.md +80 -0
- package/dist/builtin-memory/spec.md +4 -1
- package/dist/builtin-personas/advisor/PERSONA.md +10 -0
- package/dist/builtin-personas/design/PERSONA.md +2 -2
- package/dist/builtin-personas/design/orchestrator.md +3 -3
- package/dist/builtin-personas/developer/PERSONA.md +1 -1
- package/dist/builtin-personas/developer/orchestrator.md +2 -2
- package/dist/builtin-personas/explore/PERSONA.md +3 -3
- package/dist/builtin-personas/explore/orchestrator.md +4 -2
- package/dist/builtin-personas/general/PERSONA.md +1 -1
- package/dist/builtin-personas/general/orchestrator.md +1 -1
- package/dist/builtin-personas/orchestration-kernel.md +7 -14
- package/dist/builtin-personas/plan/PERSONA.md +1 -1
- package/dist/builtin-personas/plan/orchestrator.md +2 -2
- package/dist/builtin-personas/plan/reviewers/architecture-fit/PERSONA.md +1 -1
- package/dist/builtin-personas/plan/reviewers/code-smells/PERSONA.md +1 -1
- package/dist/builtin-personas/plan/reviewers/pattern-consistency/PERSONA.md +1 -1
- package/dist/builtin-personas/plan/reviewers/requirements-coverage/PERSONA.md +1 -1
- package/dist/builtin-personas/plan/reviewers/security/PERSONA.md +1 -1
- package/dist/builtin-personas/product/PERSONA.md +18 -0
- package/dist/builtin-personas/product/orchestrator.md +14 -0
- package/dist/builtin-personas/product/teardown/PERSONA.md +13 -0
- package/dist/builtin-personas/review/PERSONA.md +1 -1
- package/dist/builtin-personas/review/orchestrator.md +1 -1
- package/dist/builtin-personas/runtime-base.md +5 -0
- package/dist/builtin-personas/spec/PERSONA.md +1 -1
- package/dist/builtin-personas/spec/orchestrator.md +2 -2
- package/dist/builtin-personas/spec/requirements/PERSONA.md +1 -1
- package/dist/builtin-views/canvas/core.mjs +82 -1
- package/dist/builtin-views/canvas/tui.mjs +9 -5
- package/dist/builtin-views/canvas/web.jsx +3 -2
- package/dist/builtin-views/chat/core.mjs +725 -0
- package/dist/builtin-views/chat/text.mjs +101 -0
- package/dist/builtin-views/chat/tui.mjs +368 -0
- package/dist/builtin-views/chat/web.jsx +367 -0
- package/dist/builtin-views/prompt-review/core.mjs +863 -0
- package/dist/builtin-views/prompt-review/text.mjs +15 -0
- package/dist/builtin-views/prompt-review/tui.mjs +196 -0
- package/dist/builtin-views/prompt-review/web.jsx +484 -0
- package/dist/builtin-views/settings/core.mjs +397 -0
- package/dist/builtin-views/settings/text.mjs +40 -0
- package/dist/builtin-views/settings/tui.mjs +95 -0
- package/dist/builtin-views/settings/web.jsx +167 -0
- package/dist/cli.js +16 -3
- package/dist/clients/attach/__tests__/autocomplete-and-bash-mode.test.js +96 -0
- package/dist/clients/attach/__tests__/bash-bang-routing.test.js +58 -0
- package/dist/clients/attach/__tests__/bundle-pi-tui-dedup.test.d.ts +1 -0
- package/dist/clients/attach/__tests__/bundle-pi-tui-dedup.test.js +56 -0
- package/dist/clients/attach/__tests__/titled-editor.test.js +22 -1
- package/dist/clients/attach/attach-cmd.d.ts +18 -0
- package/dist/clients/attach/attach-cmd.js +1723 -795
- package/dist/clients/attach/canvas-panels.js +2 -2
- package/dist/clients/attach/chat-view.d.ts +10 -0
- package/dist/clients/attach/chat-view.js +23 -0
- package/dist/clients/attach/config-load.d.ts +8 -4
- package/dist/clients/attach/config-load.js +2 -0
- package/dist/clients/attach/extension-dialogs.d.ts +2 -3
- package/dist/clients/attach/extension-dialogs.js +7 -9
- package/dist/clients/attach/graph-overlay.js +3 -2
- package/dist/clients/attach/input-controller.d.ts +4 -3
- package/dist/clients/attach/input-controller.js +24 -3
- package/dist/clients/attach/slash-commands.d.ts +7 -7
- package/dist/clients/attach/slash-commands.js +38 -14
- package/dist/clients/attach/titled-editor.js +18 -14
- package/dist/clients/attach/view-socket.d.ts +2 -1
- package/dist/clients/attach/view-socket.js +27 -8
- package/dist/clients/web/__tests__/source-cache.test.d.ts +1 -0
- package/dist/clients/web/__tests__/source-cache.test.js +32 -0
- package/dist/clients/web/dev-server.js +1 -0
- package/dist/clients/web/events.js +9 -11
- package/dist/clients/web/server.d.ts +4 -3
- package/dist/clients/web/server.js +138 -31
- package/dist/clients/web/source-cache.d.ts +10 -0
- package/dist/clients/web/source-cache.js +57 -0
- package/dist/clients/web/web-cmd.js +28 -9
- package/dist/commands/__tests__/human.test.js +30 -28
- package/dist/commands/canvas-history/search.js +1 -1
- package/dist/commands/canvas-history.js +5 -8
- package/dist/commands/canvas-issue.d.ts +2 -0
- package/dist/commands/canvas-issue.js +148 -0
- package/dist/commands/canvas-prune.js +19 -0
- package/dist/commands/canvas-rebuild-index.d.ts +2 -0
- package/dist/commands/canvas-rebuild-index.js +57 -0
- package/dist/commands/canvas-snapshot.d.ts +2 -0
- package/dist/commands/canvas-snapshot.js +48 -0
- package/dist/commands/canvas-tmux-spread.d.ts +2 -0
- package/dist/commands/canvas-tmux-spread.js +188 -0
- package/dist/commands/canvas.d.ts +1 -0
- package/dist/commands/canvas.js +16 -1
- package/dist/commands/chord.js +143 -48
- package/dist/commands/daemon.js +3 -3
- package/dist/commands/human/prompts.d.ts +0 -1
- package/dist/commands/human/prompts.js +39 -54
- package/dist/commands/human/queue.d.ts +12 -1
- package/dist/commands/human/queue.js +468 -73
- package/dist/commands/human/shared.d.ts +3 -4
- package/dist/commands/human/shared.js +3 -3
- package/dist/commands/human.js +11 -10
- package/dist/commands/memory/find.js +3 -2
- package/dist/commands/memory/list.js +4 -3
- package/dist/commands/memory/read.js +3 -3
- package/dist/commands/memory/shared.d.ts +1 -4
- package/dist/commands/memory/shared.js +6 -9
- package/dist/commands/memory/write.js +3 -3
- package/dist/commands/memory.js +4 -7
- package/dist/commands/node-context.d.ts +2 -0
- package/dist/commands/node-context.js +172 -0
- package/dist/commands/node-snapshot.d.ts +2 -0
- package/dist/commands/node-snapshot.js +123 -0
- package/dist/commands/node.js +228 -52
- package/dist/commands/pkg/plugin-inspect.js +6 -6
- package/dist/commands/pkg/plugin-manage.js +1 -1
- package/dist/commands/pkg/plugin.js +2 -2
- package/dist/commands/pkg.js +2 -2
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.js +79 -11
- package/dist/commands/revive.js +74 -1
- package/dist/commands/search/answer.d.ts +1 -0
- package/dist/commands/search/answer.js +50 -0
- package/dist/commands/search/contents.d.ts +1 -0
- package/dist/commands/search/contents.js +96 -0
- package/dist/commands/search/exa.d.ts +53 -0
- package/dist/commands/search/exa.js +155 -0
- package/dist/commands/search/puremd.d.ts +11 -0
- package/dist/commands/search/puremd.js +53 -0
- package/dist/commands/search/web.d.ts +1 -0
- package/dist/commands/search/web.js +65 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +24 -0
- package/dist/commands/sys/__tests__/sync-import.test.d.ts +1 -0
- package/dist/commands/sys/__tests__/sync-import.test.js +72 -0
- package/dist/commands/sys/config.js +59 -10
- package/dist/commands/sys/doctor.js +56 -4
- package/dist/commands/sys/prompt-review.d.ts +1 -0
- package/dist/commands/sys/prompt-review.js +178 -0
- package/dist/commands/sys/promptstudio.d.ts +2 -0
- package/dist/commands/sys/promptstudio.js +65 -0
- package/dist/commands/sys/settings.d.ts +2 -0
- package/dist/commands/sys/settings.js +16 -0
- package/dist/commands/sys/sync.js +311 -159
- package/dist/commands/sys/sysprompt.d.ts +1 -0
- package/dist/commands/sys/sysprompt.js +86 -0
- package/dist/commands/sys.js +9 -5
- package/dist/commands/view-new.js +2 -2
- package/dist/core/__tests__/artifact-paths.test.d.ts +1 -0
- package/dist/core/__tests__/artifact-paths.test.js +44 -0
- package/dist/core/__tests__/broker-preflight.test.d.ts +1 -0
- package/dist/core/__tests__/broker-preflight.test.js +85 -0
- package/dist/core/__tests__/broker-sdk-wiring.test.js +15 -0
- package/dist/core/__tests__/canvas.test.js +37 -1
- package/dist/core/__tests__/chat-view-reconnect.test.d.ts +1 -0
- package/dist/core/__tests__/chat-view-reconnect.test.js +70 -0
- package/dist/core/__tests__/child-death-wake.test.js +11 -2
- package/dist/core/__tests__/close.test.js +39 -1
- package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +1 -0
- package/dist/core/__tests__/connection-reconnect-resume.test.js +37 -0
- package/dist/core/__tests__/context-intro.test.js +48 -14
- package/dist/core/__tests__/daemon-boot.test.js +182 -9
- package/dist/core/__tests__/editor-label.test.d.ts +1 -0
- package/dist/core/__tests__/editor-label.test.js +26 -0
- package/dist/core/__tests__/fault-marker.test.d.ts +1 -0
- package/dist/core/__tests__/fault-marker.test.js +112 -0
- package/dist/core/__tests__/fault-retry-rewind.test.d.ts +1 -0
- package/dist/core/__tests__/fault-retry-rewind.test.js +123 -0
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +30 -4
- package/dist/core/__tests__/fixtures/fake-engine.js +156 -17
- package/dist/core/__tests__/fixtures/fake-pi-host.js +10 -1
- package/dist/core/__tests__/full/human-new-window-regression.test.js +1 -1
- package/dist/core/__tests__/helpers/harness.d.ts +1 -1
- package/dist/core/__tests__/helpers/harness.js +2 -2
- package/dist/core/__tests__/human-stranded-deliver.test.js +38 -1
- package/dist/core/__tests__/human-surface-target.test.js +1 -1
- package/dist/core/__tests__/kickoff.test.js +18 -19
- package/dist/core/__tests__/memory-resolver.test.js +12 -1
- package/dist/core/__tests__/migration.test.js +49 -14
- package/dist/core/__tests__/model-ladders.test.d.ts +1 -0
- package/dist/core/__tests__/model-ladders.test.js +160 -0
- package/dist/core/__tests__/node-env.test.d.ts +1 -0
- package/dist/core/__tests__/node-env.test.js +26 -0
- package/dist/core/__tests__/push-final-guard.test.js +7 -1
- package/dist/core/__tests__/relaunch-root.test.js +9 -9
- package/dist/core/__tests__/revive.test.js +36 -6
- package/dist/core/__tests__/spawn-root.test.js +24 -1
- package/dist/core/__tests__/stop-guard.test.js +10 -0
- package/dist/core/__tests__/stranded-relaunch.test.d.ts +1 -0
- package/dist/core/__tests__/stranded-relaunch.test.js +72 -0
- package/dist/core/__tests__/tmux-surface.test.js +5 -1
- package/dist/core/__tests__/unknown-path.test.js +19 -19
- package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +1 -0
- package/dist/core/__tests__/yield-ensures-daemon.test.js +54 -0
- package/dist/core/artifact.d.ts +2 -33
- package/dist/core/artifact.js +27 -87
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/canvas/browse/__tests__/model.test.js +35 -1
- package/dist/core/canvas/browse/app.js +87 -17
- package/dist/core/canvas/browse/model.d.ts +10 -1
- package/dist/core/canvas/browse/model.js +37 -1
- package/dist/core/canvas/browse/render.js +35 -33
- package/dist/core/canvas/canvas.d.ts +7 -0
- package/dist/core/canvas/canvas.js +54 -5
- package/dist/core/canvas/db.js +35 -8
- package/dist/core/canvas/labels.d.ts +6 -8
- package/dist/core/canvas/labels.js +8 -11
- package/dist/core/canvas/nav-model.d.ts +5 -4
- package/dist/core/canvas/nav-model.js +31 -17
- package/dist/core/canvas/paths.d.ts +18 -1
- package/dist/core/canvas/paths.js +31 -2
- package/dist/core/canvas/render.d.ts +25 -0
- package/dist/core/canvas/render.js +96 -13
- package/dist/core/canvas/status-glyph.d.ts +35 -0
- package/dist/core/canvas/status-glyph.js +104 -0
- package/dist/core/canvas/types.d.ts +2 -2
- package/dist/core/config.js +114 -16
- package/dist/core/fault-classifier.d.ts +41 -0
- package/dist/core/fault-classifier.js +110 -0
- package/dist/core/feed/inbox.d.ts +15 -0
- package/dist/core/feed/inbox.js +40 -14
- package/dist/core/frontmatter.d.ts +1 -11
- package/dist/core/frontmatter.js +1 -55
- package/dist/core/hearth/config.d.ts +2 -0
- package/dist/core/hearth/config.js +75 -0
- package/dist/core/hearth/guest-env.d.ts +2 -0
- package/dist/core/hearth/guest-env.js +11 -0
- package/dist/core/hearth/index.d.ts +5 -0
- package/dist/core/hearth/index.js +5 -0
- package/dist/core/hearth/provider.d.ts +21 -0
- package/dist/core/hearth/provider.js +10 -0
- package/dist/core/hearth/providers/blaxel-bootstrap.d.ts +10 -0
- package/dist/core/hearth/providers/blaxel-bootstrap.js +39 -0
- package/dist/core/hearth/providers/blaxel-home.d.ts +11 -0
- package/dist/core/hearth/providers/blaxel-home.js +126 -0
- package/dist/core/hearth/providers/blaxel.d.ts +26 -0
- package/dist/core/hearth/providers/blaxel.js +208 -0
- package/dist/core/hearth/providers/types.d.ts +72 -0
- package/dist/core/hearth/providers/types.js +1 -0
- package/dist/core/hearth/registry.d.ts +15 -0
- package/dist/core/hearth/registry.js +179 -0
- package/dist/core/hearth/types.d.ts +121 -0
- package/dist/core/hearth/types.js +1 -0
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +1 -0
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +79 -0
- package/dist/core/{skill-sync → host-exports}/builtins.d.ts +21 -13
- package/dist/core/host-exports/builtins.js +68 -0
- package/dist/core/{skill-sync → host-exports}/export.d.ts +9 -6
- package/dist/core/{skill-sync → host-exports}/export.js +37 -14
- package/dist/core/io.js +1 -1
- package/dist/core/log.d.ts +9 -0
- package/dist/core/log.js +113 -0
- package/dist/core/memory-resolver.d.ts +8 -8
- package/dist/core/memory-resolver.js +15 -28
- package/dist/core/personas/index.d.ts +4 -4
- package/dist/core/personas/index.js +2 -2
- package/dist/core/personas/loader.d.ts +51 -0
- package/dist/core/personas/loader.js +54 -50
- package/dist/core/personas/resolve.d.ts +43 -27
- package/dist/core/personas/resolve.js +336 -94
- package/dist/core/runtime/auth-reload.d.ts +7 -0
- package/dist/core/runtime/auth-reload.js +69 -0
- package/dist/core/runtime/bearings.d.ts +35 -15
- package/dist/core/runtime/bearings.js +305 -44
- package/dist/core/runtime/branded-host.d.ts +4 -2
- package/dist/core/runtime/branded-host.js +66 -4
- package/dist/core/runtime/broker-protocol.d.ts +38 -3
- package/dist/core/runtime/broker.js +343 -18
- package/dist/core/runtime/close.js +37 -29
- package/dist/core/runtime/connectivity.d.ts +12 -0
- package/dist/core/runtime/connectivity.js +73 -0
- package/dist/core/runtime/fault-recovery-nudge.d.ts +2 -0
- package/dist/core/runtime/fault-recovery-nudge.js +2 -0
- package/dist/core/runtime/fault-recovery.d.ts +23 -0
- package/dist/core/runtime/fault-recovery.js +74 -0
- package/dist/core/runtime/fault.d.ts +25 -0
- package/dist/core/runtime/fault.js +176 -0
- package/dist/core/runtime/front-door.d.ts +1 -1
- package/dist/core/runtime/front-door.js +2 -2
- package/dist/core/runtime/host.d.ts +10 -0
- package/dist/core/runtime/host.js +71 -9
- package/dist/core/runtime/kickoff.js +31 -45
- package/dist/core/runtime/launch.d.ts +32 -18
- package/dist/core/runtime/launch.js +148 -43
- package/dist/core/runtime/model-swap.d.ts +18 -0
- package/dist/core/runtime/model-swap.js +95 -0
- package/dist/core/runtime/naming.d.ts +7 -0
- package/dist/core/runtime/naming.js +61 -9
- package/dist/core/runtime/nodes.js +6 -1
- package/dist/core/runtime/persona.js +16 -17
- package/dist/core/runtime/placement.d.ts +36 -31
- package/dist/core/runtime/placement.js +149 -64
- package/dist/core/runtime/promote.d.ts +2 -0
- package/dist/core/runtime/promote.js +23 -3
- package/dist/core/runtime/recycle.js +6 -4
- package/dist/core/runtime/reset.d.ts +5 -2
- package/dist/core/runtime/reset.js +2 -2
- package/dist/core/runtime/revive.d.ts +4 -0
- package/dist/core/runtime/revive.js +27 -9
- package/dist/core/runtime/roadmap.d.ts +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/runtime/spawn.d.ts +2 -2
- package/dist/core/runtime/spawn.js +30 -6
- package/dist/core/runtime/stop-guard.js +6 -1
- package/dist/core/runtime/tmux-chrome.d.ts +1 -1
- package/dist/core/runtime/tmux-chrome.js +1 -1
- package/dist/core/runtime/tmux.d.ts +29 -6
- package/dist/core/runtime/tmux.js +134 -80
- package/dist/core/runtime/view-socket-client.d.ts +46 -0
- package/dist/core/runtime/view-socket-client.js +203 -0
- package/dist/core/substrate/index.d.ts +1 -1
- package/dist/core/substrate/index.js +1 -1
- package/dist/core/substrate/on-read.js +16 -4
- package/dist/core/substrate/render.d.ts +10 -13
- package/dist/core/substrate/render.js +56 -51
- package/dist/core/tui/host.js +83 -18
- package/dist/core/view/__tests__/transport-cache.test.d.ts +1 -0
- package/dist/core/view/__tests__/transport-cache.test.js +62 -0
- package/dist/core/view/contract.d.ts +20 -0
- package/dist/core/view/stream-local.d.ts +3 -0
- package/dist/core/view/stream-local.js +184 -0
- package/dist/core/view/transport-cache.d.ts +8 -0
- package/dist/core/view/transport-cache.js +38 -0
- package/dist/core/view/transport-local.js +4 -0
- package/dist/core/view/transport.d.ts +7 -1
- package/dist/daemon/crtrd.d.ts +3 -19
- package/dist/daemon/crtrd.js +139 -178
- package/dist/daemon/manage.d.ts +18 -1
- package/dist/daemon/manage.js +54 -9
- package/dist/hearth/wake-proxy/__tests__/anthropic-oauth.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/anthropic-oauth.test.js +289 -0
- package/dist/hearth/wake-proxy/__tests__/config-timeout.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/config-timeout.test.js +34 -0
- package/dist/hearth/wake-proxy/__tests__/guest-source.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/guest-source.test.js +203 -0
- package/dist/hearth/wake-proxy/__tests__/hardening.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/hardening.test.js +59 -0
- package/dist/hearth/wake-proxy/__tests__/hearth-status-route.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/hearth-status-route.test.js +372 -0
- package/dist/hearth/wake-proxy/__tests__/http-running-route-fast-path.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/http-running-route-fast-path.test.js +258 -0
- package/dist/hearth/wake-proxy/__tests__/model-auth-routes.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/model-auth-routes.test.js +437 -0
- package/dist/hearth/wake-proxy/__tests__/source-bridge-gate.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/source-bridge-gate.test.js +455 -0
- package/dist/hearth/wake-proxy/__tests__/static-asset-allowlist.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/static-asset-allowlist.test.js +15 -0
- package/dist/hearth/wake-proxy/__tests__/warm-path-concurrency.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/warm-path-concurrency.test.js +141 -0
- package/dist/hearth/wake-proxy/__tests__/ws-teardown-accounting.test.d.ts +1 -0
- package/dist/hearth/wake-proxy/__tests__/ws-teardown-accounting.test.js +143 -0
- package/dist/hearth/wake-proxy/anthropic-oauth.d.ts +58 -0
- package/dist/hearth/wake-proxy/anthropic-oauth.js +189 -0
- package/dist/hearth/wake-proxy/auth.d.ts +22 -0
- package/dist/hearth/wake-proxy/auth.js +128 -0
- package/dist/hearth/wake-proxy/config.d.ts +2 -0
- package/dist/hearth/wake-proxy/config.js +151 -0
- package/dist/hearth/wake-proxy/guest-source.d.ts +14 -0
- package/dist/hearth/wake-proxy/guest-source.js +130 -0
- package/dist/hearth/wake-proxy/hearth-status.d.ts +44 -0
- package/dist/hearth/wake-proxy/hearth-status.js +267 -0
- package/dist/hearth/wake-proxy/home.d.ts +67 -0
- package/dist/hearth/wake-proxy/home.js +297 -0
- package/dist/hearth/wake-proxy/main.d.ts +1 -0
- package/dist/hearth/wake-proxy/main.js +134 -0
- package/dist/hearth/wake-proxy/model-auth.d.ts +13 -0
- package/dist/hearth/wake-proxy/model-auth.js +345 -0
- package/dist/hearth/wake-proxy/proxy.d.ts +35 -0
- package/dist/hearth/wake-proxy/proxy.js +716 -0
- package/dist/hearth/wake-proxy/public-source-gate.d.ts +9 -0
- package/dist/hearth/wake-proxy/public-source-gate.js +409 -0
- package/dist/hearth/wake-proxy/redact.d.ts +1 -0
- package/dist/hearth/wake-proxy/redact.js +17 -0
- package/dist/hearth/wake-proxy/server.d.ts +11 -0
- package/dist/hearth/wake-proxy/server.js +142 -0
- package/dist/hearth/wake-proxy/state.d.ts +18 -0
- package/dist/hearth/wake-proxy/state.js +342 -0
- package/dist/hearth/wake-proxy/types.d.ts +76 -0
- package/dist/hearth/wake-proxy/types.js +1 -0
- package/dist/index.js +3 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +6 -5
- package/dist/pi-extensions/canvas-context-intro.js +7 -7
- package/dist/pi-extensions/canvas-doc-substrate.js +19 -22
- package/dist/pi-extensions/canvas-nav.js +15 -8
- package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
- package/dist/pi-extensions/canvas-stophook.js +78 -11
- package/dist/types.d.ts +39 -20
- package/dist/types.js +38 -13
- package/dist/web/runtime.js +141 -42
- package/dist/web/transport-http.js +7 -5
- package/dist/web/transport-stream.d.ts +3 -0
- package/dist/web/transport-stream.js +204 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
- package/dist/web-client/assets/fraunces-latin-ext-wght-normal-Ca2vKHc0.woff2 +0 -0
- package/dist/web-client/assets/fraunces-latin-wght-normal-ukD16Tqj.woff2 +0 -0
- package/dist/web-client/assets/fraunces-vietnamese-wght-normal-CnvboYUG.woff2 +0 -0
- package/dist/web-client/assets/index-BZUxTkv5.css +2 -0
- package/dist/web-client/assets/index-D36PNBj4.js +80 -0
- package/dist/web-client/assets/instrument-sans-latin-ext-wght-normal-B5bTHO_g.woff2 +0 -0
- package/dist/web-client/assets/instrument-sans-latin-wght-normal-BbzFLZTg.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
- package/dist/web-client/index.html +3 -2
- package/package.json +32 -10
- package/dist/core/__tests__/error-stall-recycle.test.js +0 -141
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.js +0 -57
- package/dist/core/skill-sync/builtins.js +0 -112
- package/dist/core/skill-sync/claude-plugins.d.ts +0 -23
- package/dist/core/skill-sync/claude-plugins.js +0 -71
- package/dist/core/skill-sync/engine.d.ts +0 -42
- package/dist/core/skill-sync/engine.js +0 -633
- package/dist/core/skill-sync/manifest.d.ts +0 -64
- package/dist/core/skill-sync/manifest.js +0 -181
- package/dist/core/skill-sync/profile.d.ts +0 -76
- package/dist/core/skill-sync/profile.js +0 -173
- package/dist/core/skill-sync/snapshot.d.ts +0 -57
- package/dist/core/skill-sync/snapshot.js +0 -120
- package/dist/pi-extensions/canvas-commands.d.ts +0 -37
- package/dist/pi-extensions/canvas-commands.js +0 -113
- package/dist/pi-extensions/canvas-resume.d.ts +0 -21
- package/dist/pi-extensions/canvas-resume.js +0 -83
- package/dist/pi-extensions/canvas-view.d.ts +0 -21
- package/dist/pi-extensions/canvas-view.js +0 -76
- package/dist/web-client/assets/index-BUvQb4hR.css +0 -2
- package/dist/web-client/assets/index-ClLQXYAE.js +0 -10
- /package/dist/{core/__tests__/error-stall-recycle.test.d.ts → clients/attach/__tests__/autocomplete-and-bash-mode.test.d.ts} +0 -0
- /package/dist/{core/skill-sync/__tests__/dry-run-wrote-count.test.d.ts → clients/attach/__tests__/bash-bang-routing.test.d.ts} +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { general } from '../../core/errors.js';
|
|
4
|
+
import { getHome, putHome, updateHome } from '../../core/hearth/registry.js';
|
|
5
|
+
import { nowIso } from '../../core/fs-utils.js';
|
|
6
|
+
const LOCK_STALE_MS = 2 * 60_000;
|
|
7
|
+
const DEFAULT_VERSION = 1;
|
|
8
|
+
const tenantLocks = new Map();
|
|
9
|
+
const tenantRuntimes = new Map();
|
|
10
|
+
function ensureParentDir(path) {
|
|
11
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
function atomicWriteJson(path, value) {
|
|
14
|
+
ensureParentDir(path);
|
|
15
|
+
const tmp = `${path}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
16
|
+
writeFileSync(tmp, JSON.stringify(value, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
17
|
+
try {
|
|
18
|
+
renameSync(tmp, path);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
try {
|
|
22
|
+
rmSync(tmp, { force: true });
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* ignore */
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function readJsonFile(path) {
|
|
31
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
32
|
+
}
|
|
33
|
+
function normalizeProxyState(value) {
|
|
34
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
35
|
+
throw general('invalid hearth proxy state file', { valueType: value === null ? 'null' : typeof value });
|
|
36
|
+
}
|
|
37
|
+
const obj = value;
|
|
38
|
+
const owner = obj.owner;
|
|
39
|
+
if (owner === null || typeof owner !== 'object' || Array.isArray(owner)) {
|
|
40
|
+
throw general('invalid hearth proxy state owner', { valueType: typeof owner });
|
|
41
|
+
}
|
|
42
|
+
const ownerObj = owner;
|
|
43
|
+
if (typeof ownerObj.ownerUserId !== 'string' || typeof ownerObj.defaultTenantId !== 'string' || typeof ownerObj.tokenHash !== 'string') {
|
|
44
|
+
throw general('invalid hearth proxy state owner fields', { owner });
|
|
45
|
+
}
|
|
46
|
+
const tenantsRaw = obj.tenants;
|
|
47
|
+
const tenants = {};
|
|
48
|
+
if (tenantsRaw !== undefined) {
|
|
49
|
+
if (tenantsRaw === null || typeof tenantsRaw !== 'object' || Array.isArray(tenantsRaw)) {
|
|
50
|
+
throw general('invalid hearth proxy tenants map', { tenantsRaw });
|
|
51
|
+
}
|
|
52
|
+
for (const [tenantId, tenant] of Object.entries(tenantsRaw)) {
|
|
53
|
+
if (tenant === null || typeof tenant !== 'object' || Array.isArray(tenant))
|
|
54
|
+
continue;
|
|
55
|
+
const draft = tenant;
|
|
56
|
+
if (typeof draft.tenantId !== 'string' || typeof draft.ownerUserId !== 'string' || typeof draft.m0RegistryPath !== 'string' || typeof draft.idleAfterMs !== 'number' || typeof draft.updatedAt !== 'string') {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
tenants[tenantId] = {
|
|
60
|
+
tenantId: draft.tenantId,
|
|
61
|
+
ownerUserId: draft.ownerUserId,
|
|
62
|
+
m0RegistryPath: draft.m0RegistryPath,
|
|
63
|
+
idleAfterMs: draft.idleAfterMs,
|
|
64
|
+
lastActivityAt: typeof draft.lastActivityAt === 'string' ? draft.lastActivityAt : null,
|
|
65
|
+
lastWakeAt: typeof draft.lastWakeAt === 'string' ? draft.lastWakeAt : null,
|
|
66
|
+
lastPauseAt: typeof draft.lastPauseAt === 'string' ? draft.lastPauseAt : null,
|
|
67
|
+
updatedAt: draft.updatedAt,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
version: DEFAULT_VERSION,
|
|
73
|
+
owner: {
|
|
74
|
+
ownerUserId: ownerObj.ownerUserId,
|
|
75
|
+
defaultTenantId: ownerObj.defaultTenantId,
|
|
76
|
+
tokenHash: ownerObj.tokenHash,
|
|
77
|
+
createdAt: typeof ownerObj.createdAt === 'string' ? ownerObj.createdAt : nowIso(),
|
|
78
|
+
},
|
|
79
|
+
tenants,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function loadProxyState(statePath) {
|
|
83
|
+
if (!existsSync(statePath))
|
|
84
|
+
return null;
|
|
85
|
+
return normalizeProxyState(readJsonFile(statePath));
|
|
86
|
+
}
|
|
87
|
+
export function saveProxyState(statePath, state) {
|
|
88
|
+
atomicWriteJson(statePath, state);
|
|
89
|
+
return state;
|
|
90
|
+
}
|
|
91
|
+
export function ensureProxyState(config) {
|
|
92
|
+
const existing = loadProxyState(config.statePath);
|
|
93
|
+
const now = nowIso();
|
|
94
|
+
const base = existing ?? {
|
|
95
|
+
version: DEFAULT_VERSION,
|
|
96
|
+
owner: {
|
|
97
|
+
ownerUserId: config.ownerUserId,
|
|
98
|
+
defaultTenantId: config.defaultTenantId,
|
|
99
|
+
tokenHash: config.ownerTokenHash,
|
|
100
|
+
createdAt: now,
|
|
101
|
+
},
|
|
102
|
+
tenants: {},
|
|
103
|
+
};
|
|
104
|
+
base.owner.ownerUserId = config.ownerUserId;
|
|
105
|
+
base.owner.defaultTenantId = config.defaultTenantId;
|
|
106
|
+
base.owner.tokenHash = config.ownerTokenHash;
|
|
107
|
+
if (base.owner.createdAt.trim() === '')
|
|
108
|
+
base.owner.createdAt = now;
|
|
109
|
+
base.tenants[config.defaultTenantId] = ensureTenantState(base.tenants[config.defaultTenantId], config, now);
|
|
110
|
+
return saveProxyState(config.statePath, base);
|
|
111
|
+
}
|
|
112
|
+
export function getTenantState(state, tenantId) {
|
|
113
|
+
return state.tenants[tenantId] ?? null;
|
|
114
|
+
}
|
|
115
|
+
function ensureTenantState(existing, config, now = nowIso()) {
|
|
116
|
+
return {
|
|
117
|
+
tenantId: existing?.tenantId ?? config.defaultTenantId,
|
|
118
|
+
ownerUserId: existing?.ownerUserId ?? config.ownerUserId,
|
|
119
|
+
m0RegistryPath: existing?.m0RegistryPath ?? config.m0RegistryPath,
|
|
120
|
+
idleAfterMs: existing?.idleAfterMs ?? config.idlePauseMs,
|
|
121
|
+
lastActivityAt: existing?.lastActivityAt ?? null,
|
|
122
|
+
lastWakeAt: existing?.lastWakeAt ?? null,
|
|
123
|
+
lastPauseAt: existing?.lastPauseAt ?? null,
|
|
124
|
+
updatedAt: now,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export function updateTenantState(config, tenantId, mutate) {
|
|
128
|
+
const state = ensureProxyState(config);
|
|
129
|
+
const current = state.tenants[tenantId] ?? ensureTenantState(undefined, config);
|
|
130
|
+
const draft = { ...current, tenantId, ownerUserId: config.ownerUserId, m0RegistryPath: config.m0RegistryPath, idleAfterMs: config.idlePauseMs };
|
|
131
|
+
const next = mutate(draft) ?? draft;
|
|
132
|
+
next.updatedAt = nowIso();
|
|
133
|
+
state.tenants[tenantId] = next;
|
|
134
|
+
return saveProxyState(config.statePath, state).tenants[tenantId];
|
|
135
|
+
}
|
|
136
|
+
export function touchTenantActivity(config, tenantId) {
|
|
137
|
+
return updateTenantState(config, tenantId, (tenant) => {
|
|
138
|
+
tenant.lastActivityAt = nowIso();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export function touchTenantWake(config, tenantId) {
|
|
142
|
+
return updateTenantState(config, tenantId, (tenant) => {
|
|
143
|
+
tenant.lastWakeAt = nowIso();
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
export function touchTenantPause(config, tenantId) {
|
|
147
|
+
return updateTenantState(config, tenantId, (tenant) => {
|
|
148
|
+
tenant.lastPauseAt = nowIso();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
export function withTenantLock(tenantId, fn) {
|
|
152
|
+
const previous = tenantLocks.get(tenantId) ?? Promise.resolve();
|
|
153
|
+
let release;
|
|
154
|
+
const current = new Promise((resolve) => {
|
|
155
|
+
release = resolve;
|
|
156
|
+
});
|
|
157
|
+
const tail = previous.then(() => current, () => current);
|
|
158
|
+
tenantLocks.set(tenantId, tail);
|
|
159
|
+
return previous
|
|
160
|
+
.catch(() => undefined)
|
|
161
|
+
.then(() => Promise.resolve(fn()))
|
|
162
|
+
.finally(() => {
|
|
163
|
+
release();
|
|
164
|
+
if (tenantLocks.get(tenantId) === tail) {
|
|
165
|
+
tenantLocks.delete(tenantId);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
function runtimeFor(tenantId) {
|
|
170
|
+
const existing = tenantRuntimes.get(tenantId);
|
|
171
|
+
if (existing !== undefined)
|
|
172
|
+
return existing;
|
|
173
|
+
const created = {
|
|
174
|
+
counts: { http: 0, ws: 0, wake: 0 },
|
|
175
|
+
idleDeadlineAt: null,
|
|
176
|
+
timer: null,
|
|
177
|
+
};
|
|
178
|
+
tenantRuntimes.set(tenantId, created);
|
|
179
|
+
return created;
|
|
180
|
+
}
|
|
181
|
+
function clearTimer(runtime) {
|
|
182
|
+
if (runtime.timer !== null) {
|
|
183
|
+
clearTimeout(runtime.timer);
|
|
184
|
+
runtime.timer = null;
|
|
185
|
+
}
|
|
186
|
+
runtime.idleDeadlineAt = null;
|
|
187
|
+
}
|
|
188
|
+
export function beginActivity(config, tenantId, kind) {
|
|
189
|
+
const runtime = runtimeFor(tenantId);
|
|
190
|
+
runtime.counts[kind] += 1;
|
|
191
|
+
clearTimer(runtime);
|
|
192
|
+
touchTenantActivity(config, tenantId);
|
|
193
|
+
return {
|
|
194
|
+
tenantId,
|
|
195
|
+
kind,
|
|
196
|
+
acquiredAt: nowIso(),
|
|
197
|
+
closed: false,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
export function endActivity(handle) {
|
|
201
|
+
const runtime = runtimeFor(handle.tenantId);
|
|
202
|
+
if (!handle.closed) {
|
|
203
|
+
handle.closed = true;
|
|
204
|
+
runtime.counts[handle.kind] = Math.max(0, runtime.counts[handle.kind] - 1);
|
|
205
|
+
}
|
|
206
|
+
const total = runtime.counts.http + runtime.counts.ws + runtime.counts.wake;
|
|
207
|
+
return {
|
|
208
|
+
tenantId: handle.tenantId,
|
|
209
|
+
counts: { ...runtime.counts },
|
|
210
|
+
total,
|
|
211
|
+
idleDeadlineAt: runtime.idleDeadlineAt,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
export function getTenantActivitySnapshot(tenantId) {
|
|
215
|
+
const runtime = runtimeFor(tenantId);
|
|
216
|
+
return {
|
|
217
|
+
tenantId,
|
|
218
|
+
counts: { ...runtime.counts },
|
|
219
|
+
total: runtime.counts.http + runtime.counts.ws + runtime.counts.wake,
|
|
220
|
+
idleDeadlineAt: runtime.idleDeadlineAt,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
export function setTenantIdleTimer(tenantId, deadlineAt, timer) {
|
|
224
|
+
const runtime = runtimeFor(tenantId);
|
|
225
|
+
clearTimer(runtime);
|
|
226
|
+
runtime.idleDeadlineAt = deadlineAt;
|
|
227
|
+
runtime.timer = timer;
|
|
228
|
+
}
|
|
229
|
+
export function clearTenantIdleTimer(tenantId) {
|
|
230
|
+
clearTimer(runtimeFor(tenantId));
|
|
231
|
+
}
|
|
232
|
+
export function readTenantHome(config, tenantId) {
|
|
233
|
+
return getHome(config.m0RegistryPath, tenantId);
|
|
234
|
+
}
|
|
235
|
+
function mergeHomeStorage(home, m0Config, volumeId) {
|
|
236
|
+
const next = { ...home };
|
|
237
|
+
next.providerName = m0Config.providerName;
|
|
238
|
+
next.homeStorage = {
|
|
239
|
+
kind: 'volume',
|
|
240
|
+
durability: 'durable-volume',
|
|
241
|
+
longTermContract: true,
|
|
242
|
+
ownerMachineId: home.machineId,
|
|
243
|
+
guestHome: m0Config.guestHome,
|
|
244
|
+
volumeId,
|
|
245
|
+
mountPath: m0Config.guestHome,
|
|
246
|
+
};
|
|
247
|
+
return next;
|
|
248
|
+
}
|
|
249
|
+
export function ensureSeededM0Registry(config, m0Config) {
|
|
250
|
+
const existing = getHome(config.m0RegistryPath, config.defaultTenantId);
|
|
251
|
+
if (existing !== null) {
|
|
252
|
+
if (typeof existing.machineId !== 'string' || existing.machineId.trim() === '') {
|
|
253
|
+
throw general('hearth m0 registry is missing machineId — run the existing M0 provision/bootstrap flow before starting the wake proxy', {
|
|
254
|
+
tenantId: config.defaultTenantId,
|
|
255
|
+
registryPath: config.m0RegistryPath,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const updated = updateHome(config.m0RegistryPath, config.defaultTenantId, (home) => {
|
|
259
|
+
if (home.providerName !== m0Config.providerName)
|
|
260
|
+
home.providerName = m0Config.providerName;
|
|
261
|
+
if (!home.homeStorage || home.homeStorage.volumeId.trim() === '') {
|
|
262
|
+
if (config.seedHome === null) {
|
|
263
|
+
throw general('hearth m0 registry is missing homeStorage.volumeId and no seed home was provided', {
|
|
264
|
+
tenantId: config.defaultTenantId,
|
|
265
|
+
registryPath: config.m0RegistryPath,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
home.homeStorage = mergeHomeStorage(home, m0Config, config.seedHome.volumeId).homeStorage;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
home.homeStorage = {
|
|
272
|
+
...home.homeStorage,
|
|
273
|
+
ownerMachineId: home.machineId,
|
|
274
|
+
guestHome: m0Config.guestHome,
|
|
275
|
+
mountPath: m0Config.guestHome,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
if ((typeof home.nodeId !== 'string' || home.nodeId.trim() === '') && config.seedHome?.nodeId) {
|
|
279
|
+
home.nodeId = config.seedHome.nodeId;
|
|
280
|
+
}
|
|
281
|
+
if ((typeof home.relayToken !== 'string' || home.relayToken.trim() === '') && config.seedHome?.relayToken) {
|
|
282
|
+
home.relayToken = config.seedHome.relayToken;
|
|
283
|
+
}
|
|
284
|
+
if (home.state === undefined || home.state === null || home.state === '') {
|
|
285
|
+
home.state = config.seedHome?.state ?? 'running';
|
|
286
|
+
}
|
|
287
|
+
if ((home.webRoute === undefined || home.webRoute === null) && config.seedHome?.webRouteUrl) {
|
|
288
|
+
home.webRoute = {
|
|
289
|
+
routeId: config.seedHome.webRouteUrl,
|
|
290
|
+
machineId: home.machineId,
|
|
291
|
+
targetPort: m0Config.webPort,
|
|
292
|
+
url: config.seedHome.webRouteUrl,
|
|
293
|
+
concreteUrl: config.seedHome.webRouteUrl,
|
|
294
|
+
concreteUrlSource: 'config',
|
|
295
|
+
createdAt: nowIso(),
|
|
296
|
+
raw: null,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
home.updatedAt = nowIso();
|
|
300
|
+
});
|
|
301
|
+
return updated;
|
|
302
|
+
}
|
|
303
|
+
if (config.seedHome === null) {
|
|
304
|
+
throw general('hearth m0 registry is empty and no HEARTH_SEED_* values were provided — run the existing M0 provision/bootstrap flow before starting the wake proxy', {
|
|
305
|
+
registryPath: config.m0RegistryPath,
|
|
306
|
+
tenantId: config.defaultTenantId,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
const now = nowIso();
|
|
310
|
+
const home = {
|
|
311
|
+
tenantId: config.seedHome.tenantId,
|
|
312
|
+
providerName: m0Config.providerName,
|
|
313
|
+
machineId: config.seedHome.machineId,
|
|
314
|
+
homeStorage: {
|
|
315
|
+
kind: 'volume',
|
|
316
|
+
durability: 'durable-volume',
|
|
317
|
+
longTermContract: true,
|
|
318
|
+
ownerMachineId: config.seedHome.machineId,
|
|
319
|
+
guestHome: m0Config.guestHome,
|
|
320
|
+
volumeId: config.seedHome.volumeId,
|
|
321
|
+
mountPath: m0Config.guestHome,
|
|
322
|
+
},
|
|
323
|
+
state: config.seedHome.state ?? 'running',
|
|
324
|
+
nodeId: config.seedHome.nodeId,
|
|
325
|
+
relayToken: config.seedHome.relayToken,
|
|
326
|
+
webRoute: config.seedHome.webRouteUrl
|
|
327
|
+
? {
|
|
328
|
+
routeId: config.seedHome.webRouteUrl,
|
|
329
|
+
machineId: config.seedHome.machineId,
|
|
330
|
+
targetPort: m0Config.webPort,
|
|
331
|
+
url: config.seedHome.webRouteUrl,
|
|
332
|
+
concreteUrl: config.seedHome.webRouteUrl,
|
|
333
|
+
concreteUrlSource: 'config',
|
|
334
|
+
createdAt: now,
|
|
335
|
+
raw: null,
|
|
336
|
+
}
|
|
337
|
+
: null,
|
|
338
|
+
createdAt: now,
|
|
339
|
+
updatedAt: now,
|
|
340
|
+
};
|
|
341
|
+
return putHome(config.m0RegistryPath, home);
|
|
342
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { GuestNodeId, MachineId, MachineState, M0Config, RelayToken, TenantId } from '../../core/hearth/types.js';
|
|
2
|
+
export interface HearthProxyOwnerState {
|
|
3
|
+
ownerUserId: string;
|
|
4
|
+
defaultTenantId: TenantId;
|
|
5
|
+
tokenHash: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface HearthProxyTenantState {
|
|
9
|
+
tenantId: TenantId;
|
|
10
|
+
ownerUserId: string;
|
|
11
|
+
m0RegistryPath: string;
|
|
12
|
+
idleAfterMs: number;
|
|
13
|
+
lastActivityAt: string | null;
|
|
14
|
+
lastWakeAt: string | null;
|
|
15
|
+
lastPauseAt: string | null;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
export interface HearthProxyState {
|
|
19
|
+
version: 1;
|
|
20
|
+
owner: HearthProxyOwnerState;
|
|
21
|
+
tenants: Record<TenantId, HearthProxyTenantState>;
|
|
22
|
+
}
|
|
23
|
+
export interface HearthProxySeedHome {
|
|
24
|
+
tenantId: TenantId;
|
|
25
|
+
machineId: MachineId;
|
|
26
|
+
nodeId: GuestNodeId;
|
|
27
|
+
relayToken: RelayToken;
|
|
28
|
+
volumeId: string;
|
|
29
|
+
state?: MachineState | null;
|
|
30
|
+
webRouteUrl?: string | null;
|
|
31
|
+
}
|
|
32
|
+
export interface HearthProxyConfig {
|
|
33
|
+
host: string;
|
|
34
|
+
port: number;
|
|
35
|
+
publicOrigin: string;
|
|
36
|
+
statePath: string;
|
|
37
|
+
m0RegistryPath: string;
|
|
38
|
+
ownerUserId: string;
|
|
39
|
+
defaultTenantId: TenantId;
|
|
40
|
+
ownerTokenHash: string;
|
|
41
|
+
idlePauseMs: number;
|
|
42
|
+
wakeTimeoutMs: number;
|
|
43
|
+
readyTimeoutMs: number;
|
|
44
|
+
cookieSecure: boolean;
|
|
45
|
+
seedHome: HearthProxySeedHome | null;
|
|
46
|
+
}
|
|
47
|
+
export interface HearthWakeProxyRuntime {
|
|
48
|
+
proxy: HearthProxyConfig;
|
|
49
|
+
m0: M0Config;
|
|
50
|
+
}
|
|
51
|
+
export type ActivityKind = 'http' | 'ws' | 'wake';
|
|
52
|
+
export interface TenantActivitySnapshot {
|
|
53
|
+
tenantId: TenantId;
|
|
54
|
+
counts: Record<ActivityKind, number>;
|
|
55
|
+
total: number;
|
|
56
|
+
idleDeadlineAt: string | null;
|
|
57
|
+
}
|
|
58
|
+
export interface ActivityHandle {
|
|
59
|
+
tenantId: TenantId;
|
|
60
|
+
kind: ActivityKind;
|
|
61
|
+
acquiredAt: string;
|
|
62
|
+
closed: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface AwakenedHome {
|
|
65
|
+
tenantId: TenantId;
|
|
66
|
+
nodeId: GuestNodeId;
|
|
67
|
+
routeUrl: string;
|
|
68
|
+
relayToken: RelayToken;
|
|
69
|
+
machineId: MachineId;
|
|
70
|
+
webPort: number;
|
|
71
|
+
}
|
|
72
|
+
export interface WakeProxyLogger {
|
|
73
|
+
info(message: string, details?: Record<string, unknown>): void;
|
|
74
|
+
warn(message: string, details?: Record<string, unknown>): void;
|
|
75
|
+
error(message: string, details?: Record<string, unknown>): void;
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @crouton-kit/crouter — the sanctioned library surface (design D1).
|
|
2
2
|
//
|
|
3
3
|
// This barrel is the ONLY supported way to import crouter as a library; the
|
|
4
|
-
// `exports` map gates off deep subpath imports, so consumers
|
|
5
|
-
//
|
|
4
|
+
// `exports` map gates off deep subpath imports, so consumers depend on exactly
|
|
5
|
+
// the symbols re-exported here — notably the in-tree web client, which reaches
|
|
6
|
+
// the runtime through the `@crouton-kit/crouter/web` seam.
|
|
6
7
|
// Everything below is a stable, server-facing surface: runtime control that
|
|
7
8
|
// keeps the canvas-row ⇄ pi-session lockstep guarantees, read-only canvas/
|
|
8
9
|
// telemetry queries, and the broker socket client + wire protocol. Nothing
|
|
@@ -85,7 +85,7 @@ after(() => {
|
|
|
85
85
|
test('boot intro asserts the node\'s OWN identity up front (regression: forked node impersonated source)', () => {
|
|
86
86
|
createNode(node('alpha', { name: 'fix-auth', kind: 'developer' }));
|
|
87
87
|
const intro = buildContextIntro('alpha');
|
|
88
|
-
assert.match(intro, /<crtr-
|
|
88
|
+
assert.match(intro, /<crtr-bearings>/, 'opens with the bearings section');
|
|
89
89
|
assert.match(intro, /You are node alpha/, 'names the node by its own id');
|
|
90
90
|
assert.match(intro, /kind developer/, 'states the node kind');
|
|
91
91
|
// Gated (Option A): a fresh (non-fork) node's bearings are its FIRST entry, so
|
|
@@ -93,9 +93,10 @@ test('boot intro asserts the node\'s OWN identity up front (regression: forked n
|
|
|
93
93
|
// naming the copied history "inherited reference material") is fork-only and must
|
|
94
94
|
// NOT appear here.
|
|
95
95
|
assert.ok(!/inherited reference material/.test(intro), 'a non-fork node carries no disown-the-earlier-narrative line');
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
assert.
|
|
96
|
+
// Identity LEADS the bearings block (no wrapper of its own), so it is the first
|
|
97
|
+
// prose the model reads — the orienting frame, not a trailing note.
|
|
98
|
+
assert.match(intro, /<crtr-bearings>\nYou are node alpha/, 'identity leads the bearings block');
|
|
99
|
+
assert.ok(intro.indexOf('<crtr-bearings>') < intro.indexOf('<project_context>'), 'bearings precede project context');
|
|
99
100
|
});
|
|
100
101
|
test('a FORK\'s intro names the source and disowns it (regression: fork acted AS the source)', () => {
|
|
101
102
|
// The source node whose conversation pi copied into the fork.
|
|
@@ -124,7 +125,7 @@ test('session_start INJECTS the fork\'s own bearings despite the inherited sourc
|
|
|
124
125
|
createNode(node('srcA'));
|
|
125
126
|
createNode(node('forkB', { fork_from: 'srcA' }));
|
|
126
127
|
// A fork boots with the SOURCE's whole conversation copied in — including the
|
|
127
|
-
// source's
|
|
128
|
+
// source's bearings intro entry (which names srcA, not forkB).
|
|
128
129
|
const inheritedSourceBlock = introEntry(buildContextIntro('srcA'));
|
|
129
130
|
process.env['CRTR_NODE_ID'] = 'forkB';
|
|
130
131
|
const pi = makeFakePi();
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
//
|
|
16
16
|
// The block carries: the path to the node's own context dir and the framing for
|
|
17
17
|
// what belongs there (a shared document store for the other nodes). EVERY node
|
|
18
|
-
// also gets a `<knowledge>` block rendered from the document
|
|
19
|
-
// eligible `knowledge` docs at their system-prompt visibility rung,
|
|
20
|
-
// node's own node-local substrate docs — so the bearings name what to
|
|
21
|
-
// demand. (Preferences surface as their own `<
|
|
22
|
-
// system prompt, not in this block.) An
|
|
18
|
+
// also gets a `<memory kind="knowledge">` block rendered from the document
|
|
19
|
+
// substrate — eligible `knowledge` docs at their system-prompt visibility rung,
|
|
20
|
+
// plus the node's own node-local substrate docs — so the bearings name what to
|
|
21
|
+
// read on demand. (Preferences surface as their own `<memory kind="preference">`
|
|
22
|
+
// block of the system prompt, not in this block.) An
|
|
23
23
|
// orchestrator additionally gets the across-refresh-cycles framing (the one
|
|
24
24
|
// thing a terminal worker's bearings drop). The prose lives in
|
|
25
25
|
// core/runtime/bearings.ts (shared with the promotion guidance dump).
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
// (whose bearings name the SOURCE's node id), so the handler must NOT treat that
|
|
32
32
|
// inherited block as ours; it only skips when a bearings block belonging to OUR
|
|
33
33
|
// node is already present (exact `details.nodeId` stamp, content-match
|
|
34
|
-
// fallback), otherwise it injects ours — whose
|
|
35
|
-
// the fork's identity over the inherited persona. This is ONE of two reinforcing
|
|
34
|
+
// fallback), otherwise it injects ours — whose identity assertion (leading the
|
|
35
|
+
// <crtr-bearings> block) reasserts the fork's identity over the inherited persona. This is ONE of two reinforcing
|
|
36
36
|
// channels: spawn.ts ALSO prepends the same identity assertion to a fork's
|
|
37
37
|
// kickoff prompt (the turn-triggering message), so the override does not rest on
|
|
38
38
|
// a single trailing custom_message.
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
// It owns the substrate's two new pi hooks:
|
|
10
10
|
//
|
|
11
11
|
// 1. before_agent_start — the BOOT system-prompt half. Splices the rendered
|
|
12
|
-
// `<
|
|
13
|
-
// right after pi's native "Available tools" list
|
|
14
|
-
// `\n\nGuidelines:` anchor), so the substrate's standing
|
|
15
|
-
// the tool-selection frame the agent reads while choosing
|
|
16
|
-
// mirroring the personal crouter-help.ts anchor logic. Falls
|
|
17
|
-
// appending when the anchor is absent. (
|
|
18
|
-
// bearings message instead — see core/substrate/render.ts.)
|
|
12
|
+
// `<memory kind="preference">` block (memory-usage guidance + preferences)
|
|
13
|
+
// into `event.systemPrompt`, right after pi's native "Available tools" list
|
|
14
|
+
// (before the `\n\nGuidelines:` anchor), so the substrate's standing
|
|
15
|
+
// directives sit in the tool-selection frame the agent reads while choosing
|
|
16
|
+
// a capability — mirroring the personal crouter-help.ts anchor logic. Falls
|
|
17
|
+
// back to appending when the anchor is absent. (The `<memory kind="knowledge">`
|
|
18
|
+
// catalog rides the bearings message instead — see core/substrate/render.ts.)
|
|
19
19
|
//
|
|
20
20
|
// 2. tool_result (gated on `read`) — the ON-READ half. For each non-error
|
|
21
21
|
// `read`, surfaces the substrate docs that should appear alongside the file
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
// with no dep on the pi packages. Mirrors canvas-context-intro.ts.
|
|
35
35
|
import { homedir } from 'node:os';
|
|
36
36
|
import { join, resolve } from 'node:path';
|
|
37
|
-
import {
|
|
37
|
+
import { renderOnReadDocs, renderPreferencesSection, } from '../core/substrate/index.js';
|
|
38
38
|
import { clearSessionCache } from '../core/substrate/session-cache.js';
|
|
39
39
|
import { loadInjectedDocs, saveInjectedDocs } from '../core/substrate/injected-store.js';
|
|
40
40
|
// ---------------------------------------------------------------------------
|
|
@@ -42,8 +42,8 @@ import { loadInjectedDocs, saveInjectedDocs } from '../core/substrate/injected-s
|
|
|
42
42
|
// ---------------------------------------------------------------------------
|
|
43
43
|
/** The stable seam that closes pi's native "Available tools" list. We splice the
|
|
44
44
|
* substrate's boot sections right before it — the agent decides which capability
|
|
45
|
-
* to reach for while reading the tools, so
|
|
46
|
-
* not far below. Mirrors crouter-help.ts. Falls back to appending if absent. */
|
|
45
|
+
* to reach for while reading the tools, so memory docs/preferences must sit
|
|
46
|
+
* there, not far below. Mirrors crouter-help.ts. Falls back to appending if absent. */
|
|
47
47
|
const TOOLS_ANCHOR = '\n\nGuidelines:';
|
|
48
48
|
/**
|
|
49
49
|
* Register the document substrate's two render hooks on `pi`.
|
|
@@ -67,24 +67,21 @@ export function registerCanvasDocSubstrate(pi) {
|
|
|
67
67
|
const injectedDocs = loadInjectedDocs(nodeId);
|
|
68
68
|
pi.on('session_start', () => {
|
|
69
69
|
// Only the per-session substrate PARSE cache resets each session (so the
|
|
70
|
-
// corpus is re-scanned, picking up
|
|
70
|
+
// corpus is re-scanned, picking up memory writes). injectedDocs is
|
|
71
71
|
// transcript-scoped, not session-scoped — deliberately NOT cleared here.
|
|
72
72
|
clearSessionCache();
|
|
73
73
|
});
|
|
74
|
-
// 1. BOOT system-prompt half — splice `<
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
74
|
+
// 1. BOOT system-prompt half — splice the `<memory kind="preference">` block
|
|
75
|
+
// (memory-usage guidance + preferences). The guidance frame is always
|
|
76
|
+
// present for a canvas node (the memory system always exists), so the block
|
|
77
|
+
// is never empty even when no preference is eligible. (The knowledge catalog
|
|
78
|
+
// no longer enters the system prompt — it rides the bearings message via
|
|
79
|
+
// renderKnowledgeBlock.)
|
|
79
80
|
pi.on('before_agent_start', (event) => {
|
|
80
81
|
try {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
renderMemoryGuidance(),
|
|
84
|
-
].filter((s) => s !== '');
|
|
85
|
-
if (sections.length === 0)
|
|
82
|
+
const block = renderPreferencesSection(nodeId);
|
|
83
|
+
if (block === '')
|
|
86
84
|
return; // nothing eligible — leave the prompt untouched
|
|
87
|
-
const block = sections.join('\n\n');
|
|
88
85
|
const idx = event.systemPrompt.indexOf(TOOLS_ANCHOR);
|
|
89
86
|
if (idx === -1) {
|
|
90
87
|
return { systemPrompt: `${event.systemPrompt}\n\n${block}` };
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
// viewing the node: a `focuses` viewport points at it
|
|
26
26
|
// (tmux host) or ≥1 helloed viewer is connected to its
|
|
27
27
|
// broker (job/attach.json). Running is a separate axis,
|
|
28
|
-
// signaled by the
|
|
29
|
-
// its host — which may be an unwatched backstage pane
|
|
30
|
-
//
|
|
28
|
+
// signaled by the overlay-aware glyph (●/○/⟳/⚠) alone on
|
|
29
|
+
// its host — which may be an unwatched backstage pane or
|
|
30
|
+
// a paneless broker).
|
|
31
31
|
// SELF = bold name — a quiet "you are here" marker.
|
|
32
32
|
//
|
|
33
33
|
// Folding is auto by default: a branch stays COLLAPSED unless its subtree holds
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
// inside crouter's own tsc build without a dep on the pi packages.
|
|
46
46
|
import { execFile } from 'node:child_process';
|
|
47
47
|
import { fullName } from '../core/canvas/index.js';
|
|
48
|
-
import { beginFrame, cNode, managerOf, liveReports, sortedChildIds, subtreeIds, climbRoot, computeSubtreeActivity, buildGraphModel, renderGraphRow, navLabel,
|
|
48
|
+
import { beginFrame, cNode, managerOf, liveReports, sortedChildIds, subtreeIds, climbRoot, computeSubtreeActivity, buildGraphModel, renderGraphRow, navLabel, nodeGlyph, truncate, tokensCell, cycleBadge, childBadge, liveBelowBadge, askBadge, activityCell, focusedNodeIds, graphWidgetBudget, fetchAsksMap, shortId, DIM, RESET, BOLD, YELLOW, GRAPH_HINT, } from '../core/canvas/nav-model.js';
|
|
49
49
|
import { readConfig } from '../core/config.js';
|
|
50
50
|
import { onNavRerender } from './widget-order-bus.js';
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
@@ -207,7 +207,7 @@ export function registerCanvasNav(pi) {
|
|
|
207
207
|
else {
|
|
208
208
|
const mn = cNode(mgr);
|
|
209
209
|
const name = navLabel(mn, mgr);
|
|
210
|
-
const mgrLine = truncate(`↑ ${name} ${
|
|
210
|
+
const mgrLine = truncate(`↑ ${name} ${nodeGlyph(mn)} ${DIM}${mn?.kind ?? ''}${RESET} ${DIM}${tokensCell(mgr)}${RESET}${cycleBadge(mn)}${childBadge(mn)}${liveBelowBadge(mn, activity.activeBelow)}${askBadge(mgr, asksMap)}${activityCell(mgr, mn)}`);
|
|
211
211
|
ui.setWidget('crtr-managers', [mgrLine], { placement: 'aboveEditor' });
|
|
212
212
|
}
|
|
213
213
|
const reports = liveReports(nodeId);
|
|
@@ -220,7 +220,7 @@ export function registerCanvasNav(pi) {
|
|
|
220
220
|
const name = navLabel(n, id).padEnd(nameW);
|
|
221
221
|
const kind = `${DIM}${(n?.kind ?? '').padEnd(6)}${RESET}`;
|
|
222
222
|
const tokens = `${DIM}${tokensCell(id).padStart(5)}${RESET}`;
|
|
223
|
-
lines.push(truncate(` ${
|
|
223
|
+
lines.push(truncate(` ${nodeGlyph(n)} ${name} ${kind} ${tokens}${cycleBadge(n)}${childBadge(n)}${liveBelowBadge(n, activity.activeBelow)}${askBadge(id, asksMap)}${activityCell(id, n)}`));
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
// Self's own pending asks (no self row in BASE) → a trailing inline line.
|
|
@@ -477,6 +477,13 @@ export function registerCanvasNav(pi) {
|
|
|
477
477
|
render();
|
|
478
478
|
return { consume: true };
|
|
479
479
|
}
|
|
480
|
+
if (isPlain(data, 'e')) {
|
|
481
|
+
// Expand → tmux: spread the cursor node's local subtree into a tiled tmux
|
|
482
|
+
// window (same action as the alt+c → e menu chord), for parity.
|
|
483
|
+
shellCrtr(['canvas', 'tmux-spread', cursorId ?? nodeId], render);
|
|
484
|
+
render();
|
|
485
|
+
return { consume: true };
|
|
486
|
+
}
|
|
480
487
|
// Custom graphBinds — additive only (built-in keys reserved).
|
|
481
488
|
for (const [key, bind] of Object.entries(navConfig.graphBinds)) {
|
|
482
489
|
if (key.length !== 1 || RESERVED_GRAPH_KEYS.has(key))
|
|
@@ -517,8 +524,8 @@ export function registerCanvasNav(pi) {
|
|
|
517
524
|
}
|
|
518
525
|
};
|
|
519
526
|
// -------------------------------------------------------------------------
|
|
520
|
-
// Slash command + shortcut to toggle GRAPH (registered once per load
|
|
521
|
-
//
|
|
527
|
+
// Slash command + shortcut to toggle GRAPH (registered once per load;
|
|
528
|
+
// pi dedupes duplicate names on /reload).
|
|
522
529
|
// -------------------------------------------------------------------------
|
|
523
530
|
if (typeof pi.registerCommand === 'function') {
|
|
524
531
|
pi.registerCommand('graph', {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type PiEvents = 'agent_start' | 'turn_end' | 'agent_end' | 'session_shutdown' | 'session_start' | 'tool_execution_start';
|
|
1
|
+
type PiEvents = 'agent_start' | 'turn_end' | 'agent_end' | 'session_shutdown' | 'session_start' | 'tool_execution_start' | 'tool_execution_end';
|
|
2
2
|
interface PiLike {
|
|
3
3
|
on: (event: PiEvents, handler: (event: any, ctx: any) => void | Promise<void>) => void;
|
|
4
4
|
sendUserMessage: (content: string, options?: {
|