@crouton-kit/crouter 0.3.31 → 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 +9 -3
- 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 +37 -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/__tests__/empty-node-guard.test.d.ts +1 -0
- package/dist/core/feed/__tests__/empty-node-guard.test.js +45 -0
- package/dist/core/feed/feed.js +8 -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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Promotion — the worker→orchestrator polymorph (mode→orchestrator).
|
|
2
2
|
//
|
|
3
|
-
// Two stages
|
|
3
|
+
// Two stages:
|
|
4
4
|
// 1. Promotion → mode flips to orchestrator (mid-turn). This call flips the
|
|
5
5
|
// node's mode and (optionally) its KIND, REWRITES its launch spec to that
|
|
6
6
|
// kind's orchestrator persona (so the next revive comes back as that
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
// never the mere act of spawning a child.
|
|
21
21
|
import { getNode, updateNode } from '../canvas/index.js';
|
|
22
22
|
import { transition } from './lifecycle.js';
|
|
23
|
+
import { ensureDaemon } from '../../daemon/manage.js';
|
|
23
24
|
import { buildLaunchSpec } from './launch.js';
|
|
24
25
|
import { hasRoadmap, seedRoadmap, roadmapPath } from './roadmap.js';
|
|
25
26
|
import { readGoal, goalPath } from './kickoff.js';
|
|
@@ -58,7 +59,7 @@ export function promote(nodeId, opts = {}) {
|
|
|
58
59
|
// Seed a barebones roadmap scaffold if absent so the file exists for a
|
|
59
60
|
// refresh. Pre-fill its Goal from the node's goal doc when present (set at
|
|
60
61
|
// spawn, or captured from the first user message); the node fleshes out the
|
|
61
|
-
// body next, guided by the kind
|
|
62
|
+
// body next, guided by the kind's roadmap memory doc dumped below.
|
|
62
63
|
let roadmapWritten = false;
|
|
63
64
|
if (!hasRoadmap(nodeId)) {
|
|
64
65
|
const goal = readGoal(nodeId);
|
|
@@ -68,10 +69,17 @@ export function promote(nodeId, opts = {}) {
|
|
|
68
69
|
// Flip mode→orchestrator + kind + launch spec. Lifecycle is independent:
|
|
69
70
|
// only set resident when the caller asked for it (the common self-promotion
|
|
70
71
|
// stays terminal/orchestrator — it still reports up + reaps).
|
|
72
|
+
// If the handle is still the spawn-time kind default (name === old kind),
|
|
73
|
+
// carry it to the new kind so the "name === kind ⇒ default, drop it" invariant
|
|
74
|
+
// in fullName() holds across a kind change. Otherwise a node spawned `general`
|
|
75
|
+
// (name="general") that reshapes to `plan` would surface a stale "general"
|
|
76
|
+
// handle in front of its real description.
|
|
77
|
+
const carriesDefaultHandle = node.name === node.kind && targetKind !== node.kind;
|
|
71
78
|
const meta = updateNode(nodeId, {
|
|
72
79
|
kind: targetKind,
|
|
73
80
|
mode: 'orchestrator',
|
|
74
81
|
launch,
|
|
82
|
+
...(carriesDefaultHandle ? { name: targetKind } : {}),
|
|
75
83
|
// Persist a newly-chosen tier so it is durable across future revives; omit
|
|
76
84
|
// when unchanged so the existing pin (or persona default) stands.
|
|
77
85
|
...(opts.model !== undefined ? { model_override: opts.model } : {}),
|
|
@@ -90,7 +98,8 @@ export function promote(nodeId, opts = {}) {
|
|
|
90
98
|
* so it comes back as an orchestrator, optionally specializing its kind. Sets
|
|
91
99
|
* intent='refresh'; the stophook shuts the process down on the next stop and
|
|
92
100
|
* the daemon revives it fresh. */
|
|
93
|
-
export function requestYield(nodeId, opts = {}) {
|
|
101
|
+
export function requestYield(nodeId, opts = {}, deps = {}) {
|
|
102
|
+
const ensure = deps.ensure ?? ensureDaemon;
|
|
94
103
|
const node = getNode(nodeId);
|
|
95
104
|
if (node === null)
|
|
96
105
|
throw new Error(`unknown node: ${nodeId}`);
|
|
@@ -113,6 +122,17 @@ export function requestYield(nodeId, opts = {}) {
|
|
|
113
122
|
// of an already-orchestrator node.
|
|
114
123
|
promoted = wasBase;
|
|
115
124
|
}
|
|
125
|
+
// The refresh-revive is the DAEMON's job: the stophook shuts this broker down
|
|
126
|
+
// on its next stop, and crtrd then sees the dead pid + intent='refresh' and
|
|
127
|
+
// relaunches it fresh. That handoff is silent if the daemon isn't running — the
|
|
128
|
+
// broker exits and nothing ever revives it (the viewer redials its view.sock
|
|
129
|
+
// for ~30s and reports "broker gone"). So ensure the supervisor is alive HERE,
|
|
130
|
+
// before we arm the yield — the same best-effort ensure spawn/recycle do, on
|
|
131
|
+
// the one other path that hands a node off to the daemon. Runs in the fresh
|
|
132
|
+
// `crtr node yield` subprocess, so it always uses current dist (never a stale
|
|
133
|
+
// in-process hook). Injectable for the regression test that locks in this
|
|
134
|
+
// ensure (default = ensureDaemon).
|
|
135
|
+
ensure();
|
|
116
136
|
// Mark the intent; the stophook enacts the shutdown, the daemon the revive.
|
|
117
137
|
transition(nodeId, 'yield');
|
|
118
138
|
const meta = getNode(nodeId);
|
|
@@ -120,7 +120,7 @@ export async function recycleNode(nodeId, callerPane) {
|
|
|
120
120
|
// CRTR_SUBTREE groups the fresh root's subtree; FRONT_DOOR is set by the broker
|
|
121
121
|
// host itself, so it is not added here.
|
|
122
122
|
inv.env = { ...inv.env, CRTR_SUBTREE: rootOfSpine(root.node_id) };
|
|
123
|
-
const ok = recycleBrokerViewer(fresh, pane, inv);
|
|
123
|
+
const ok = await recycleBrokerViewer(fresh, pane, inv);
|
|
124
124
|
return { recycled: ok, finalized, newRoot: root.node_id, delivered };
|
|
125
125
|
}
|
|
126
126
|
/** Recycle a BROKER root into `pane`: the fresh root is broker-hosted, so its
|
|
@@ -131,9 +131,11 @@ export async function recycleNode(nodeId, callerPane) {
|
|
|
131
131
|
* `@crtr_node`); it never hosts the engine. Returns false (recycle reports the
|
|
132
132
|
* pane was not respawned) when the broker never serves — the fresh root row
|
|
133
133
|
* still exists, broker-hosted, for the daemon to revive. */
|
|
134
|
-
function recycleBrokerViewer(fresh, pane, inv) {
|
|
135
|
-
headlessBrokerHost.launch(fresh.node_id, inv, { cwd: fresh.cwd, name: fullName(fresh), resuming: false });
|
|
136
|
-
if (
|
|
134
|
+
async function recycleBrokerViewer(fresh, pane, inv) {
|
|
135
|
+
const placed = headlessBrokerHost.launch(fresh.node_id, inv, { cwd: fresh.cwd, name: fullName(fresh), resuming: false });
|
|
136
|
+
if (placed.pid === null)
|
|
137
|
+
return false;
|
|
138
|
+
if (!(await waitForBrokerViewSocket(fresh.node_id, placed.exited)))
|
|
137
139
|
return false;
|
|
138
140
|
// Clear the finalized node's stale `@crtr_node` tag before respawn so the tag
|
|
139
141
|
// never names a done node during the gap before the new `crtr attach` re-tags
|
|
@@ -19,7 +19,10 @@ export interface RelaunchDeps {
|
|
|
19
19
|
/** Boot the new node's detached broker engine. Default: headlessBrokerHost.launch. */
|
|
20
20
|
launchBroker?: typeof headlessBrokerHost.launch;
|
|
21
21
|
/** Wait for the new broker's view.sock to accept. Default: waitForBrokerViewSocket. */
|
|
22
|
-
waitForViewSocket?: (nodeId: string
|
|
22
|
+
waitForViewSocket?: (nodeId: string, exited?: Promise<{
|
|
23
|
+
code: number | null;
|
|
24
|
+
signal: NodeJS.Signals | null;
|
|
25
|
+
}>) => boolean | Promise<boolean>;
|
|
23
26
|
/** Re-exec the viewer pane onto the new node. Default: respawnPaneSync. */
|
|
24
27
|
respawnViewer?: typeof respawnPaneSync;
|
|
25
28
|
/** Tear the old broker down. Default: headlessBrokerHost.teardown. */
|
|
@@ -35,7 +38,7 @@ export interface RelaunchRootResult {
|
|
|
35
38
|
* is touched, so any pre-commit failure leaves the old root fully intact and
|
|
36
39
|
* live. Returns null when `oldId` is not a relaunchable root (unknown, a child,
|
|
37
40
|
* or already parked), or when the new broker failed to launch. */
|
|
38
|
-
export declare function relaunchRoot(oldId: string, deps?: RelaunchDeps): RelaunchRootResult | null
|
|
41
|
+
export declare function relaunchRoot(oldId: string, deps?: RelaunchDeps): Promise<RelaunchRootResult | null>;
|
|
39
42
|
export interface ResetRootResult {
|
|
40
43
|
/** Descendant node ids torn down. Always empty — a child `/new` reaps nothing. */
|
|
41
44
|
reaped: string[];
|
|
@@ -68,7 +68,7 @@ export function reapDescendants(rootId) {
|
|
|
68
68
|
* is touched, so any pre-commit failure leaves the old root fully intact and
|
|
69
69
|
* live. Returns null when `oldId` is not a relaunchable root (unknown, a child,
|
|
70
70
|
* or already parked), or when the new broker failed to launch. */
|
|
71
|
-
export function relaunchRoot(oldId, deps = {}) {
|
|
71
|
+
export async function relaunchRoot(oldId, deps = {}) {
|
|
72
72
|
const launchBroker = deps.launchBroker ?? headlessBrokerHost.launch;
|
|
73
73
|
const waitForViewSocket = deps.waitForViewSocket ?? waitForBrokerViewSocket;
|
|
74
74
|
const respawnViewer = deps.respawnViewer ?? respawnPaneSync;
|
|
@@ -115,7 +115,7 @@ export function relaunchRoot(oldId, deps = {}) {
|
|
|
115
115
|
transition(newMeta.node_id, 'crash');
|
|
116
116
|
return null;
|
|
117
117
|
}
|
|
118
|
-
waitForViewSocket(newMeta.node_id); // best-effort; attach auto-redials on miss
|
|
118
|
+
await waitForViewSocket(newMeta.node_id, placed.exited); // best-effort; attach auto-redials on miss
|
|
119
119
|
// --- COMMIT: park + reap the old root, re-point the viewer, kill the old
|
|
120
120
|
// broker. Past this point the new node is the live root. ---
|
|
121
121
|
reapDescendants(oldId); // old workers → canceled + torn down
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type NodeMeta } from '../canvas/index.js';
|
|
2
2
|
import type { WakeOrigin } from './bearings.js';
|
|
3
|
+
import { headlessBrokerHost } from './host.js';
|
|
3
4
|
/** Pick the `--session` source for a revive. resume=true prefers the absolute
|
|
4
5
|
* session-file path (immune to cwd; pi opens it directly) and keeps the bare
|
|
5
6
|
* session id as the fallback for older nodes booted before pi_session_file was
|
|
@@ -19,6 +20,9 @@ export interface ReviveResult {
|
|
|
19
20
|
session: string | null;
|
|
20
21
|
/** True when pi was instructed to resume its saved conversation (`--session <id>`). */
|
|
21
22
|
resumed: boolean;
|
|
23
|
+
/** Launch handle for the detached broker, so callers can fail fast on its real
|
|
24
|
+
* exit before the socket appears. */
|
|
25
|
+
launch?: ReturnType<typeof headlessBrokerHost.launch>;
|
|
22
26
|
}
|
|
23
27
|
/** Relaunch `nodeId`'s broker engine from its persisted recipe and update canvas
|
|
24
28
|
* meta. Opens no viewer (engine-only).
|
|
@@ -21,6 +21,7 @@ import { buildPiArgv } from './launch.js';
|
|
|
21
21
|
import { buildReviveKickoff, drainBearings } from './kickoff.js';
|
|
22
22
|
import { headlessBrokerHost } from './host.js';
|
|
23
23
|
import { isPidAlive } from '../canvas/pid.js';
|
|
24
|
+
import { clearFault } from './fault.js';
|
|
24
25
|
import { clearInjectedDocs } from '../substrate/injected-store.js';
|
|
25
26
|
// ---------------------------------------------------------------------------
|
|
26
27
|
// resumeArgs — which session source a revive resumes from
|
|
@@ -72,9 +73,9 @@ export function reviveNode(nodeId, opts) {
|
|
|
72
73
|
resumed: false,
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
|
-
// Every (re)launch is a new cycle — bump the counter so
|
|
76
|
-
//
|
|
77
|
-
//
|
|
76
|
+
// Every (re)launch is a new cycle — bump the counter so CRTR_CYCLES and the
|
|
77
|
+
// footer stay in sync. Mutate the in-memory meta too so buildPiArgv below
|
|
78
|
+
// launches with the incremented count.
|
|
78
79
|
meta.cycles = (meta.cycles ?? 0) + 1;
|
|
79
80
|
updateNode(nodeId, { cycles: meta.cycles });
|
|
80
81
|
// Decide whether to wake the saved pi conversation or start fresh. Prefer the
|
|
@@ -106,19 +107,36 @@ export function reviveNode(nodeId, opts) {
|
|
|
106
107
|
// opens NO viewer — engine-only; existing viewers reconnect, and a viewer-less
|
|
107
108
|
// node is brought on screen by the next `focus`.
|
|
108
109
|
transition(nodeId, 'revive');
|
|
110
|
+
// Clear any active fault the instant this node is (re)launched — don't wait
|
|
111
|
+
// for the fresh agent_start. A revive (auto or on-demand) is the recovery
|
|
112
|
+
// this marker advertised.
|
|
113
|
+
clearFault(nodeId);
|
|
109
114
|
// Cancel-on-wake (design §6.4, AC-E1): every revive-for-any-reason (an inbox
|
|
110
115
|
// event, a different wake, a manual focus) drops this node's pending deadline,
|
|
111
116
|
// so the deadline always belongs to the dormancy being left. Writes only the
|
|
112
117
|
// wakeups table, after the atomic transition above.
|
|
113
118
|
cancelDeadlinesFor(nodeId);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
let launched;
|
|
120
|
+
try {
|
|
121
|
+
launched = headlessBrokerHost.launch(nodeId, inv, {
|
|
122
|
+
cwd: meta.cwd,
|
|
123
|
+
name: fullName(meta),
|
|
124
|
+
resuming,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
try {
|
|
129
|
+
transition(nodeId, 'crash');
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
/* best-effort cleanup */
|
|
133
|
+
}
|
|
134
|
+
clearPid(nodeId);
|
|
135
|
+
throw new Error(`[broker] refusing to revive ${nodeId}: ${error.message}`);
|
|
136
|
+
}
|
|
119
137
|
// Clear the stale pid so the daemon won't re-fire on it during the new
|
|
120
138
|
// broker's boot. The fresh broker re-records its pid during extension bind; if
|
|
121
139
|
// it never boots, the daemon's boot-grace + surfaceBootFailure own that case.
|
|
122
140
|
clearPid(nodeId);
|
|
123
|
-
return { window: null, session: meta.tmux_session ?? null, resumed: resuming };
|
|
141
|
+
return { window: null, session: meta.tmux_session ?? null, resumed: resuming, launch: launched };
|
|
124
142
|
}
|
|
@@ -4,7 +4,7 @@ export declare function readRoadmap(nodeId: string): string | null;
|
|
|
4
4
|
/** Seed a fresh, EXTREMELY BAREBONES roadmap scaffold — just the section
|
|
5
5
|
* skeleton with one-line prompts. Promotion lays this down so the file exists
|
|
6
6
|
* for a refresh; the owner fleshes it out as its next act (guided by its
|
|
7
|
-
*
|
|
7
|
+
* roadmap memory doc). `goal`/`exitCriteria` pre-fill those sections when
|
|
8
8
|
* known (e.g. from the node's goal doc). Idempotent only if you intend it —
|
|
9
9
|
* call sites guard on hasRoadmap to avoid clobbering an evolved map. */
|
|
10
10
|
export declare function seedRoadmap(nodeId: string, opts?: {
|
|
@@ -23,7 +23,7 @@ export function readRoadmap(nodeId) {
|
|
|
23
23
|
/** Seed a fresh, EXTREMELY BAREBONES roadmap scaffold — just the section
|
|
24
24
|
* skeleton with one-line prompts. Promotion lays this down so the file exists
|
|
25
25
|
* for a refresh; the owner fleshes it out as its next act (guided by its
|
|
26
|
-
*
|
|
26
|
+
* roadmap memory doc). `goal`/`exitCriteria` pre-fill those sections when
|
|
27
27
|
* known (e.g. from the node's goal doc). Idempotent only if you intend it —
|
|
28
28
|
* call sites guard on hasRoadmap to avoid clobbering an evolved map. */
|
|
29
29
|
export function seedRoadmap(nodeId, opts = {}) {
|
|
@@ -11,7 +11,7 @@ export interface BootRootOpts {
|
|
|
11
11
|
* inline so THIS terminal becomes the broker's controller-viewer. Does not
|
|
12
12
|
* return — it process.exit()s when the inline attach exits (detach leaves the
|
|
13
13
|
* resident broker running, to be reconnected later). */
|
|
14
|
-
export declare function bootRoot(opts: BootRootOpts): NodeMeta
|
|
14
|
+
export declare function bootRoot(opts: BootRootOpts): Promise<NodeMeta>;
|
|
15
15
|
export interface SpawnChildOpts {
|
|
16
16
|
kind: string;
|
|
17
17
|
mode?: Mode;
|
|
@@ -70,4 +70,4 @@ export declare function resolveSpawner(parent: string | undefined, ctxNodeId: st
|
|
|
70
70
|
* With `root`: an independent resident root — parent=null, NO subscription back
|
|
71
71
|
* to the spawner (it carries spawned_by=spawner for provenance only), brought
|
|
72
72
|
* forefront so a human can pick up the conversation directly. */
|
|
73
|
-
export declare function spawnChild(opts: SpawnChildOpts): SpawnChildResult
|
|
73
|
+
export declare function spawnChild(opts: SpawnChildOpts): Promise<SpawnChildResult>;
|
|
@@ -24,11 +24,29 @@ import { registerViewerFocus, openViewerWindow, waitForBrokerViewSocket, viewerS
|
|
|
24
24
|
import { transition } from './lifecycle.js';
|
|
25
25
|
import { headlessBrokerHost } from './host.js';
|
|
26
26
|
import { ensureDaemon } from '../../daemon/manage.js';
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Shared broker-launch wrapper — catch launch/preflight failures at the call
|
|
29
|
+
// site, mark the node crashed, then rethrow a clear error.
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
function launchBrokerOrCrash(nodeId, inv, opts) {
|
|
32
|
+
try {
|
|
33
|
+
return headlessBrokerHost.launch(nodeId, inv, opts);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
try {
|
|
37
|
+
transition(nodeId, 'crash');
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* best-effort cleanup */
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`[broker] refusing to launch ${nodeId}: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
27
45
|
/** Create the front-door root: launch its broker engine, then exec `crtr attach`
|
|
28
46
|
* inline so THIS terminal becomes the broker's controller-viewer. Does not
|
|
29
47
|
* return — it process.exit()s when the inline attach exits (detach leaves the
|
|
30
48
|
* resident broker running, to be reconnected later). */
|
|
31
|
-
export function bootRoot(opts) {
|
|
49
|
+
export async function bootRoot(opts) {
|
|
32
50
|
// crtr is tmux-only: the front door execs `crtr attach` inline in THIS pane to
|
|
33
51
|
// become the root's controller-viewer, so there must be a tmux pane to anchor
|
|
34
52
|
// on. Outside tmux there is no viewer surface — throw with a friendly message
|
|
@@ -98,7 +116,7 @@ export function bootRoot(opts) {
|
|
|
98
116
|
// broker and the viewer reconnects), and THIS terminal execs `crtr attach`
|
|
99
117
|
// inline to become its controller-viewer. The host sets CRTR_FRONT_DOOR.
|
|
100
118
|
inv.env = { ...inv.env, CRTR_SUBTREE: rootOfSpine(meta.node_id) };
|
|
101
|
-
const placed =
|
|
119
|
+
const placed = launchBrokerOrCrash(meta.node_id, inv, {
|
|
102
120
|
cwd: opts.cwd,
|
|
103
121
|
name: fullName(meta),
|
|
104
122
|
resuming: false,
|
|
@@ -112,7 +130,13 @@ export function bootRoot(opts) {
|
|
|
112
130
|
// The terminal has nothing to attach to until view.sock accepts. The root is
|
|
113
131
|
// useless without its engine, so a socket timeout IS fatal here (unlike a
|
|
114
132
|
// background child's optional viewer, which is skipped on timeout).
|
|
115
|
-
if (!waitForBrokerViewSocket(meta.node_id)) {
|
|
133
|
+
if (!(await waitForBrokerViewSocket(meta.node_id, placed.exited))) {
|
|
134
|
+
try {
|
|
135
|
+
transition(meta.node_id, 'crash');
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
/* best-effort cleanup */
|
|
139
|
+
}
|
|
116
140
|
throw new Error(`the front-door root broker ${meta.node_id} never bound its view socket — cannot attach.`);
|
|
117
141
|
}
|
|
118
142
|
const attachEnv = { ...process.env, ...viewerSplitEnv() };
|
|
@@ -210,7 +234,7 @@ export function resolveSpawner(parent, ctxNodeId, root) {
|
|
|
210
234
|
* With `root`: an independent resident root — parent=null, NO subscription back
|
|
211
235
|
* to the spawner (it carries spawned_by=spawner for provenance only), brought
|
|
212
236
|
* forefront so a human can pick up the conversation directly. */
|
|
213
|
-
export function spawnChild(opts) {
|
|
237
|
+
export async function spawnChild(opts) {
|
|
214
238
|
try {
|
|
215
239
|
ensureDaemon();
|
|
216
240
|
}
|
|
@@ -292,7 +316,7 @@ export function spawnChild(opts) {
|
|
|
292
316
|
// gets NO viewer — spawning it returns once the engine is launched and a human
|
|
293
317
|
// opens a viewer on demand via `crtr node focus` / `crtr attach`. A --root gets
|
|
294
318
|
// one foreground viewer below.
|
|
295
|
-
const placed =
|
|
319
|
+
const placed = launchBrokerOrCrash(meta.node_id, inv, {
|
|
296
320
|
cwd: meta.cwd,
|
|
297
321
|
name: fullName(meta),
|
|
298
322
|
resuming: false,
|
|
@@ -313,7 +337,7 @@ export function spawnChild(opts) {
|
|
|
313
337
|
// returns null) or the socket never binds — `focus` opens a viewer later.
|
|
314
338
|
let window = null;
|
|
315
339
|
let session = null;
|
|
316
|
-
if (root && here !== null && waitForBrokerViewSocket(meta.node_id)) {
|
|
340
|
+
if (root && here !== null && await waitForBrokerViewSocket(meta.node_id, placed.exited)) {
|
|
317
341
|
const viewer = openViewerWindow(meta.node_id, here.session, { name: fullName(meta), cwd: opts.cwd });
|
|
318
342
|
if (viewer !== null && viewer.pane !== null && viewer.pane !== '') {
|
|
319
343
|
session = here.session;
|
|
@@ -26,12 +26,17 @@ export function evaluateStop(nodeId, signals) {
|
|
|
26
26
|
return { action: 'allow', reason: 'finished' };
|
|
27
27
|
if (signals.askedHuman)
|
|
28
28
|
return { action: 'allow', reason: 'escalated' };
|
|
29
|
+
// Already-terminal stored state wins before any stall logic: a node that is
|
|
30
|
+
// done/dead/canceled is not waiting to be re-prompted.
|
|
31
|
+
const node = getNode(nodeId);
|
|
32
|
+
if (node !== null && (node.status === 'done' || node.status === 'dead' || node.status === 'canceled')) {
|
|
33
|
+
return { action: 'allow', reason: 'finished' };
|
|
34
|
+
}
|
|
29
35
|
// A RESIDENT node is interactable / human-driven and is never forced to submit
|
|
30
36
|
// a final: stopping to go dormant is always legitimate (the inbox or the human
|
|
31
37
|
// wakes it). Keyed on lifecycle, not parent — whether it has a parent doesn't
|
|
32
38
|
// matter, only whether it's resident. Roots are resident by birth default, so
|
|
33
39
|
// this still covers "don't nag the human's root" while generalizing it.
|
|
34
|
-
const node = getNode(nodeId);
|
|
35
40
|
if (node !== null && node.lifecycle === 'resident') {
|
|
36
41
|
return { action: 'allow', reason: 'dormant' };
|
|
37
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { installMenuBinding, installNavBindings, installViewNavBindings, sendKeysEnter } from './tmux.js';
|
|
1
|
+
export { installMenuBinding, installNavBindings, installViewNavBindings, sendKeysEnter, displayMessage, paneCurrentPath } from './tmux.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// tmux-chrome.ts — chrome seam (§2.1): stateless keybind/input verbs.
|
|
2
2
|
// The ONLY non-placement module allowed to import the tmux driver, per the
|
|
3
3
|
// §5.1 lint. Re-exports the menu/nav/send-keys verbs callers (spawn, chord) need.
|
|
4
|
-
export { installMenuBinding, installNavBindings, installViewNavBindings, sendKeysEnter } from './tmux.js';
|
|
4
|
+
export { installMenuBinding, installNavBindings, installViewNavBindings, sendKeysEnter, displayMessage, paneCurrentPath } from './tmux.js';
|
|
@@ -72,6 +72,18 @@ export declare function closeWindow(window: string): boolean;
|
|
|
72
72
|
* root relaunch to re-title the viewer window when its pane is re-pointed at
|
|
73
73
|
* the freshly-minted node. Best-effort; false if tmux fails. */
|
|
74
74
|
export declare function renameWindow(window: string, name: string): boolean;
|
|
75
|
+
/** Break a single PANE out into a BRAND-NEW window of its own (`tmux break-pane
|
|
76
|
+
* -d`). `-d` keeps the new window in the background (does not switch the client
|
|
77
|
+
* to it); `-s <pane>` names the source pane — the §2.2 HARD DRIVER INVARIANT, so
|
|
78
|
+
* the break never falls back to tmux's global current pane. The pane keeps its
|
|
79
|
+
* durable `%id` across the move (only its window changes), so callers can keep
|
|
80
|
+
* using the same pane handle. Returns the new `{window, pane}` location, or null
|
|
81
|
+
* if tmux fails. Used by `canvas tmux-spread` to lift the caller's viewer into a
|
|
82
|
+
* fresh window before tiling sibling viewers beside it. */
|
|
83
|
+
export declare function breakPane(pane: string): {
|
|
84
|
+
window: string;
|
|
85
|
+
pane: string;
|
|
86
|
+
} | null;
|
|
75
87
|
/** Close a single PANE. Its window closes automatically once this was the last
|
|
76
88
|
* pane, but sibling panes survive — so co-located nodes (several agents sharing
|
|
77
89
|
* one window via swap-pane focus) are torn down one at a time instead of all
|
|
@@ -122,6 +134,11 @@ export declare function listLivePanes(): Set<string> | null;
|
|
|
122
134
|
* '#{pane_current_path}'`). Used to preserve a view monitor's cwd across a
|
|
123
135
|
* view-cycle respawn so project-scoped views still resolve. Null if tmux fails. */
|
|
124
136
|
export declare function paneCurrentPath(pane: string): string | null;
|
|
137
|
+
/** Flash a transient status-line toast on the client showing `pane` (or the
|
|
138
|
+
* current client when `pane` is omitted). `ms` sets the display duration. Used
|
|
139
|
+
* by `crtr canvas issue new` to confirm a capture from inside its popup.
|
|
140
|
+
* Best-effort; never throws. */
|
|
141
|
+
export declare function displayMessage(message: string, pane?: string, ms?: number): boolean;
|
|
125
142
|
/** Set a PANE-scoped tmux option (`tmux set-option -p -t <pane> <name> <value>`).
|
|
126
143
|
* Used to tag a pane with the view id it currently hosts (`@crtr_view`) so the
|
|
127
144
|
* view-nav cycle can read it back and switch to the next/prev view in place.
|
|
@@ -169,6 +186,17 @@ export declare function windowAlive(session: string | null | undefined, window:
|
|
|
169
186
|
/** Activate a window within its session (same-session navigation). Equivalent
|
|
170
187
|
* to `tmux select-window -t <session>:<window>`. Best-effort; never throws. */
|
|
171
188
|
export declare function selectWindow(session: string, window: string): boolean;
|
|
189
|
+
/** Apply a named tmux layout to a window (`tmux select-layout -t <window>
|
|
190
|
+
* <layout>`). `canvas tmux-spread` calls it with `tiled` to evenly grid every
|
|
191
|
+
* viewer pane in the spread window (and between splits, to redistribute space so
|
|
192
|
+
* the next split has room). Best-effort; false if tmux fails. */
|
|
193
|
+
export declare function selectLayout(window: string, layout: string): boolean;
|
|
194
|
+
/** Make a pane the ACTIVE pane in its window (`tmux select-pane -t <pane>`). A
|
|
195
|
+
* `split-window -d` keeps the CALLER active, so a freshly-opened viewer pane is
|
|
196
|
+
* not focused until this runs — `focus` calls it so picking a node (e.g. from the
|
|
197
|
+
* alt+g graph) lands the keyboard on the new viewer. Best-effort; false if tmux
|
|
198
|
+
* fails. */
|
|
199
|
+
export declare function selectPane(pane: string): boolean;
|
|
172
200
|
/** Switch the tmux client to a different session (cross-session focus). Runs
|
|
173
201
|
* `tmux switch-client -t <session>`. Best-effort; never throws. The caller is
|
|
174
202
|
* responsible for following up with selectWindow to land on the right window. */
|
|
@@ -177,12 +205,7 @@ export declare function switchClient(session: string): boolean;
|
|
|
177
205
|
* (`tmux send-keys -t <pane> '<text>' Enter`). Requires the pane's editor be
|
|
178
206
|
* empty, same limitation as the menu's `/promote` item. Best-effort. */
|
|
179
207
|
export declare function sendKeysEnter(pane: string, text: string): boolean;
|
|
180
|
-
/** Bind Alt+C to the crouter action menu. Best-effort; false if tmux fails.
|
|
181
|
-
* The built-in items (promote/resume/demote/detach/close) are static; the canvas-nav
|
|
182
|
-
* chords (default g→graph, m→manager + any custom prefixBind) are appended
|
|
183
|
-
* from `canvasNav.prefixBinds`, each routed through `crtr canvas chord` (or, for
|
|
184
|
-
* the `__graph__` sentinel, a `send-keys '/graph'`) so the menu stays static
|
|
185
|
-
* while behaviour is config-driven. */
|
|
208
|
+
/** Bind Alt+C to the crouter action menu. Best-effort; false if tmux fails. */
|
|
186
209
|
export declare function installMenuBinding(): boolean;
|
|
187
210
|
/** Bind Alt+] (forward) and Alt+[ (back) to the DFS canvas walk. Best-effort;
|
|
188
211
|
* false if either bind fails. NOTE: Alt+[ is only delivered cleanly when the
|