@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
|
@@ -28,21 +28,31 @@
|
|
|
28
28
|
// crouter's own tsc build without a dep on the pi packages.
|
|
29
29
|
import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
|
|
30
30
|
import { join } from 'node:path';
|
|
31
|
-
import { getNode, jobDir, updateNode, recordPid,
|
|
31
|
+
import { getNode, jobDir, updateNode, recordPid, setPresence } from '../core/canvas/index.js';
|
|
32
32
|
import { transition } from '../core/runtime/lifecycle.js';
|
|
33
33
|
import { markBusy, clearBusy } from '../core/runtime/busy.js';
|
|
34
34
|
import { evaluateStop } from '../core/runtime/stop-guard.js';
|
|
35
35
|
import { personaDrift, commitPersonaAck } from '../core/runtime/persona.js';
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
|
|
36
|
+
import { handleNewSession, relaunchRoot, markCleanExitDone } from '../core/runtime/reset.js';
|
|
37
|
+
import { focusOf, tearDownNode } from '../core/runtime/placement.js';
|
|
38
|
+
/** Condense a tool call into one short line for the activity cue. Picks the most
|
|
39
|
+
* identifying arg (command / path / pattern / description), collapses whitespace,
|
|
40
|
+
* and hard-caps the length so a giant bash command can't bloat telemetry.json. */
|
|
41
|
+
const ACTIVITY_CAP = 80;
|
|
42
|
+
function summarizeActivity(toolName, args) {
|
|
43
|
+
const a = (args ?? {});
|
|
44
|
+
const pick = (v) => (typeof v === 'string' ? v : '');
|
|
45
|
+
const detail = pick(a['command']) || pick(a['path']) || pick(a['file_path']) || pick(a['pattern']) || pick(a['description']) || pick(a['prompt']);
|
|
46
|
+
const line = (detail !== '' ? `${toolName}: ${detail}` : toolName).replace(/\s+/g, ' ').trim();
|
|
47
|
+
return line.length > ACTIVITY_CAP ? line.slice(0, ACTIVITY_CAP) : line;
|
|
48
|
+
}
|
|
39
49
|
/**
|
|
40
50
|
* Merge accumulated token counts into nodes/<nodeId>/job/telemetry.json.
|
|
41
51
|
* Creates the directory when it doesn't yet exist. Best-effort; never throws.
|
|
42
52
|
* `contextTokens` is the live window gauge for THIS turn; when null (pi can't
|
|
43
53
|
* size the window yet) the last recorded value is preserved.
|
|
44
54
|
*/
|
|
45
|
-
function flushTelemetry(jobDirPath, tokensIn, tokensOut, model, contextTokens) {
|
|
55
|
+
function flushTelemetry(jobDirPath, tokensIn, tokensOut, model, contextTokens, activity) {
|
|
46
56
|
try {
|
|
47
57
|
if (!existsSync(jobDirPath))
|
|
48
58
|
mkdirSync(jobDirPath, { recursive: true });
|
|
@@ -62,6 +72,7 @@ function flushTelemetry(jobDirPath, tokensIn, tokensOut, model, contextTokens) {
|
|
|
62
72
|
tokens_in: tokensIn,
|
|
63
73
|
tokens_out: tokensOut,
|
|
64
74
|
context_tokens: contextTokens ?? existing.context_tokens,
|
|
75
|
+
last_activity: activity ?? existing.last_activity,
|
|
65
76
|
model: model !== '' ? model : (existing.model ?? ''),
|
|
66
77
|
updated_at: new Date().toISOString(),
|
|
67
78
|
};
|
|
@@ -98,18 +109,22 @@ function lastAssistantMessage(messages) {
|
|
|
98
109
|
// 185k+ pushy. Keyed on mode, NOT lifecycle: a terminal/orchestrator
|
|
99
110
|
// yields against its roadmap exactly like a resident one (the
|
|
100
111
|
// daemon's refresh-revive keys on intent='refresh', not lifecycle).
|
|
101
|
-
// resident/base (a root conversation):
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
112
|
+
// resident/base (a root conversation): NO roadmap on disk yet, so it is not
|
|
113
|
+
// told to checkpoint one. `crtr node yield` is still its continue
|
|
114
|
+
// verb — it auto-promotes + seeds a roadmap transparently — offered
|
|
115
|
+
// against wrap-up, since a root chat can simply end. Gentle → firm →
|
|
105
116
|
// pushy.
|
|
106
|
-
// terminal/base (a worker):
|
|
107
|
-
//
|
|
117
|
+
// terminal/base (a worker): steered to `crtr node yield` to continue in a
|
|
118
|
+
// fresh window when work remains (yield auto-promotes under the
|
|
119
|
+
// hood), or `push final` when close. Gentle → firm → pushy.
|
|
108
120
|
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
121
|
+
// Every persona's "keep going" verb is `crtr node yield` — NEVER a bare `node
|
|
122
|
+
// promote`, which framed promotion as a heavy "become an orchestrator" step and
|
|
123
|
+
// bred yield-avoidance. A base node's yield auto-promotes + seeds the roadmap
|
|
124
|
+
// under the hood, so the agent never decides to promote — it just yields. Only a
|
|
125
|
+
// terminal node is ever told `push final` (a resident finishes by yielding or
|
|
126
|
+
// being closed); only an orchestrator already HAS a roadmap to checkpoint before
|
|
127
|
+
// it yields.
|
|
113
128
|
// ---------------------------------------------------------------------------
|
|
114
129
|
const STEER_STEP = 10_000;
|
|
115
130
|
// Shared escalation schedule (both lifecycles). Tightens as it climbs:
|
|
@@ -132,20 +147,22 @@ function steerBand(tokens) {
|
|
|
132
147
|
return chosen;
|
|
133
148
|
}
|
|
134
149
|
/** The nudge text for a crossed band, specialized to the node's (mode,
|
|
135
|
-
* lifecycle) persona + how far along the escalation it is.
|
|
150
|
+
* lifecycle) persona + how far along the escalation it is. `crtr node yield` is
|
|
151
|
+
* the single "keep going past this window" verb for every persona: it refreshes
|
|
152
|
+
* the node into a clean window against a roadmap, and for a base node
|
|
153
|
+
* auto-promotes transparently — so no persona is ever steered at a bare `node
|
|
154
|
+
* promote` (which framed promotion as a heavy "become an orchestrator" step and
|
|
155
|
+
* bred yield-avoidance).
|
|
136
156
|
*
|
|
137
|
-
* - orchestrator (terminal OR resident): checkpoint
|
|
138
|
-
* (
|
|
139
|
-
* - resident/base (root conversation):
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* - terminal/base (worker): PROMOTE itself — become an orchestrator — when
|
|
144
|
-
* work remains, with an "ignore if nearly done, finish with push final" once
|
|
145
|
-
* it's deeper in.
|
|
157
|
+
* - orchestrator (terminal OR resident): checkpoint context/roadmap.md, then
|
|
158
|
+
* yield (it already has a roadmap to bring current first).
|
|
159
|
+
* - resident/base (root conversation): yield to continue in a fresh window if
|
|
160
|
+
* the chat is growing into a job, else wrap up — a root can simply end.
|
|
161
|
+
* - terminal/base (worker): yield to continue if work remains, or `push final`
|
|
162
|
+
* when close.
|
|
146
163
|
*
|
|
147
|
-
*
|
|
148
|
-
* drifting further risks an overflow. */
|
|
164
|
+
* The wording strengthens with depth: gentle < 150k → firm < 185k → pushy at/
|
|
165
|
+
* past 185k, where drifting further risks an overflow. */
|
|
149
166
|
export function steerNote(at, lifecycle, mode) {
|
|
150
167
|
const k = Math.round(at / 1000);
|
|
151
168
|
const pushy = at >= 185_000;
|
|
@@ -161,25 +178,31 @@ export function steerNote(at, lifecycle, mode) {
|
|
|
161
178
|
return `Context ~${k}k — this is getting long. Stop taking on new work now: checkpoint context/roadmap.md, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`;
|
|
162
179
|
}
|
|
163
180
|
if (lifecycle === 'resident') {
|
|
164
|
-
// resident/base — a root conversation
|
|
165
|
-
//
|
|
166
|
-
|
|
181
|
+
// resident/base — a root conversation with no roadmap yet. `crtr node yield`
|
|
182
|
+
// is still the natural "carry this forward" verb: it refreshes into a clean
|
|
183
|
+
// window against a roadmap and auto-promotes transparently (no scary
|
|
184
|
+
// "become an orchestrator" step). Offer wrap-up as the alternative — a root
|
|
185
|
+
// chat can simply end.
|
|
186
|
+
const grow = `If this is turning into a multi-phase job, \`crtr node yield\` to continue in a fresh window against a roadmap — no need to "become" anything, yield just carries you forward.`;
|
|
167
187
|
if (at < 150_000) {
|
|
168
188
|
return `Context ~${k}k and growing. ${grow} Otherwise no rush — wrap up when you reach a good stopping point.`;
|
|
169
189
|
}
|
|
170
190
|
if (!pushy) {
|
|
171
|
-
return `Context ~${k}k. ${grow} If you're near done, just finish here; if there's more open-ended work,
|
|
191
|
+
return `Context ~${k}k. ${grow} If you're near done, just finish here; if there's more open-ended work, \`crtr node yield\` rather than letting this context grow.`;
|
|
172
192
|
}
|
|
173
|
-
return `Context ~${k}k — this is getting long. Wrap up now before this context overflows: finish what's in hand, or \`crtr node
|
|
193
|
+
return `Context ~${k}k — this is getting long. Wrap up now before this context overflows: finish what's in hand, or \`crtr node yield\` immediately to continue fresh against a roadmap if substantial work remains.`;
|
|
194
|
+
}
|
|
195
|
+
// terminal/base — a worker. The natural "keep going past this window" verb is
|
|
196
|
+
// `crtr node yield`: it refreshes into a clean window against a roadmap and
|
|
197
|
+
// auto-promotes transparently, so there is no separate "become an orchestrator"
|
|
198
|
+
// decision to agonize over. Steer it to yield-or-finish, never a bare promote.
|
|
199
|
+
if (at < 150_000) {
|
|
200
|
+
return `Context ~${k}k and growing. If you're near done, finish with \`crtr push final\`. If real work remains, \`crtr node yield\` to continue in a fresh window against a roadmap — no rush yet.`;
|
|
174
201
|
}
|
|
175
|
-
// terminal — a worker.
|
|
176
|
-
const suggest = `If much more work remains than this context can finish, consider \`crtr node promote\` to become an orchestrator (seeds a roadmap, lets you delegate and \`crtr node yield\` to refresh).`;
|
|
177
|
-
if (at < 170_000)
|
|
178
|
-
return `Context ~${k}k. ${suggest}`;
|
|
179
202
|
if (!pushy) {
|
|
180
|
-
return `Context ~${k}k.
|
|
203
|
+
return `Context ~${k}k. If you're close, finish with \`crtr push final\`; otherwise \`crtr node yield\` now to refresh into a clean window and keep going against a roadmap.`;
|
|
181
204
|
}
|
|
182
|
-
return `Context ~${k}k — this is getting long. Wrap up now: \`crtr push final\` if you're close, otherwise \`crtr node
|
|
205
|
+
return `Context ~${k}k — this is getting long. Wrap up now before this context overflows: \`crtr push final\` if you're close, otherwise \`crtr node yield\` immediately to continue in a fresh window against a roadmap.`;
|
|
183
206
|
}
|
|
184
207
|
// ---------------------------------------------------------------------------
|
|
185
208
|
// Extension
|
|
@@ -205,6 +228,10 @@ export function registerCanvasStophook(pi) {
|
|
|
205
228
|
let totalIn = 0;
|
|
206
229
|
let totalOut = 0;
|
|
207
230
|
let model = '';
|
|
231
|
+
// Last live context-window gauge + last tool summary, tracked across handlers so
|
|
232
|
+
// a tool_execution_start flush (activity-only) preserves the latest token figure.
|
|
233
|
+
let lastContext = null;
|
|
234
|
+
let lastActivity = null;
|
|
208
235
|
// Context-size steering. As input context grows we nudge the node once per
|
|
209
236
|
// band on an escalating, persona-specific schedule (see steerBand/steerNote).
|
|
210
237
|
// The node's (lifecycle, mode) persona is read at fire time, since a terminal
|
|
@@ -224,13 +251,12 @@ export function registerCanvasStophook(pi) {
|
|
|
224
251
|
// Why reason, not a closure flag: pi RE-ACTIVATES extensions on every session
|
|
225
252
|
// swap, so any id we stash on boot is reset to its initial value before the
|
|
226
253
|
// next session_start fires and can never observe the change — a `/new` then
|
|
227
|
-
// looks identical to a boot.
|
|
228
|
-
//
|
|
229
|
-
// id + context dir never changed.) The event reason is delivered fresh on
|
|
230
|
-
// every fire and is immune to the re-activation.
|
|
254
|
+
// looks identical to a boot. The event reason is delivered fresh on every fire
|
|
255
|
+
// and is immune to the re-activation.
|
|
231
256
|
//
|
|
232
|
-
//
|
|
233
|
-
// root
|
|
257
|
+
// `/new` splits by who ran it: a ROOT relaunches into a genuinely new node
|
|
258
|
+
// (relaunchRoot — park the old root `done`, boot a fresh node, re-point this
|
|
259
|
+
// pane), a non-root CHILD just refreshes its session id (handleNewSession).
|
|
234
260
|
// ---------------------------------------------------------------------------
|
|
235
261
|
pi.on('session_start', (event, ctx) => {
|
|
236
262
|
try {
|
|
@@ -242,16 +268,19 @@ export function registerCanvasStophook(pi) {
|
|
|
242
268
|
// whereas a bare id is resolved cwd-relative and forks across projects.
|
|
243
269
|
const filed = ctx?.sessionManager?.getSessionFile?.();
|
|
244
270
|
const sessionFile = typeof filed === 'string' && filed !== '' ? filed : null;
|
|
245
|
-
// `/new` — a brand-new conversation in the same process.
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
// after handleNewSession.
|
|
271
|
+
// `/new` — a brand-new conversation in the same process. The broker already
|
|
272
|
+
// drove the engine-side new_session (the viewer's /new → broker
|
|
273
|
+
// new_session frame); the runtime side then splits on root-ness: a ROOT
|
|
274
|
+
// relaunches into a freshly-minted node (park the old root `done`, boot a
|
|
275
|
+
// new broker, re-point the viewer pane), a non-root CHILD just refreshes
|
|
276
|
+
// its session id on the SAME node.
|
|
252
277
|
if (event?.reason === 'new') {
|
|
253
278
|
try {
|
|
254
|
-
|
|
279
|
+
const m = getNode(nodeId);
|
|
280
|
+
if (m?.parent == null)
|
|
281
|
+
relaunchRoot(nodeId);
|
|
282
|
+
else
|
|
283
|
+
handleNewSession(nodeId, id, sessionFile);
|
|
255
284
|
}
|
|
256
285
|
catch { /* best-effort */ }
|
|
257
286
|
// Clear in-memory context-steering so the fresh conversation starts clean.
|
|
@@ -261,13 +290,12 @@ export function registerCanvasStophook(pi) {
|
|
|
261
290
|
return;
|
|
262
291
|
}
|
|
263
292
|
// Boot / startup / resume / reload / fork → (re)bind this process to its
|
|
264
|
-
// session id, record our OS pid (the daemon's liveness signal
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
// set
|
|
269
|
-
//
|
|
270
|
-
// it — otherwise a failed respawn would look identical to a successful one.
|
|
293
|
+
// session id, record our OS pid (the daemon's broker-liveness signal), and
|
|
294
|
+
// CONFIRM any pending refresh-yield. Reaching session_start proves a fresh
|
|
295
|
+
// engine actually booted, so it is now safe to clear intent='refresh' — a
|
|
296
|
+
// refresh shuts the broker down and the daemon relaunches it FRESH, which
|
|
297
|
+
// leaves intent='refresh' set until this boot clears it (the only proof the
|
|
298
|
+
// relaunch worked; otherwise a failed relaunch would look like a success).
|
|
271
299
|
const existing = getNode(nodeId);
|
|
272
300
|
// Identity (session id/file) → meta; runtime (pid, intent) → atomic row setters.
|
|
273
301
|
updateNode(nodeId, {
|
|
@@ -294,6 +322,18 @@ export function registerCanvasStophook(pi) {
|
|
|
294
322
|
catch { /* best-effort */ }
|
|
295
323
|
});
|
|
296
324
|
// ---------------------------------------------------------------------------
|
|
325
|
+
// tool_execution_start — capture the live "what is it doing" cue. Writes the
|
|
326
|
+
// one-line tool summary to telemetry.json so out-of-process readers (the nav
|
|
327
|
+
// chrome) show it inline without a second file or any extra read on their side.
|
|
328
|
+
// ---------------------------------------------------------------------------
|
|
329
|
+
pi.on('tool_execution_start', (event) => {
|
|
330
|
+
try {
|
|
331
|
+
lastActivity = summarizeActivity(String(event?.toolName ?? ''), event?.args);
|
|
332
|
+
flushTelemetry(jobDirPath, totalIn, totalOut, model, lastContext, lastActivity);
|
|
333
|
+
}
|
|
334
|
+
catch { /* best-effort */ }
|
|
335
|
+
});
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
297
337
|
// session_shutdown — clean exit → done.
|
|
298
338
|
//
|
|
299
339
|
// pi hands us a reason as a session tears down. Only 'quit' is a node-ending
|
|
@@ -347,8 +387,10 @@ export function registerCanvasStophook(pi) {
|
|
|
347
387
|
contextTokens = t;
|
|
348
388
|
}
|
|
349
389
|
catch { /* gauge unavailable this turn */ }
|
|
390
|
+
if (contextTokens !== null)
|
|
391
|
+
lastContext = contextTokens;
|
|
350
392
|
// Fire-and-forget: flushTelemetry uses synchronous fs writes and never throws.
|
|
351
|
-
flushTelemetry(jobDirPath, totalIn, totalOut, model, contextTokens);
|
|
393
|
+
flushTelemetry(jobDirPath, totalIn, totalOut, model, contextTokens, lastActivity);
|
|
352
394
|
// Context-size steering: fire the current band once, with lifecycle-specific
|
|
353
395
|
// guidance (lifecycle is read live — a terminal worker may have promoted to
|
|
354
396
|
// resident since launch).
|
|
@@ -417,32 +459,18 @@ export function registerCanvasStophook(pi) {
|
|
|
417
459
|
// transitions node.status → 'done' synchronously. Shut down cleanly.
|
|
418
460
|
const node = getNode(nodeId);
|
|
419
461
|
if (node?.status === 'done') {
|
|
420
|
-
// TRULY-DONE (pushed `final` this turn).
|
|
421
|
-
//
|
|
422
|
-
//
|
|
423
|
-
//
|
|
424
|
-
//
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
// this focus AND flip remain-on-exit OFF on %m's window so the pane
|
|
429
|
-
// closes when this pi exits (return-to-shell) instead of freezing into
|
|
430
|
-
// an orphan. We CANNOT closePane(%m) from inside %m (self-saw), but the
|
|
431
|
-
// pi is still alive mid-shutdown, so remain-on-exit-off is safe and
|
|
432
|
-
// makes tmux reap the pane on exit. An unfocused done node just shuts
|
|
433
|
-
// down (no pane anywhere, Invariant P). M is done → it owns no pane
|
|
434
|
-
// (Invariant P), so null its own presence in BOTH sub-branches before
|
|
435
|
-
// shutdown.
|
|
436
|
-
const f = focusOf(nodeId);
|
|
437
|
-
if (f !== null) {
|
|
438
|
-
const managerId = node.parent ?? subscribersOf(nodeId)[0]?.node_id ?? null;
|
|
439
|
-
if (!handFocusToManager(f.focus_id, managerId)) {
|
|
440
|
-
// Q1 return-to-shell, self-saw-safe: close the focus row + disarm the
|
|
441
|
-
// pane's freeze so it reaps on exit (we can't closePane our own pane).
|
|
442
|
-
closeFocusToShell(f.focus_id, nodeId);
|
|
462
|
+
// TRULY-DONE (pushed `final` this turn). The engine is a detached
|
|
463
|
+
// broker, not a pane, so there is no engine to hand off — just close
|
|
464
|
+
// this node's VIEWER pane (if any) and shut the broker down. The daemon
|
|
465
|
+
// won't revive a done node. tearDownNode closes the viewer focus row +
|
|
466
|
+
// pane; ctx.shutdown() exits the broker process.
|
|
467
|
+
if (focusOf(nodeId) !== null) {
|
|
468
|
+
try {
|
|
469
|
+
tearDownNode(nodeId);
|
|
443
470
|
}
|
|
471
|
+
catch { /* best-effort */ }
|
|
444
472
|
}
|
|
445
|
-
setPresence(nodeId, { pane: null, tmux_session: null, window: null });
|
|
473
|
+
setPresence(nodeId, { pane: null, tmux_session: null, window: null });
|
|
446
474
|
try {
|
|
447
475
|
ctx?.shutdown?.();
|
|
448
476
|
}
|
|
@@ -450,27 +478,15 @@ export function registerCanvasStophook(pi) {
|
|
|
450
478
|
return;
|
|
451
479
|
}
|
|
452
480
|
// (b') Refresh-yield: the node ran `crtr node yield` this turn, setting
|
|
453
|
-
// intent='refresh'.
|
|
454
|
-
//
|
|
455
|
-
//
|
|
456
|
-
//
|
|
457
|
-
//
|
|
458
|
-
// exited into a persistent shell pane). Falls back to a clean
|
|
459
|
-
// shutdown (daemon revives in a new window) only when we're not in
|
|
460
|
-
// a tmux pane.
|
|
481
|
+
// intent='refresh'. Just shut the broker down — the daemon sees the
|
|
482
|
+
// dead pid + intent='refresh' and reviveNode's relaunches the broker
|
|
483
|
+
// FRESH (no resume) so the node re-reads its roadmap. (The daemon
|
|
484
|
+
// also force-recycles a stuck refresh whose engine never exits, so a
|
|
485
|
+
// stale in-process stophook can't strand the yield — see crtrd.)
|
|
461
486
|
if (node?.intent === 'refresh') {
|
|
462
487
|
// A yield is SILENT to subscribers: the node keeps its identity and
|
|
463
|
-
// subscription edges across the revive and reports only through its
|
|
464
|
-
//
|
|
465
|
-
// — just re-exec a fresh pi in place against the roadmap.
|
|
466
|
-
const pane = process.env['TMUX_PANE'];
|
|
467
|
-
if (pane !== undefined && pane.trim() !== '') {
|
|
468
|
-
try {
|
|
469
|
-
reviveInPlace(nodeId, pane);
|
|
470
|
-
return; // respawn-pane -k tears down this pi and starts the fresh one
|
|
471
|
-
}
|
|
472
|
-
catch { /* fall through to plain shutdown */ }
|
|
473
|
-
}
|
|
488
|
+
// subscription edges across the revive and reports only through its own
|
|
489
|
+
// explicit `crtr push` calls, so there is no checkpoint push here.
|
|
474
490
|
try {
|
|
475
491
|
ctx?.shutdown?.();
|
|
476
492
|
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
// inside crouter's own tsc build without a dep on the pi packages (mirrors
|
|
22
22
|
// canvas-resume.ts / canvas-nav.ts / canvas-commands.ts).
|
|
23
23
|
import { execFile } from 'node:child_process';
|
|
24
|
+
import { surfaceTmuxStyleArgs } from '../core/runtime/surface-bg.js';
|
|
24
25
|
/** Single-quote a string for safe interpolation into a `sh -c` command line —
|
|
25
26
|
* tmux runs the display-popup trailing string through the shell, so a view
|
|
26
27
|
* name with spaces or quotes must be escaped. */
|
|
@@ -59,7 +60,7 @@ export function registerCanvasView(pi) {
|
|
|
59
60
|
// bare /view → the picker; /view <name> → that view directly.
|
|
60
61
|
const cmd = name === '' ? 'crtr view pick' : `crtr view run ${shellQuote(name)}`;
|
|
61
62
|
try {
|
|
62
|
-
execFile('tmux', ['display-popup', '-E', '-w', '90%', '-h', '85%', cmd], () => { });
|
|
63
|
+
execFile('tmux', ['display-popup', '-E', '-w', '90%', '-h', '85%', ...surfaceTmuxStyleArgs(), cmd], () => { });
|
|
63
64
|
}
|
|
64
65
|
catch { /* best-effort */ }
|
|
65
66
|
return;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Called by canvas-nav (once per session_start) to expose its scheduleRender. */
|
|
2
|
+
export declare function onNavRerender(cb: () => void): void;
|
|
3
|
+
/** Called by canvas-recap after it sets/clears `crtr-recap` to nudge canvas-nav
|
|
4
|
+
* to re-assert `crtr-managers` below it. No-op if nav has not registered (e.g.
|
|
5
|
+
* nav inert, or recap-only test harness). */
|
|
6
|
+
export declare function requestNavRerender(): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// widget-order-bus.ts — a tiny in-process bus that lets canvas-recap keep its
|
|
2
|
+
// recap widget pinned ABOVE canvas-nav's manager line.
|
|
3
|
+
//
|
|
4
|
+
// Why this exists: pi's interactive widget store (and the broker's relay) is
|
|
5
|
+
// insertion-ordered, and re-setting an existing widget key moves it to the END
|
|
6
|
+
// (bottom) — see interactive-mode.js `setExtensionWidget` (delete+set). So the
|
|
7
|
+
// LAST extension to call setWidget for an aboveEditor key renders closest to the
|
|
8
|
+
// editor. canvas-recap only paints during idle, when canvas-nav has not re-set
|
|
9
|
+
// `crtr-managers` for a long time, so a naive recap setWidget lands BELOW the
|
|
10
|
+
// manager line. The fix: after canvas-recap changes its widget, it asks
|
|
11
|
+
// canvas-nav to re-assert `crtr-managers`, which re-inserts that key after
|
|
12
|
+
// `crtr-recap` and so drops it below the recap — making the recap the topmost
|
|
13
|
+
// chrome.
|
|
14
|
+
//
|
|
15
|
+
// Both extensions load in the SAME pi process, so this module is a shared
|
|
16
|
+
// singleton via Node's module cache. No @earendil-works/* imports — compiles in
|
|
17
|
+
// crouter's own tsc build.
|
|
18
|
+
/** canvas-nav registers its re-render here on session_start; canvas-recap calls
|
|
19
|
+
* requestNavRerender() after it shows/clears the recap so the manager line
|
|
20
|
+
* re-inserts (and thus orders) below the recap widget. */
|
|
21
|
+
let navRerender;
|
|
22
|
+
/** Called by canvas-nav (once per session_start) to expose its scheduleRender. */
|
|
23
|
+
export function onNavRerender(cb) {
|
|
24
|
+
navRerender = cb;
|
|
25
|
+
}
|
|
26
|
+
/** Called by canvas-recap after it sets/clears `crtr-recap` to nudge canvas-nav
|
|
27
|
+
* to re-assert `crtr-managers` below it. No-op if nav has not registered (e.g.
|
|
28
|
+
* nav inert, or recap-only test harness). */
|
|
29
|
+
export function requestNavRerender() {
|
|
30
|
+
try {
|
|
31
|
+
navRerender?.();
|
|
32
|
+
}
|
|
33
|
+
catch { /* best-effort */ }
|
|
34
|
+
}
|
package/dist/prompts/view.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export interface ViewScaffoldVars {
|
|
|
3
3
|
title: string;
|
|
4
4
|
description: string;
|
|
5
5
|
}
|
|
6
|
-
/** Build
|
|
7
|
-
export declare function viewScaffold(v: ViewScaffoldVars): string
|
|
6
|
+
/** Build every file of a freshly scaffolded dual-target view, keyed by filename. */
|
|
7
|
+
export declare function viewScaffold(v: ViewScaffoldVars): Record<string, string>;
|