@crouton-kit/crouter 0.3.27 → 0.3.29
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.js +4 -2
- 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 +8 -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 +3 -3
- 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__/reconnect-giveup.test.js +30 -0
- package/dist/clients/attach/__tests__/slash-quit-copy.test.js +42 -0
- package/dist/clients/attach/__tests__/titled-editor.test.d.ts +1 -0
- package/dist/clients/attach/__tests__/titled-editor.test.js +39 -0
- package/dist/clients/attach/attach-cmd.js +445 -41
- 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 +12 -0
- package/dist/clients/attach/canvas-panels.js +78 -0
- 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 +43 -0
- package/dist/clients/attach/graph-overlay.js +306 -0
- package/dist/clients/attach/input-controller.d.ts +81 -13
- package/dist/clients/attach/input-controller.js +307 -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 +44 -1
- package/dist/clients/attach/slash-commands.js +250 -27
- 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 +37 -2
- package/dist/clients/attach/view-socket.js +131 -7
- 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 +1 -1
- package/dist/commands/dashboard.js +5 -1
- package/dist/commands/human/prompts.js +3 -3
- package/dist/commands/human/queue.d.ts +17 -0
- package/dist/commands/human/queue.js +111 -4
- package/dist/commands/memory/__tests__/lint-schema.test.js +27 -4
- package/dist/commands/memory/lint.d.ts +5 -4
- package/dist/commands/memory/lint.js +23 -7
- 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 +20 -7
- 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/feedback.d.ts +1 -0
- package/dist/commands/sys/feedback.js +163 -0
- package/dist/commands/sys/sync.d.ts +1 -0
- package/dist/commands/sys/sync.js +187 -0
- package/dist/commands/sys.js +4 -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__/broker-snapshot-history.test.d.ts +1 -0
- package/dist/core/__tests__/broker-snapshot-history.test.js +105 -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 +24 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +32 -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__/human-stranded-deliver.test.d.ts +1 -0
- package/dist/core/__tests__/human-stranded-deliver.test.js +108 -0
- package/dist/core/__tests__/lifecycle.test.js +1 -19
- 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.d.ts +1 -0
- package/dist/core/__tests__/on-read-dedup-resume.test.js +81 -0
- 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.d.ts +162 -0
- package/dist/core/canvas/nav-model.js +487 -0
- package/dist/core/canvas/paths.d.ts +7 -0
- package/dist/core/canvas/paths.js +9 -0
- 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-sdk.d.ts +0 -12
- package/dist/core/runtime/broker-sdk.js +77 -6
- package/dist/core/runtime/broker.d.ts +5 -1
- package/dist/core/runtime/broker.js +520 -59
- package/dist/core/runtime/close.d.ts +12 -2
- package/dist/core/runtime/close.js +37 -16
- package/dist/core/runtime/front-door.js +14 -7
- 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 -334
- package/dist/core/runtime/placement.js +262 -828
- 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 +45 -135
- package/dist/core/runtime/spawn.d.ts +15 -11
- package/dist/core/runtime/spawn.js +168 -136
- 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 -43
- package/dist/core/runtime/tmux.js +38 -80
- 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/spawn.d.ts +14 -0
- package/dist/core/spawn.js +29 -9
- package/dist/core/substrate/index.d.ts +2 -2
- package/dist/core/substrate/index.js +7 -7
- package/dist/core/substrate/injected-store.d.ts +10 -0
- package/dist/core/substrate/injected-store.js +55 -0
- 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 +16 -11
- package/dist/core/substrate/schema.js +32 -31
- 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 +29 -20
- package/dist/pi-extensions/canvas-nav.js +35 -385
- 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 +15 -13
- package/dist/pi-extensions/canvas-stophook.js +119 -103
- 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 -221
- 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__/reconnect-giveup.test.d.ts} +0 -0
- /package/dist/{core/__tests__/relaunch.test.d.ts → clients/attach/__tests__/slash-quit-copy.test.d.ts} +0 -0
|
@@ -1,33 +1,31 @@
|
|
|
1
|
-
//
|
|
1
|
+
// `/new` handling — root relaunch + child session-id refresh — plus clean-exit
|
|
2
|
+
// termination.
|
|
2
3
|
//
|
|
3
|
-
// A
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// behave like re-running `crtr` we have two strategies:
|
|
4
|
+
// A node's engine is a detached broker process bound to one CRTR_NODE_ID, and
|
|
5
|
+
// its on-screen viewer is a SEPARATE `crtr attach` pane. `/new` splits by who
|
|
6
|
+
// ran it:
|
|
7
7
|
//
|
|
8
|
-
// • relaunchRoot
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// The
|
|
12
|
-
//
|
|
13
|
-
//
|
|
8
|
+
// • relaunchRoot — a `/new` on a ROOT starts a genuinely new node: the old
|
|
9
|
+
// root is parked `done` (kept as history), a fresh node id + broker is
|
|
10
|
+
// minted in the same pane/cwd, and the viewer pane is re-pointed at the new
|
|
11
|
+
// broker. The new broker is booted FIRST, so any failure before the commit
|
|
12
|
+
// point leaves the old root fully intact.
|
|
13
|
+
// • resetRoot — a `/new` on a non-root child refreshes its session id only, so
|
|
14
|
+
// a later `--session <id>` wakes the right conversation.
|
|
14
15
|
//
|
|
15
16
|
// Termination semantics: a pi that ends cleanly resolves its node to `done`
|
|
16
|
-
// (markCleanExitDone); only a true crash leaves it `dead`. A force-kill
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
17
|
+
// (markCleanExitDone); only a true crash leaves it `dead`. A force-kill fires NO
|
|
18
|
+
// clean session_shutdown, so reaped descendants are marked `canceled` explicitly
|
|
19
|
+
// here (A5: an externally-reaped node did not finish its own work — done is
|
|
20
|
+
// reserved for finalize).
|
|
20
21
|
//
|
|
21
|
-
// Best-effort throughout: a tmux/fs failure on one node never aborts the
|
|
22
|
-
import {
|
|
23
|
-
import { getNode, updateNode, setPresence, clearPid, setFocusOccupant, subscriptionsOf, unsubscribe, view, reportsDir, inboxPath, nodeDir, openDb, } from '../canvas/index.js';
|
|
22
|
+
// Best-effort throughout: a tmux/fs failure on one node never aborts the reap.
|
|
23
|
+
import { getNode, updateNode, fullName, closeFocusRow, view, } from '../canvas/index.js';
|
|
24
24
|
import { transition } from './lifecycle.js';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { buildLaunchSpec } from './launch.js';
|
|
28
|
-
import {
|
|
29
|
-
import { spawnNode, newNodeId, nodeSession } from './nodes.js';
|
|
30
|
-
import { relaunchRootInPane } from './revive.js';
|
|
25
|
+
import { headlessBrokerHost } from './host.js';
|
|
26
|
+
import { tearDownNode, focusOf, registerViewerFocus, respawnPaneSync, viewerSplitEnv, windowOfPane, renameWindow, waitForBrokerViewSocket, } from './placement.js';
|
|
27
|
+
import { buildLaunchSpec, buildPiArgv } from './launch.js';
|
|
28
|
+
import { spawnNode, rootOfSpine } from './nodes.js';
|
|
31
29
|
// ---------------------------------------------------------------------------
|
|
32
30
|
// reapDescendants — tear down a root's descendant sub-DAG (shared helper)
|
|
33
31
|
// ---------------------------------------------------------------------------
|
|
@@ -37,25 +35,25 @@ import { relaunchRootInPane } from './revive.js';
|
|
|
37
35
|
* keep parent=rootId. No wipe. Returns the reaped ids.
|
|
38
36
|
*
|
|
39
37
|
* Why `canceled` (A5, human-confirmed 2026-06-06): an externally-reaped node —
|
|
40
|
-
* whether via `node close` OR a root reset
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* same `cancel` event the close cascade uses. Shared by relaunchRoot (option C)
|
|
46
|
-
* and resetRoot's in-place fallback, so both leave their descendants `canceled`. */
|
|
38
|
+
* whether via `node close` OR a root reset — did not finish its OWN work, so it
|
|
39
|
+
* unifies on `canceled`; `done` is reserved for finalize. Why marking is STILL
|
|
40
|
+
* explicit: an abrupt broker teardown fires NO clean `session_shutdown`, so the
|
|
41
|
+
* general quit→done rule does NOT auto-resolve a force-killed descendant — we
|
|
42
|
+
* mark it `canceled` here via the same `cancel` event the close cascade uses. */
|
|
47
43
|
export function reapDescendants(rootId) {
|
|
48
44
|
const reaped = [];
|
|
49
45
|
for (const id of view(rootId)) {
|
|
50
46
|
try {
|
|
51
|
-
// Reap BEFORE tearing down the
|
|
52
|
-
// `cancel` event encodes): a non-supervised status + cleared intent first,
|
|
53
|
-
// the daemon can't revive a descendant mid-teardown. Teardown then
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
// Reap BEFORE tearing down the engine (the crash-safety invariant the
|
|
48
|
+
// `cancel` event encodes): a non-supervised status + cleared intent first,
|
|
49
|
+
// so the daemon can't revive a descendant mid-teardown. Teardown then sends
|
|
50
|
+
// the broker the `shutdown` frame so its PROCESS exits and releases the
|
|
51
|
+
// sole .jsonl writer; tearDownNode then proactively closes the on-screen
|
|
52
|
+
// viewer pane + registry row (attach auto-reconnects, so the viewer must be
|
|
53
|
+
// closed here or it lingers ~30s in a misleading "reconnecting…" state).
|
|
54
|
+
transition(id, 'cancel');
|
|
55
|
+
headlessBrokerHost.teardown(id);
|
|
56
|
+
tearDownNode(id);
|
|
59
57
|
reaped.push(id);
|
|
60
58
|
}
|
|
61
59
|
catch {
|
|
@@ -64,194 +62,109 @@ export function reapDescendants(rootId) {
|
|
|
64
62
|
}
|
|
65
63
|
return reaped;
|
|
66
64
|
}
|
|
67
|
-
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// 3) Wipe the root's working state (reports / inbox / roadmap).
|
|
95
|
-
for (const p of [
|
|
96
|
-
reportsDir(nodeId),
|
|
97
|
-
inboxPath(nodeId),
|
|
98
|
-
`${inboxPath(nodeId)}.cursor`,
|
|
99
|
-
roadmapPath(nodeId),
|
|
100
|
-
]) {
|
|
101
|
-
try {
|
|
102
|
-
if (existsSync(p))
|
|
103
|
-
rmSync(p, { recursive: true, force: true });
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
/* */
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
// 4) Re-point the root at a fresh base persona + the new pi session id. A
|
|
110
|
-
// root is resident by definition (this only runs on roots — see the early
|
|
111
|
-
// return above), so resetting to base/resident is the model, not a bypass.
|
|
112
|
-
// Re-seed persona_ack to the fresh persona so the pristine `/new`
|
|
113
|
-
// conversation never gets a spurious mode/lifecycle transition steer (the
|
|
114
|
-
// persona injector compares against this ack).
|
|
115
|
-
const { launch } = buildLaunchSpec(meta.kind, 'base', { lifecycle: 'resident', hasManager: false, model: meta.model_override ?? undefined });
|
|
116
|
-
updateNode(nodeId, {
|
|
65
|
+
/** Relaunch a ROOT on `/new`: park the old root `done` (kept as history) and
|
|
66
|
+
* mint a fresh node id + broker in the same pane/cwd, re-pointing the viewer at
|
|
67
|
+
* it. The new broker is booted FIRST and its pid confirmed BEFORE the old root
|
|
68
|
+
* is touched, so any pre-commit failure leaves the old root fully intact and
|
|
69
|
+
* live. Returns null when `oldId` is not a relaunchable root (unknown, a child,
|
|
70
|
+
* or already parked), or when the new broker failed to launch. */
|
|
71
|
+
export function relaunchRoot(oldId, deps = {}) {
|
|
72
|
+
const launchBroker = deps.launchBroker ?? headlessBrokerHost.launch;
|
|
73
|
+
const waitForViewSocket = deps.waitForViewSocket ?? waitForBrokerViewSocket;
|
|
74
|
+
const respawnViewer = deps.respawnViewer ?? respawnPaneSync;
|
|
75
|
+
const teardownBroker = deps.teardownBroker ?? headlessBrokerHost.teardown;
|
|
76
|
+
const old = getNode(oldId);
|
|
77
|
+
if (old === null || old.parent != null)
|
|
78
|
+
return null; // roots only
|
|
79
|
+
if (old.status === 'done')
|
|
80
|
+
return null; // defensive: a double `/new`
|
|
81
|
+
const oldFocus = focusOf(oldId); // capture the viewer BEFORE any teardown
|
|
82
|
+
// --- mint + boot the NEW broker FIRST (a failure here leaves the old root
|
|
83
|
+
// untouched) ---
|
|
84
|
+
// A relaunched root is a fresh resident base, exactly like the front door.
|
|
85
|
+
const { launch } = buildLaunchSpec(old.kind, 'base', {
|
|
86
|
+
lifecycle: 'resident',
|
|
87
|
+
hasManager: false,
|
|
88
|
+
model: old.model_override ?? undefined,
|
|
89
|
+
});
|
|
90
|
+
const newMeta = spawnNode({
|
|
91
|
+
kind: old.kind,
|
|
117
92
|
mode: 'base',
|
|
118
93
|
lifecycle: 'resident',
|
|
119
|
-
|
|
94
|
+
cwd: old.cwd,
|
|
95
|
+
name: old.kind,
|
|
96
|
+
parent: null,
|
|
120
97
|
launch,
|
|
121
|
-
|
|
122
|
-
...(newSessionFile !== undefined ? { pi_session_file: newSessionFile } : {}),
|
|
98
|
+
modelOverride: old.model_override ?? undefined,
|
|
123
99
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return { path: 'reset-child' };
|
|
142
|
-
}
|
|
143
|
-
// Root with no pane (not inside tmux): in-place reset fallback. Option C needs
|
|
144
|
-
// a pane to respawn into; resetRoot needs the new session id (available here
|
|
145
|
-
// because the trigger is session_start).
|
|
146
|
-
if (pane === undefined || pane.trim() === '') {
|
|
147
|
-
resetRoot(nodeId, newSessionId, newSessionFile);
|
|
148
|
-
return { path: 'reset-root' };
|
|
149
|
-
}
|
|
150
|
-
// Root with a pane: option C relaunch. relaunchRoot self-rolls-back its DB
|
|
151
|
-
// writes on a respawn-dispatch failure and rethrows; we then degrade to the
|
|
152
|
-
// legacy in-place reset (the live pi is still alive, never killed).
|
|
153
|
-
try {
|
|
154
|
-
const result = relaunchRoot(nodeId, pane, deps);
|
|
155
|
-
if (result === null)
|
|
156
|
-
return { path: 'noop' }; // defensive guard hit (e.g. rapid double /new)
|
|
157
|
-
return { path: 'relaunch', newNodeId: result.newNodeId };
|
|
100
|
+
const inv = buildPiArgv(newMeta, {});
|
|
101
|
+
// Mirror bootRoot's subtree routing on inv.env (the broker host merges it; it
|
|
102
|
+
// sets CRTR_FRONT_DOOR itself).
|
|
103
|
+
inv.env = {
|
|
104
|
+
...inv.env,
|
|
105
|
+
CRTR_SUBTREE: rootOfSpine(newMeta.node_id),
|
|
106
|
+
};
|
|
107
|
+
const placed = launchBroker(newMeta.node_id, inv, {
|
|
108
|
+
cwd: old.cwd,
|
|
109
|
+
name: fullName(newMeta),
|
|
110
|
+
resuming: false,
|
|
111
|
+
});
|
|
112
|
+
if (placed.pid == null) {
|
|
113
|
+
// The new broker never started — crash the half-born node and BAIL. The old
|
|
114
|
+
// root is still live and untouched (nothing below this point has run).
|
|
115
|
+
transition(newMeta.node_id, 'crash');
|
|
116
|
+
return null;
|
|
158
117
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
118
|
+
waitForViewSocket(newMeta.node_id); // best-effort; attach auto-redials on miss
|
|
119
|
+
// --- COMMIT: park + reap the old root, re-point the viewer, kill the old
|
|
120
|
+
// broker. Past this point the new node is the live root. ---
|
|
121
|
+
reapDescendants(oldId); // old workers → canceled + torn down
|
|
122
|
+
// Park the old root DONE (kept as history; NOT canceled — a relaunched root
|
|
123
|
+
// finished cleanly, the user just started fresh). Its reports/inbox/roadmap
|
|
124
|
+
// are left on disk as the record of that session.
|
|
125
|
+
transition(oldId, 'finalize');
|
|
126
|
+
if (oldFocus?.pane != null) {
|
|
127
|
+
closeFocusRow(oldFocus.focus_id);
|
|
128
|
+
respawnViewer({
|
|
129
|
+
pane: oldFocus.pane,
|
|
130
|
+
cwd: old.cwd,
|
|
131
|
+
env: viewerSplitEnv(),
|
|
132
|
+
command: `crtr attach to ${newMeta.node_id}`,
|
|
133
|
+
});
|
|
134
|
+
const window = windowOfPane(oldFocus.pane);
|
|
135
|
+
if (window !== null)
|
|
136
|
+
renameWindow(window, fullName(newMeta));
|
|
137
|
+
registerViewerFocus(newMeta.node_id, oldFocus.pane, oldFocus.session, window);
|
|
162
138
|
}
|
|
139
|
+
teardownBroker(oldId); // old broker exits cleanly (its /new work is discarded)
|
|
140
|
+
return { newNodeId: newMeta.node_id };
|
|
163
141
|
}
|
|
164
|
-
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// meta when paneLocation can't resolve, e.g. outside a live tmux server).
|
|
178
|
-
const loc = paneLocation(pane) ?? {
|
|
179
|
-
session: oldMeta.tmux_session ?? null,
|
|
180
|
-
window: oldMeta.window ?? null,
|
|
181
|
-
};
|
|
182
|
-
const newId = newNodeId();
|
|
183
|
-
const { launch } = buildLaunchSpec(oldMeta.kind, 'base', { lifecycle: 'resident', hasManager: false, model: oldMeta.model_override ?? undefined });
|
|
184
|
-
// Park-old + mint-new is the single most fragile spot in the runtime, so it is
|
|
185
|
-
// ONE atomic unit: every ROW write below runs inside a sqlite transaction. A
|
|
186
|
-
// failure anywhere — including the respawn DISPATCH — rolls the whole thing
|
|
187
|
-
// back, leaving the old root EXACTLY as it was (no hand-rolled compensation).
|
|
188
|
-
// Only the *detached* respawn (the async pane kill) lands outside the txn — it
|
|
189
|
-
// must, since it kills this caller, and by then COMMIT has made the new state
|
|
190
|
-
// durable. The focus repoint (step 4) is INSIDE the txn, so a ROLLBACK undoes
|
|
191
|
-
// it automatically — there is no file to restore.
|
|
192
|
-
const db = openDb();
|
|
193
|
-
db.exec('BEGIN');
|
|
194
|
-
try {
|
|
195
|
-
// 1) Reap descendants (mark canceled + kill windows, keep edges, no wipe).
|
|
196
|
-
reapDescendants(oldId);
|
|
197
|
-
// 2) Create the fresh root node (new id, empty context dir via
|
|
198
|
-
// ensureNodeDirs) seeded active; `yield` adds the refresh safety net so
|
|
199
|
-
// that if the pane dies before boot the daemon revives it in a new window.
|
|
200
|
-
spawnNode({
|
|
201
|
-
kind: oldMeta.kind,
|
|
202
|
-
mode: 'base',
|
|
203
|
-
lifecycle: 'resident',
|
|
204
|
-
cwd: oldMeta.cwd,
|
|
205
|
-
name: oldMeta.kind,
|
|
206
|
-
parent: null,
|
|
207
|
-
spawnedBy: oldId, // audit-only successor link; does NOT touch the spine
|
|
208
|
-
nodeId: newId,
|
|
209
|
-
modelOverride: oldMeta.model_override,
|
|
210
|
-
launch,
|
|
142
|
+
/** Refresh a non-root child's pi session id on `/new`, so a later
|
|
143
|
+
* `--session <id>` wakes the right conversation. A `/new` on a child is NOT a
|
|
144
|
+
* graph reset — a root's `/new` is handled by relaunchRoot, never here; a root
|
|
145
|
+
* that reaches this is a no-op. */
|
|
146
|
+
export function resetRoot(nodeId, newSessionId, newSessionFile) {
|
|
147
|
+
const meta = getNode(nodeId);
|
|
148
|
+
const empty = { reaped: [], detached: [], reset: false };
|
|
149
|
+
if (meta === null || meta.parent == null)
|
|
150
|
+
return empty; // unknown or a root
|
|
151
|
+
if (newSessionId !== undefined) {
|
|
152
|
+
updateNode(nodeId, {
|
|
153
|
+
pi_session_id: newSessionId,
|
|
154
|
+
...(newSessionFile !== undefined ? { pi_session_file: newSessionFile } : {}),
|
|
211
155
|
});
|
|
212
|
-
transition(newId, 'yield'); // active (from spawn) + intent=refresh safety net
|
|
213
|
-
setPresence(newId, { tmux_session: loc.session, window: loc.window });
|
|
214
|
-
// REVIVE-HOME: the relaunched root's durable revive target is the session
|
|
215
|
-
// of the pane it is respawned into (same pane-recycle rule as demote).
|
|
216
|
-
updateNode(newId, { home_session: loc.session ?? nodeSession() });
|
|
217
|
-
clearPid(newId); // no pi yet → daemon 'leave' until boot records the pid
|
|
218
|
-
// 3) Park the old root: cancel (canceled + intent cleared) and detach its
|
|
219
|
-
// window so it never claims the pane, but KEEP pi_session_id (resumable),
|
|
220
|
-
// parent=null, and all edges. A5: a superseded old root did not finish its
|
|
221
|
-
// own work — it unifies on `canceled` like every other external reap.
|
|
222
|
-
transition(oldId, 'cancel');
|
|
223
|
-
setPresence(oldId, { window: null, tmux_session: null });
|
|
224
|
-
// 4) Focus follows content: repoint the old root's focus row to the new root
|
|
225
|
-
// (same pane — respawn-pane -k below keeps the %id). Inside the txn → the
|
|
226
|
-
// ROLLBACK path restores the old occupant automatically (no file to restore).
|
|
227
|
-
const oldFocus = focusOf(oldId);
|
|
228
|
-
if (oldFocus !== null)
|
|
229
|
-
setFocusOccupant(oldFocus.focus_id, newId);
|
|
230
|
-
// 5) Re-exec pi in this pane bound to newId; the dispatch is the LAST thing
|
|
231
|
-
// inside the txn. If it throws the txn rolls back (old root untouched); on
|
|
232
|
-
// success we COMMIT and the async detached kill of this pane lands after.
|
|
233
|
-
respawn(newId, pane);
|
|
234
|
-
db.exec('COMMIT');
|
|
235
156
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
rmSync(nodeDir(newId), { recursive: true, force: true });
|
|
248
|
-
}
|
|
249
|
-
catch { /* */ }
|
|
250
|
-
// The focus repoint was inside the txn; ROLLBACK already restored the old
|
|
251
|
-
// occupant — nothing to undo here.
|
|
252
|
-
throw err instanceof Error ? err : new Error(String(err));
|
|
253
|
-
}
|
|
254
|
-
return { newNodeId: newId };
|
|
157
|
+
return empty;
|
|
158
|
+
}
|
|
159
|
+
/** The child-side `/new` entry the stophook calls (the root side goes to
|
|
160
|
+
* relaunchRoot directly). The broker already drove the engine-side new_session;
|
|
161
|
+
* this only refreshes the child's session id on the SAME node id. */
|
|
162
|
+
export function handleNewSession(nodeId, newSessionId, newSessionFile) {
|
|
163
|
+
const meta = getNode(nodeId);
|
|
164
|
+
if (meta === null)
|
|
165
|
+
return { path: 'noop' };
|
|
166
|
+
resetRoot(nodeId, newSessionId, newSessionFile);
|
|
167
|
+
return { path: 'reset-child' };
|
|
255
168
|
}
|
|
256
169
|
// ---------------------------------------------------------------------------
|
|
257
170
|
// markCleanExitDone — the clean-exit→done termination guard
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type NodeMeta } from '../canvas/index.js';
|
|
2
2
|
import type { WakeOrigin } from './bearings.js';
|
|
3
|
-
import { type RespawnPaneOpts } from './placement.js';
|
|
4
3
|
/** Pick the `--session` source for a revive. resume=true prefers the absolute
|
|
5
4
|
* session-file path (immune to cwd; pi opens it directly) and keeps the bare
|
|
6
5
|
* session id as the fallback for older nodes booted before pi_session_file was
|
|
@@ -12,41 +11,22 @@ export declare function resumeArgs(meta: NodeMeta, resume: boolean): {
|
|
|
12
11
|
resumeSessionPath?: string;
|
|
13
12
|
};
|
|
14
13
|
export interface ReviveResult {
|
|
15
|
-
/**
|
|
14
|
+
/** Always null — the broker engine is never placed in a tmux window. Kept on
|
|
15
|
+
* the result for caller back-compat. */
|
|
16
16
|
window: string | null;
|
|
17
|
-
/** The
|
|
18
|
-
|
|
17
|
+
/** The node's last live LOCATION session, or null — the broker engine has no
|
|
18
|
+
* tmux session of its own (it opens no viewer). Kept for caller back-compat. */
|
|
19
|
+
session: string | null;
|
|
19
20
|
/** True when pi was instructed to resume its saved conversation (`--session <id>`). */
|
|
20
21
|
resumed: boolean;
|
|
21
22
|
}
|
|
22
|
-
/**
|
|
23
|
+
/** Relaunch `nodeId`'s broker engine from its persisted recipe and update canvas
|
|
24
|
+
* meta. Opens no viewer (engine-only).
|
|
23
25
|
*
|
|
24
|
-
* Throws if the node does not exist. All other failures
|
|
25
|
-
*
|
|
26
|
+
* Throws if the node does not exist. All other failures propagate as-is —
|
|
27
|
+
* callers (daemon, command) decide how to handle.
|
|
26
28
|
*/
|
|
27
29
|
export declare function reviveNode(nodeId: string, opts: {
|
|
28
30
|
resume: boolean;
|
|
29
31
|
wakeReason?: WakeOrigin;
|
|
30
32
|
}): ReviveResult;
|
|
31
|
-
/** Re-exec a node's pi FRESH in its EXISTING tmux pane (the refresh-yield
|
|
32
|
-
* path). Unlike `reviveNode`, this opens no new window: the pane's current pi
|
|
33
|
-
* is replaced in place via `respawn-pane -k`, so a foreground/interactive
|
|
34
|
-
* session keeps its terminal and a background node keeps its window. Always
|
|
35
|
-
* fresh (no resume) — the node re-reads its roadmap/context dir.
|
|
36
|
-
*
|
|
37
|
-
* `pane` is the target pane id (the yielding node reads it from $TMUX_PANE).
|
|
38
|
-
* Throws on unknown node or when the respawn could not be dispatched, so the
|
|
39
|
-
* caller can fall back to a plain shutdown (daemon revives in a new window). */
|
|
40
|
-
export declare function reviveInPlace(nodeId: string, pane: string, respawn?: (opts: RespawnPaneOpts) => boolean): ReviveResult;
|
|
41
|
-
/** Re-exec a FRESH pi for `nodeId` in EXISTING `pane` (respawn-pane -k), with
|
|
42
|
-
* NO prompt and NO resume — a clean root conversation (goal-capture /
|
|
43
|
-
* context-intro handle the first message + bearings, exactly like bare
|
|
44
|
-
* `crtr`). Unlike reviveInPlace: no buildReviveKickoff prompt, no cycles bump,
|
|
45
|
-
* and it sets CRTR_FRONT_DOOR=1 (REQUIRED — src/core/runtime/CLAUDE.md: any
|
|
46
|
-
* path that boots a pi must guard against a removed/renamed subcommand
|
|
47
|
-
* fork-bombing). Throws if the respawn could not be dispatched.
|
|
48
|
-
*
|
|
49
|
-
* Used by relaunchRoot (reset.ts) for the `/new`-in-a-root relaunch. Kept
|
|
50
|
-
* SEPARATE from reviveInPlace so the refresh-yield path's exact semantics
|
|
51
|
-
* (kickoff + cycle bump) are untouched. */
|
|
52
|
-
export declare function relaunchRootInPane(nodeId: string, pane: string): void;
|