@crouton-kit/crouter 0.3.28 → 0.3.30
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/dist/build-root.d.ts +15 -7
- package/dist/build-root.js +48 -34
- package/dist/builtin-memory/crouter-development/marketplaces.md +7 -6
- package/dist/builtin-memory/crouter-development/personas/base-prompt.md +1 -1
- package/dist/builtin-memory/crouter-development/personas/orchestrator-prompt.md +1 -1
- package/dist/builtin-memory/crouter-development/personas.md +1 -1
- package/dist/builtin-memory/crouter-development/plugins.md +20 -18
- package/dist/builtin-memory/design.md +1 -1
- package/dist/builtin-memory/development.md +1 -1
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-memory/planning.md +1 -1
- package/dist/builtin-memory/spec.md +6 -4
- package/dist/builtin-personas/orchestration-kernel.md +4 -5
- package/dist/builtin-personas/runtime-base.md +5 -4
- package/dist/builtin-personas/spec/PERSONA.md +8 -4
- package/dist/builtin-personas/spec/orchestrator.md +5 -3
- package/dist/builtin-personas/spec/requirements/PERSONA.md +10 -0
- package/dist/builtin-views/canvas/core.mjs +586 -0
- package/dist/builtin-views/canvas/text.mjs +58 -0
- package/dist/builtin-views/canvas/tui.mjs +165 -0
- package/dist/builtin-views/canvas/web.jsx +120 -0
- package/dist/builtin-views/git-pr/core.mjs +673 -0
- package/dist/builtin-views/git-pr/text.mjs +84 -0
- package/dist/builtin-views/git-pr/tui.mjs +302 -0
- package/dist/builtin-views/git-pr/web.jsx +216 -0
- package/dist/builtin-views/inbox/_lib/render.mjs +1 -3
- package/dist/builtin-views/inbox/core.mjs +1273 -0
- package/dist/builtin-views/inbox/text.mjs +73 -0
- package/dist/builtin-views/inbox/tui.mjs +312 -0
- package/dist/builtin-views/inbox/web.jsx +188 -0
- package/dist/builtin-views/linkedin/core.mjs +906 -0
- package/dist/builtin-views/linkedin/text.mjs +69 -0
- package/dist/builtin-views/linkedin/tui.mjs +427 -0
- package/dist/builtin-views/linkedin/web.jsx +206 -0
- package/dist/builtin-views/workspace-sidebar/core.mjs +621 -0
- package/dist/builtin-views/workspace-sidebar/text.mjs +53 -0
- package/dist/builtin-views/workspace-sidebar/tui.mjs +142 -0
- package/dist/builtin-views/workspace-sidebar/web.jsx +109 -0
- package/dist/cli.js +22 -17
- package/dist/clients/attach/__tests__/action-parity.test.js +48 -0
- package/dist/clients/attach/__tests__/clipboard-image.test.js +76 -0
- package/dist/clients/attach/__tests__/editor-newline.test.js +57 -0
- package/dist/clients/attach/__tests__/git-info.test.js +31 -0
- package/dist/clients/attach/__tests__/onrequest-wired.test.js +20 -0
- package/dist/clients/attach/__tests__/slash-quit-copy.test.js +42 -0
- package/dist/clients/attach/__tests__/titled-editor.test.js +39 -0
- package/dist/clients/attach/attach-cmd.js +282 -46
- package/dist/clients/attach/auth-pickers.d.ts +9 -0
- package/dist/clients/attach/auth-pickers.js +194 -0
- package/dist/clients/attach/canvas-panels.d.ts +4 -2
- package/dist/clients/attach/canvas-panels.js +45 -17
- package/dist/clients/attach/chat-view.d.ts +27 -2
- package/dist/clients/attach/chat-view.js +98 -9
- package/dist/clients/attach/clipboard-image.d.ts +47 -8
- package/dist/clients/attach/clipboard-image.js +150 -26
- package/dist/clients/attach/clipboard-text.d.ts +3 -0
- package/dist/clients/attach/clipboard-text.js +39 -0
- package/dist/clients/attach/config-load.d.ts +54 -7
- package/dist/clients/attach/config-load.js +99 -3
- package/dist/clients/attach/context-message.d.ts +12 -0
- package/dist/clients/attach/context-message.js +72 -0
- package/dist/clients/attach/git-info.d.ts +20 -0
- package/dist/clients/attach/git-info.js +44 -0
- package/dist/clients/attach/graph-overlay.d.ts +13 -4
- package/dist/clients/attach/graph-overlay.js +59 -19
- package/dist/clients/attach/input-controller.d.ts +75 -13
- package/dist/clients/attach/input-controller.js +305 -67
- package/dist/clients/attach/pickers.d.ts +58 -0
- package/dist/clients/attach/pickers.js +171 -0
- package/dist/clients/attach/slash-commands.d.ts +22 -0
- package/dist/clients/attach/slash-commands.js +91 -25
- package/dist/clients/attach/titled-editor.d.ts +33 -0
- package/dist/clients/attach/titled-editor.js +84 -0
- package/dist/clients/attach/view-socket.d.ts +18 -1
- package/dist/clients/attach/view-socket.js +70 -1
- package/dist/clients/web/dev-server.d.ts +7 -0
- package/dist/clients/web/dev-server.js +59 -0
- package/dist/clients/web/events.d.ts +14 -0
- package/dist/clients/web/events.js +151 -0
- package/dist/clients/web/server.d.ts +18 -0
- package/dist/clients/web/server.js +450 -0
- package/dist/clients/web/web-cmd.d.ts +2 -0
- package/dist/clients/web/web-cmd.js +120 -0
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/chord.js +4 -25
- package/dist/commands/dashboard.js +5 -1
- package/dist/commands/memory/__tests__/lint-schema.test.js +6 -6
- package/dist/commands/memory/lint.js +14 -2
- package/dist/commands/memory/read.js +2 -2
- package/dist/commands/memory/shared.d.ts +7 -1
- package/dist/commands/memory/shared.js +18 -3
- package/dist/commands/memory/write.js +8 -4
- package/dist/commands/memory.js +4 -4
- package/dist/commands/node.d.ts +1 -1
- package/dist/commands/node.js +64 -65
- package/dist/commands/pkg.js +1 -2
- package/dist/commands/revive.js +11 -3
- package/dist/commands/sys/sync.d.ts +1 -0
- package/dist/commands/sys/sync.js +187 -0
- package/dist/commands/sys.js +3 -2
- package/dist/commands/view-cycle.js +2 -2
- package/dist/commands/view-list.js +8 -8
- package/dist/commands/view-new.js +21 -17
- package/dist/commands/view-pick.js +1 -1
- package/dist/commands/view-run.js +35 -14
- package/dist/commands/view.js +8 -6
- package/dist/commands/workspace.d.ts +2 -0
- package/dist/commands/workspace.js +161 -0
- package/dist/core/__tests__/broker-double-spawn.test.d.ts +1 -0
- package/dist/core/__tests__/broker-double-spawn.test.js +143 -0
- package/dist/core/__tests__/broker-fork-seam.test.d.ts +1 -0
- package/dist/core/__tests__/broker-fork-seam.test.js +102 -0
- package/dist/core/__tests__/broker-sdk-wiring.test.js +2 -0
- package/dist/core/__tests__/child-death-wake.test.js +56 -111
- package/dist/core/__tests__/close.test.js +14 -20
- package/dist/core/__tests__/context-intro.test.js +19 -19
- package/dist/core/__tests__/daemon-boot.test.js +30 -23
- package/dist/core/__tests__/draw-style.test.js +1 -1
- package/dist/core/__tests__/error-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/error-stall-recycle.test.js +141 -0
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +17 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +22 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +25 -13
- package/dist/core/__tests__/fork.test.js +22 -5
- package/dist/core/__tests__/full/broker-control-preempt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-control-preempt.test.js +61 -0
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +57 -0
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +80 -0
- package/dist/core/__tests__/full/broker-pane-resolution.test.js +90 -0
- package/dist/core/__tests__/full/cascade-close.test.js +22 -8
- package/dist/core/__tests__/full/detach-focus.test.js +66 -169
- package/dist/core/__tests__/helpers/harness.d.ts +6 -9
- package/dist/core/__tests__/helpers/harness.js +19 -36
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +1 -0
- package/dist/core/__tests__/human-node-not-supervised.test.js +83 -0
- package/dist/core/__tests__/lifecycle.test.js +1 -19
- package/dist/core/__tests__/listing-completeness.test.js +2 -2
- package/dist/core/__tests__/live-mutation-verbs.test.js +5 -5
- package/dist/core/__tests__/memory-resolver.test.js +1 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -2
- package/dist/core/__tests__/refresh-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/refresh-stall-recycle.test.js +88 -0
- package/dist/core/__tests__/relaunch-root.test.d.ts +1 -0
- package/dist/core/__tests__/relaunch-root.test.js +114 -0
- package/dist/core/__tests__/reset.test.js +19 -79
- package/dist/core/__tests__/steer-note.test.js +9 -7
- package/dist/core/__tests__/tmux-surface.test.js +13 -7
- package/dist/core/bootstrap.d.ts +0 -3
- package/dist/core/bootstrap.js +1 -143
- package/dist/core/canvas/browse/__tests__/model.test.js +86 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +2 -1
- package/dist/core/canvas/browse/app.js +131 -8
- package/dist/core/canvas/browse/model.d.ts +23 -5
- package/dist/core/canvas/browse/model.js +68 -13
- package/dist/core/canvas/browse/render.d.ts +7 -1
- package/dist/core/canvas/browse/render.js +178 -47
- package/dist/core/canvas/canvas.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -4
- package/dist/core/canvas/focuses.js +7 -7
- package/dist/core/canvas/nav-model.js +8 -7
- package/dist/core/canvas/render.d.ts +68 -9
- package/dist/core/canvas/render.js +195 -61
- package/dist/core/canvas/types.d.ts +16 -23
- package/dist/core/config.js +1 -4
- package/dist/core/memory-resolver.js +43 -5
- package/dist/core/runtime/bearings.d.ts +1 -1
- package/dist/core/runtime/bearings.js +8 -8
- package/dist/core/runtime/branded-host.d.ts +16 -0
- package/dist/core/runtime/branded-host.js +127 -0
- package/dist/core/runtime/broker-protocol.d.ts +212 -6
- package/dist/core/runtime/broker.d.ts +4 -1
- package/dist/core/runtime/broker.js +494 -58
- package/dist/core/runtime/close.d.ts +12 -2
- package/dist/core/runtime/close.js +37 -16
- package/dist/core/runtime/front-door.js +6 -14
- package/dist/core/runtime/host.d.ts +14 -34
- package/dist/core/runtime/host.js +14 -50
- package/dist/core/runtime/launch.d.ts +12 -9
- package/dist/core/runtime/launch.js +27 -15
- package/dist/core/runtime/lifecycle.d.ts +1 -1
- package/dist/core/runtime/lifecycle.js +15 -19
- package/dist/core/runtime/nodes.d.ts +0 -55
- package/dist/core/runtime/nodes.js +6 -74
- package/dist/core/runtime/placement.d.ts +91 -335
- package/dist/core/runtime/placement.js +291 -858
- package/dist/core/runtime/promote.d.ts +2 -0
- package/dist/core/runtime/promote.js +24 -6
- package/dist/core/runtime/recap.d.ts +8 -0
- package/dist/core/runtime/recap.js +107 -0
- package/dist/core/runtime/recycle.js +25 -61
- package/dist/core/runtime/reset.d.ts +43 -37
- package/dist/core/runtime/reset.js +131 -218
- package/dist/core/runtime/revive.d.ts +9 -29
- package/dist/core/runtime/revive.js +40 -139
- package/dist/core/runtime/spawn.d.ts +15 -16
- package/dist/core/runtime/spawn.js +165 -194
- package/dist/core/runtime/surface-bg.d.ts +11 -0
- package/dist/core/runtime/surface-bg.js +68 -0
- package/dist/core/runtime/tmux.d.ts +15 -52
- package/dist/core/runtime/tmux.js +35 -99
- package/dist/core/scope.d.ts +1 -2
- package/dist/core/scope.js +1 -5
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.d.ts +1 -0
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.js +57 -0
- package/dist/core/skill-sync/builtins.d.ts +42 -0
- package/dist/core/skill-sync/builtins.js +112 -0
- package/dist/core/skill-sync/claude-plugins.d.ts +23 -0
- package/dist/core/skill-sync/claude-plugins.js +71 -0
- package/dist/core/skill-sync/engine.d.ts +42 -0
- package/dist/core/skill-sync/engine.js +633 -0
- package/dist/core/skill-sync/export.d.ts +23 -0
- package/dist/core/skill-sync/export.js +86 -0
- package/dist/core/skill-sync/manifest.d.ts +64 -0
- package/dist/core/skill-sync/manifest.js +181 -0
- package/dist/core/skill-sync/profile.d.ts +76 -0
- package/dist/core/skill-sync/profile.js +173 -0
- package/dist/core/skill-sync/snapshot.d.ts +57 -0
- package/dist/core/skill-sync/snapshot.js +120 -0
- package/dist/core/substrate/index.d.ts +1 -1
- package/dist/core/substrate/index.js +1 -1
- package/dist/core/substrate/injected-store.js +3 -3
- package/dist/core/substrate/on-read.js +68 -6
- package/dist/core/substrate/render.d.ts +8 -11
- package/dist/core/substrate/render.js +29 -43
- package/dist/core/substrate/schema.d.ts +10 -3
- package/dist/core/substrate/schema.js +6 -3
- package/dist/core/tui/host.d.ts +12 -4
- package/dist/core/tui/host.js +280 -149
- package/dist/core/view/bridge.d.ts +10 -0
- package/dist/core/view/bridge.js +31 -0
- package/dist/core/view/chrome.d.ts +9 -0
- package/dist/core/view/chrome.js +22 -0
- package/dist/core/view/contract.d.ts +171 -0
- package/dist/core/view/contract.js +23 -0
- package/dist/core/view/loader.d.ts +31 -0
- package/dist/core/view/loader.js +188 -0
- package/dist/core/view/transport-local.d.ts +7 -0
- package/dist/core/view/transport-local.js +70 -0
- package/dist/core/view/transport.d.ts +4 -0
- package/dist/core/view/transport.js +15 -0
- package/dist/daemon/crtrd.d.ts +38 -27
- package/dist/daemon/crtrd.js +303 -376
- package/dist/daemon/manage.js +6 -1
- package/dist/index.js +1 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +28 -20
- package/dist/pi-extensions/canvas-context-intro.js +4 -4
- package/dist/pi-extensions/canvas-doc-substrate.js +16 -16
- package/dist/pi-extensions/canvas-nav.js +5 -0
- package/dist/pi-extensions/canvas-recap.d.ts +37 -0
- package/dist/pi-extensions/canvas-recap.js +236 -0
- package/dist/pi-extensions/canvas-resume.js +2 -1
- package/dist/pi-extensions/canvas-stophook.d.ts +14 -12
- package/dist/pi-extensions/canvas-stophook.js +87 -101
- package/dist/pi-extensions/canvas-view.js +2 -1
- package/dist/pi-extensions/widget-order-bus.d.ts +6 -0
- package/dist/pi-extensions/widget-order-bus.js +34 -0
- package/dist/prompts/view.d.ts +2 -2
- package/dist/prompts/view.js +145 -73
- package/dist/types.d.ts +1 -6
- package/dist/types.js +1 -3
- package/dist/web/ViewChrome.d.ts +7 -0
- package/dist/web/ViewChrome.js +28 -0
- package/dist/web/ViewPane.d.ts +39 -0
- package/dist/web/ViewPane.js +48 -0
- package/dist/web/index.d.ts +6 -0
- package/dist/web/index.js +16 -0
- package/dist/web/runtime.d.ts +39 -0
- package/dist/web/runtime.js +133 -0
- package/dist/web/states.d.ts +24 -0
- package/dist/web/states.js +24 -0
- package/dist/web/transport-http.d.ts +5 -0
- package/dist/web/transport-http.js +28 -0
- package/dist/web-client/assets/index-BUvQb4hR.css +2 -0
- package/dist/web-client/assets/index-ClLQXYAE.js +10 -0
- package/dist/web-client/index.html +13 -0
- package/package.json +20 -6
- package/dist/builtin-views/canvas/client.mjs +0 -303
- package/dist/builtin-views/canvas/view.mjs +0 -576
- package/dist/builtin-views/git-pr/client.mjs +0 -440
- package/dist/builtin-views/git-pr/view.mjs +0 -675
- package/dist/builtin-views/inbox/sources/gmail.mjs +0 -965
- package/dist/builtin-views/inbox/sources/linkedin.mjs +0 -427
- package/dist/builtin-views/inbox/view.mjs +0 -889
- package/dist/builtin-views/linkedin/client.mjs +0 -610
- package/dist/builtin-views/linkedin/view.mjs +0 -1171
- package/dist/commands/pkg/bridge.d.ts +0 -1
- package/dist/commands/pkg/bridge.js +0 -137
- package/dist/commands/skill/author.d.ts +0 -3
- package/dist/commands/skill/author.js +0 -140
- package/dist/commands/skill/shared.d.ts +0 -3
- package/dist/commands/skill/shared.js +0 -19
- package/dist/commands/skill.d.ts +0 -2
- package/dist/commands/skill.js +0 -21
- package/dist/commands/tmux-spread.d.ts +0 -2
- package/dist/commands/tmux-spread.js +0 -144
- package/dist/core/__tests__/full/daemon-liveness-pane.full.test.js +0 -292
- package/dist/core/__tests__/full/placement-focus.test.js +0 -309
- package/dist/core/__tests__/full/placement-reconcile.test.js +0 -212
- package/dist/core/__tests__/full/placement-revive.test.js +0 -238
- package/dist/core/__tests__/full/placement-teardown.test.js +0 -297
- package/dist/core/__tests__/home-session.test.js +0 -186
- package/dist/core/__tests__/relaunch.test.js +0 -335
- package/dist/core/bridge-map.d.ts +0 -19
- package/dist/core/bridge-map.js +0 -73
- package/dist/core/tui/contract.d.ts +0 -83
- package/dist/core/tui/contract.js +0 -8
- package/dist/core/tui/loader.d.ts +0 -16
- package/dist/core/tui/loader.js +0 -94
- package/dist/prompts/skill.d.ts +0 -2
- package/dist/prompts/skill.js +0 -650
- /package/dist/{core/__tests__/full/daemon-liveness-pane.full.test.d.ts → clients/attach/__tests__/action-parity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-focus.test.d.ts → clients/attach/__tests__/clipboard-image.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-reconcile.test.d.ts → clients/attach/__tests__/editor-newline.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-revive.test.d.ts → clients/attach/__tests__/git-info.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-teardown.test.d.ts → clients/attach/__tests__/onrequest-wired.test.d.ts} +0 -0
- /package/dist/{core/__tests__/home-session.test.d.ts → clients/attach/__tests__/slash-quit-copy.test.d.ts} +0 -0
- /package/dist/{core/__tests__/relaunch.test.d.ts → clients/attach/__tests__/titled-editor.test.d.ts} +0 -0
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
// The revive primitive — restores a node to active status
|
|
2
|
-
//
|
|
3
|
-
// the explicit `crtr canvas revive` command.
|
|
1
|
+
// The revive primitive — restores a node to active status by relaunching its
|
|
2
|
+
// broker engine. Used by both the supervisor daemon (on crash/refresh
|
|
3
|
+
// detection) and the explicit `crtr canvas revive` command.
|
|
4
4
|
//
|
|
5
5
|
// A revive replays the node's persisted LaunchSpec + cwd (the canonical recipe)
|
|
6
|
-
// and
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// unbidden window in the user's session.
|
|
6
|
+
// and launches the headless broker host (the only host after the
|
|
7
|
+
// broker-is-the-host cut). It opens NO viewer — it relaunches the engine only;
|
|
8
|
+
// existing viewer panes reconnect to the fresh broker on their own (attach
|
|
9
|
+
// auto-reconnect), and a node with no viewer is brought on screen by the next
|
|
10
|
+
// `focus`.
|
|
12
11
|
//
|
|
13
12
|
// resume=true → `pi --session <path|id>` — wakes the saved conversation,
|
|
14
13
|
// preferring the absolute session-file path (cwd-immune) over
|
|
15
14
|
// the bare session id.
|
|
16
15
|
// resume=false → fresh pi invocation — the node re-reads its roadmap/context dir.
|
|
17
|
-
|
|
16
|
+
//
|
|
17
|
+
// reviveNode remains the ONLY sanctioned launcher of the node engine.
|
|
18
|
+
import { getNode, updateNode, clearPid, fullName, cancelDeadlinesFor, } from '../canvas/index.js';
|
|
18
19
|
import { transition } from './lifecycle.js';
|
|
19
20
|
import { buildPiArgv } from './launch.js';
|
|
20
21
|
import { buildReviveKickoff, drainBearings } from './kickoff.js';
|
|
21
|
-
import {
|
|
22
|
-
import { reconcile, piCommand, respawnPane, } from './placement.js';
|
|
23
|
-
import { hostFor } from './host.js';
|
|
24
|
-
import { nodeSession, childBackstageOf, rootOfSpine } from './nodes.js';
|
|
22
|
+
import { headlessBrokerHost } from './host.js';
|
|
25
23
|
import { isPidAlive } from '../canvas/pid.js';
|
|
26
24
|
import { clearInjectedDocs } from '../substrate/injected-store.js';
|
|
27
25
|
// ---------------------------------------------------------------------------
|
|
@@ -44,29 +42,33 @@ export function resumeArgs(meta, resume) {
|
|
|
44
42
|
// ---------------------------------------------------------------------------
|
|
45
43
|
// reviveNode
|
|
46
44
|
// ---------------------------------------------------------------------------
|
|
47
|
-
/**
|
|
45
|
+
/** Relaunch `nodeId`'s broker engine from its persisted recipe and update canvas
|
|
46
|
+
* meta. Opens no viewer (engine-only).
|
|
48
47
|
*
|
|
49
|
-
* Throws if the node does not exist. All other failures
|
|
50
|
-
*
|
|
48
|
+
* Throws if the node does not exist. All other failures propagate as-is —
|
|
49
|
+
* callers (daemon, command) decide how to handle.
|
|
51
50
|
*/
|
|
52
51
|
export function reviveNode(nodeId, opts) {
|
|
53
52
|
const meta = getNode(nodeId);
|
|
54
53
|
if (meta === null) {
|
|
55
54
|
throw new Error(`reviveNode: unknown node ${nodeId}`);
|
|
56
55
|
}
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
// Lazy host_kind coerce (§C): a pre-cut row carries host_kind null or 'tmux'.
|
|
57
|
+
// Every launcher now uses the broker host regardless, loading the same
|
|
58
|
+
// host-agnostic session.jsonl; persist 'broker' so inspect/history read honest
|
|
59
|
+
// values and the daemon never branches it back. Mutate the in-memory meta too.
|
|
60
|
+
if (meta.host_kind !== 'broker') {
|
|
61
|
+
updateNode(nodeId, { host_kind: 'broker' });
|
|
62
|
+
meta.host_kind = 'broker';
|
|
63
|
+
}
|
|
64
|
+
// Double-revive guard: the broker's isAlive IS isPidAlive(pi_pid), so a node
|
|
65
|
+
// whose broker pid is still running was already revived by another path —
|
|
66
|
+
// re-launching would put a SECOND broker on the same session file. No-op.
|
|
65
67
|
const live = getNode(nodeId) ?? meta;
|
|
66
|
-
if (
|
|
68
|
+
if (isPidAlive(live.pi_pid)) {
|
|
67
69
|
return {
|
|
68
|
-
window:
|
|
69
|
-
session: live.tmux_session ??
|
|
70
|
+
window: null,
|
|
71
|
+
session: live.tmux_session ?? null,
|
|
70
72
|
resumed: false,
|
|
71
73
|
};
|
|
72
74
|
}
|
|
@@ -99,125 +101,24 @@ export function reviveNode(nodeId, opts) {
|
|
|
99
101
|
// would instead KEEP the persisted set, continuing the same transcript).
|
|
100
102
|
clearInjectedDocs(nodeId);
|
|
101
103
|
}
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
// around it (the crash-safety ordering, unchanged). THIS is the bug-kill: a
|
|
107
|
-
// non-focused background revive can no longer new-window into a user session.
|
|
104
|
+
// The broker host launches the detached engine. reviveNode keeps
|
|
105
|
+
// transition+clearPid around it (the crash-safety ordering, unchanged). It
|
|
106
|
+
// opens NO viewer — engine-only; existing viewers reconnect, and a viewer-less
|
|
107
|
+
// node is brought on screen by the next `focus`.
|
|
108
108
|
transition(nodeId, 'revive');
|
|
109
109
|
// Cancel-on-wake (design §6.4, AC-E1): every revive-for-any-reason (an inbox
|
|
110
110
|
// event, a different wake, a manual focus) drops this node's pending deadline,
|
|
111
111
|
// so the deadline always belongs to the dormancy being left. Writes only the
|
|
112
|
-
// wakeups table, after the atomic transition above.
|
|
113
|
-
// transition('boot') needs NO hook — a refresh is the same node continuing,
|
|
114
|
-
// not leaving a dormancy.)
|
|
112
|
+
// wakeups table, after the atomic transition above.
|
|
115
113
|
cancelDeadlinesFor(nodeId);
|
|
116
|
-
|
|
114
|
+
headlessBrokerHost.launch(nodeId, inv, {
|
|
117
115
|
cwd: meta.cwd,
|
|
118
116
|
name: fullName(meta),
|
|
119
117
|
resuming,
|
|
120
118
|
});
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
// pass reaps it.
|
|
119
|
+
// Clear the stale pid so the daemon won't re-fire on it during the new
|
|
120
|
+
// broker's boot. The fresh broker re-records its pid during extension bind; if
|
|
121
|
+
// it never boots, the daemon's boot-grace + surfaceBootFailure own that case.
|
|
125
122
|
clearPid(nodeId);
|
|
126
|
-
return { window:
|
|
127
|
-
}
|
|
128
|
-
// ---------------------------------------------------------------------------
|
|
129
|
-
// reviveInPlace — refresh-yield without churning the window
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
|
-
/** Re-exec a node's pi FRESH in its EXISTING tmux pane (the refresh-yield
|
|
132
|
-
* path). Unlike `reviveNode`, this opens no new window: the pane's current pi
|
|
133
|
-
* is replaced in place via `respawn-pane -k`, so a foreground/interactive
|
|
134
|
-
* session keeps its terminal and a background node keeps its window. Always
|
|
135
|
-
* fresh (no resume) — the node re-reads its roadmap/context dir.
|
|
136
|
-
*
|
|
137
|
-
* `pane` is the target pane id (the yielding node reads it from $TMUX_PANE).
|
|
138
|
-
* Throws on unknown node or when the respawn could not be dispatched, so the
|
|
139
|
-
* caller can fall back to a plain shutdown (daemon revives in a new window). */
|
|
140
|
-
export function reviveInPlace(nodeId, pane, respawn = respawnPane) {
|
|
141
|
-
const meta = getNode(nodeId);
|
|
142
|
-
if (meta === null) {
|
|
143
|
-
throw new Error(`reviveInPlace: unknown node ${nodeId}`);
|
|
144
|
-
}
|
|
145
|
-
// A refresh-yield is a cycle too — advance the label's trailing N.
|
|
146
|
-
meta.cycles = (meta.cycles ?? 0) + 1;
|
|
147
|
-
updateNode(nodeId, { cycles: meta.cycles });
|
|
148
|
-
// Fresh re-exec → new transcript: reset the on-read doc dedup.
|
|
149
|
-
clearInjectedDocs(nodeId);
|
|
150
|
-
// The node's LOCATION — the session its pane physically lives in. The re-exec
|
|
151
|
-
// is IN PLACE (the pane never moves), so this is preserved unchanged below.
|
|
152
|
-
const session = meta.tmux_session ?? nodeSession();
|
|
153
|
-
// Fresh re-exec: same recipe as a no-resume reviveNode, with the kickoff so
|
|
154
|
-
// the node rebuilds its bearings from disk. Drain the one-shot bearings first,
|
|
155
|
-
// then build purely.
|
|
156
|
-
const bearings = drainBearings(meta);
|
|
157
|
-
const inv = buildPiArgv(meta, { prompt: buildReviveKickoff(meta, bearings) });
|
|
158
|
-
// CRTR_ROOT_SESSION is the backstage this node's CHILDREN spawn into — NOT the
|
|
159
|
-
// pane's live `session`. A FOCUSED child's pane is in a USER session (focus
|
|
160
|
-
// taints meta.tmux_session), so sourcing it from `session` would land any
|
|
161
|
-
// child it spawns in the user's session, re-tainting that child's
|
|
162
|
-
// home_session (A-MAJOR-1). childBackstageOf is the taint-immune backstage:
|
|
163
|
-
// home_session for a managed child, but `nodeSession()` for a ROOT (whose
|
|
164
|
-
// home_session may itself be a user session it adopted via the inline front
|
|
165
|
-
// door — sourcing children from it would re-point the root's whole subtree
|
|
166
|
-
// into the user's session on every refresh-yield).
|
|
167
|
-
const env = { ...inv.env, CRTR_ROOT_SESSION: childBackstageOf(nodeId), CRTR_SUBTREE: rootOfSpine(nodeId) };
|
|
168
|
-
const ok = respawn({ pane, cwd: meta.cwd, env, command: piCommand(inv.argv) });
|
|
169
|
-
if (!ok) {
|
|
170
|
-
throw new Error(`reviveInPlace: respawn-pane dispatch failed for ${nodeId}`);
|
|
171
|
-
}
|
|
172
|
-
// Deliberately DO NOT clear intent here, and DO NOT touch pi_pid. The detached
|
|
173
|
-
// respawn-pane can't confirm it actually replaced the pi (it kills this very
|
|
174
|
-
// process mid-flight), so clearing intent optimistically is how a failed
|
|
175
|
-
// refresh became a silent death: the fresh pi never boots, yet meta says the
|
|
176
|
-
// refresh completed. Instead we leave intent='refresh' (the fresh pi clears it
|
|
177
|
-
// on boot — the only proof the respawn worked) and leave pi_pid as the OLD
|
|
178
|
-
// pid. If the respawn succeeds, the old pi dies and the fresh one overwrites
|
|
179
|
-
// pid+intent within the daemon's grace window; if it fails, the old pid stays
|
|
180
|
-
// dead and the daemon's pi-liveness pass revives the node.
|
|
181
|
-
transition(nodeId, 'boot');
|
|
182
|
-
// tmux_session may have resolved to the shared session; window is unchanged
|
|
183
|
-
// (we re-execed in place), so preserve it explicitly.
|
|
184
|
-
setPresence(nodeId, { tmux_session: session, window: meta.window ?? null });
|
|
185
|
-
// Window is unchanged (we re-execed in place); report the existing one.
|
|
186
|
-
return { window: meta.window ?? null, session, resumed: false };
|
|
187
|
-
}
|
|
188
|
-
// ---------------------------------------------------------------------------
|
|
189
|
-
// relaunchRootInPane — boot a CLEAN fresh root in the current pane (option C)
|
|
190
|
-
// ---------------------------------------------------------------------------
|
|
191
|
-
/** Re-exec a FRESH pi for `nodeId` in EXISTING `pane` (respawn-pane -k), with
|
|
192
|
-
* NO prompt and NO resume — a clean root conversation (goal-capture /
|
|
193
|
-
* context-intro handle the first message + bearings, exactly like bare
|
|
194
|
-
* `crtr`). Unlike reviveInPlace: no buildReviveKickoff prompt, no cycles bump,
|
|
195
|
-
* and it sets CRTR_FRONT_DOOR=1 (REQUIRED — src/core/runtime/CLAUDE.md: any
|
|
196
|
-
* path that boots a pi must guard against a removed/renamed subcommand
|
|
197
|
-
* fork-bombing). Throws if the respawn could not be dispatched.
|
|
198
|
-
*
|
|
199
|
-
* Used by relaunchRoot (reset.ts) for the `/new`-in-a-root relaunch. Kept
|
|
200
|
-
* SEPARATE from reviveInPlace so the refresh-yield path's exact semantics
|
|
201
|
-
* (kickoff + cycle bump) are untouched. */
|
|
202
|
-
export function relaunchRootInPane(nodeId, pane) {
|
|
203
|
-
const meta = getNode(nodeId);
|
|
204
|
-
if (meta === null) {
|
|
205
|
-
throw new Error(`relaunchRootInPane: unknown node ${nodeId}`);
|
|
206
|
-
}
|
|
207
|
-
// No prompt, no resume → a brand-new root conversation at cycle 0.
|
|
208
|
-
// Brand-new transcript: reset the on-read doc dedup.
|
|
209
|
-
clearInjectedDocs(nodeId);
|
|
210
|
-
const inv = buildPiArgv(meta, {});
|
|
211
|
-
// Source CRTR_ROOT_SESSION from childBackstageOf, the same backstage rule as
|
|
212
|
-
// reviveInPlace. relaunchRootInPane runs only on a root, whose children must
|
|
213
|
-
// flow to the shared backstage `nodeSession()` — never the root's own adopted
|
|
214
|
-
// user session — so both in-pane revive paths stay sourced identically.
|
|
215
|
-
const env = { ...inv.env, CRTR_ROOT_SESSION: childBackstageOf(nodeId), CRTR_SUBTREE: rootOfSpine(nodeId), [FRONT_DOOR_ENV]: '1' };
|
|
216
|
-
const ok = respawnPane({ pane, cwd: meta.cwd, env, command: piCommand(inv.argv) });
|
|
217
|
-
if (!ok) {
|
|
218
|
-
throw new Error(`relaunchRootInPane: respawn-pane dispatch failed for ${nodeId}`);
|
|
219
|
-
}
|
|
220
|
-
// Do NOT clear intent/pi_pid here — the fresh pi clears intent='refresh' on
|
|
221
|
-
// its session_start boot (the only proof the respawn worked), same dance as
|
|
222
|
-
// reviveInPlace.
|
|
123
|
+
return { window: null, session: meta.tmux_session ?? null, resumed: resuming };
|
|
223
124
|
}
|
|
@@ -6,14 +6,11 @@ export interface BootRootOpts {
|
|
|
6
6
|
name?: string;
|
|
7
7
|
/** Optional starter prompt (bare `crtr` requires none). */
|
|
8
8
|
prompt?: string;
|
|
9
|
-
/** Tri-state host selection: `true`/`false` from an explicit
|
|
10
|
-
* `--headless`/`--no-headless`, `undefined` to defer to the `headless`
|
|
11
|
-
* config default. When it resolves to broker, the front door boots a
|
|
12
|
-
* DETACHED broker root and auto-attaches a viewer inline in this pane. */
|
|
13
|
-
headless?: boolean;
|
|
14
9
|
}
|
|
15
|
-
/** Create
|
|
16
|
-
*
|
|
10
|
+
/** Create the front-door root: launch its broker engine, then exec `crtr attach`
|
|
11
|
+
* inline so THIS terminal becomes the broker's controller-viewer. Does not
|
|
12
|
+
* return — it process.exit()s when the inline attach exits (detach leaves the
|
|
13
|
+
* resident broker running, to be reconnected later). */
|
|
17
14
|
export declare function bootRoot(opts: BootRootOpts): NodeMeta;
|
|
18
15
|
export interface SpawnChildOpts {
|
|
19
16
|
kind: string;
|
|
@@ -40,24 +37,26 @@ export interface SpawnChildOpts {
|
|
|
40
37
|
* a <crtr-wake> block is prepended to the kickoff so the newborn knows a clock
|
|
41
38
|
* birthed it. */
|
|
42
39
|
wakeOrigin?: WakeOrigin;
|
|
43
|
-
/** Which HOST launches + supervises this node: a tmux pane (default) or the
|
|
44
|
-
* headless broker. Persisted as `host_kind` at birth (resolved from
|
|
45
|
-
* `--headless` / the `headless` config default by the caller). */
|
|
46
|
-
hostKind?: 'tmux' | 'broker';
|
|
47
40
|
/** Pin the node to a model TIER (ultra/strong/medium/light), overriding the
|
|
48
41
|
* persona's declared default. Persisted to `meta.model_override` so it
|
|
49
42
|
* survives polymorphs. Omit to use the persona default. */
|
|
50
43
|
model?: string;
|
|
51
44
|
}
|
|
52
|
-
/** Resolve a `--fork-from` value to
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
45
|
+
/** Resolve a `--fork-from` value to an ABSOLUTE `.jsonl` source path for the
|
|
46
|
+
* broker fork (`SessionManager.forkFrom`, which loads a file — never a bare id).
|
|
47
|
+
* A live node id resolves to its captured session FILE (absolute, cwd-immune); a
|
|
48
|
+
* relative path is made absolute; a bare/partial uuid is resolved against pi's
|
|
49
|
+
* sessions store. Throws when a known node has no captured session file, or when
|
|
50
|
+
* a uuid resolves to zero or multiple sessions. */
|
|
56
51
|
export declare function resolveForkSource(value: string): string;
|
|
57
52
|
export interface SpawnChildResult {
|
|
58
53
|
node: NodeMeta;
|
|
54
|
+
/** The viewer window opened for a --root in tmux; null otherwise (a managed
|
|
55
|
+
* child opens no viewer, and a --root spawned outside tmux opens none). */
|
|
59
56
|
window: string | null;
|
|
60
|
-
session
|
|
57
|
+
/** The session the --root's viewer opened into (the caller's current session);
|
|
58
|
+
* null when no viewer was opened. */
|
|
59
|
+
session: string | null;
|
|
61
60
|
}
|
|
62
61
|
/** Resolve who a spawn is attributed to. A managed child needs a spine parent
|
|
63
62
|
* (explicit `--parent` or the calling node's CRTR_NODE_ID). A --root spawn
|