@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
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// canvas-recap.ts — pi extension for pi-native canvas agent nodes.
|
|
2
|
+
//
|
|
3
|
+
// A per-node INACTIVITY RECAP, drawn as the topmost chrome above the editor.
|
|
4
|
+
// When a node has had NO new message (user or assistant) for IDLE_MS (300s by
|
|
5
|
+
// default), it runs Haiku over the literal conversation and pins a terse
|
|
6
|
+
// three-fragment card — goal / doing-now / next — above canvas-nav's manager
|
|
7
|
+
// line. The card disappears the instant the next message arrives, and the idle
|
|
8
|
+
// clock restarts.
|
|
9
|
+
//
|
|
10
|
+
// trigger/clear are keyed off MESSAGES, not turns-of-work:
|
|
11
|
+
// • a user `input` event OR an assistant `turn_end` resets the idle clock
|
|
12
|
+
// and clears any shown recap.
|
|
13
|
+
// • a single low-rate timer (no busy-loop) checks elapsed-since-last-message
|
|
14
|
+
// and, on crossing IDLE_MS, generates + shows the recap once.
|
|
15
|
+
//
|
|
16
|
+
// Haiku input = ALL user + assistant LITERAL text, most-recent within a char
|
|
17
|
+
// budget. Tool calls, tool results, thinking blocks, and extension-injected
|
|
18
|
+
// custom messages are excluded (only `message` entries with role user/assistant,
|
|
19
|
+
// and only their `text` content blocks).
|
|
20
|
+
//
|
|
21
|
+
// Placement: key `crtr-recap`, placement `aboveEditor`, ordered ABOVE
|
|
22
|
+
// `crtr-managers` via the widget-order bus (pi's widget store is insertion-
|
|
23
|
+
// ordered and re-setting moves a key to the bottom; after we paint the recap
|
|
24
|
+
// we ask canvas-nav to re-assert its manager line, which drops it below us).
|
|
25
|
+
//
|
|
26
|
+
// Surface gating: shows in BOTH the in-pane pi TUI (mode 'tui') and the
|
|
27
|
+
// headless broker → attach/web viewers (mode 'print', setWidget broadcasts to
|
|
28
|
+
// all surfaces). It does NOT gate on mode === 'tui' (that would kill the
|
|
29
|
+
// headless+attach path). It NO-OPs only when ui/setWidget is unavailable, and
|
|
30
|
+
// harmlessly in a true one-shot `pi -p` (the unref'd timer never fires before
|
|
31
|
+
// the process exits, and naming-style one-shots load with --no-extensions).
|
|
32
|
+
//
|
|
33
|
+
// INERT when CRTR_NODE_ID is absent (a plain pi session or legacy job agent).
|
|
34
|
+
//
|
|
35
|
+
// Plain TS-with-types — no imports from @earendil-works/* so this compiles
|
|
36
|
+
// inside crouter's own tsc build without a dep on the pi packages.
|
|
37
|
+
import { generateRecap } from '../core/runtime/recap.js';
|
|
38
|
+
import { requestNavRerender } from './widget-order-bus.js';
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Tuning constants
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/** No-new-message window before a recap is shown. 300s by default; override with
|
|
43
|
+
* CRTR_RECAP_IDLE_MS (for fast runtime verification). */
|
|
44
|
+
function idleMs() {
|
|
45
|
+
const raw = process.env['CRTR_RECAP_IDLE_MS'];
|
|
46
|
+
const n = raw !== undefined ? parseInt(raw, 10) : NaN;
|
|
47
|
+
return Number.isFinite(n) && n > 0 ? n : 300_000;
|
|
48
|
+
}
|
|
49
|
+
/** How often the (single, low-rate) timer checks elapsed-since-last-message.
|
|
50
|
+
* Mirrors canvas-nav's ASK_POLL_MS — cheap and tmux/crtr-free. */
|
|
51
|
+
const POLL_MS = 7_000;
|
|
52
|
+
/** Char budget on the conversation fed to Haiku — the model only needs the gist,
|
|
53
|
+
* so we keep the MOST-RECENT text within this cap (a recap is about where we
|
|
54
|
+
* left off, not the whole history). */
|
|
55
|
+
const CONVO_CHAR_BUDGET = 12_000;
|
|
56
|
+
const WIDGET_KEY = 'crtr-recap';
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Module-level state — persists across /reload so the timer doesn't stack.
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
/** The one live poll timer. Cleared and replaced on every re-registration. */
|
|
61
|
+
let liveTimer;
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Conversation extraction — literal user+assistant text ONLY.
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/** Pull the literal text out of a message's content (string or text blocks),
|
|
66
|
+
* dropping non-text blocks (thinking, toolCall, image). */
|
|
67
|
+
function messageText(msg) {
|
|
68
|
+
const c = msg.content;
|
|
69
|
+
if (typeof c === 'string')
|
|
70
|
+
return c.trim();
|
|
71
|
+
if (!Array.isArray(c))
|
|
72
|
+
return '';
|
|
73
|
+
return c
|
|
74
|
+
.filter((b) => b !== null && typeof b === 'object' && b.type === 'text' && typeof b.text === 'string')
|
|
75
|
+
.map((b) => (b.text ?? '').trim())
|
|
76
|
+
.filter((t) => t !== '')
|
|
77
|
+
.join('\n')
|
|
78
|
+
.trim();
|
|
79
|
+
}
|
|
80
|
+
/** Concatenate the conversation's user + assistant literal text into a single
|
|
81
|
+
* `User:`/`Agent:` transcript, keeping only the MOST-RECENT CONVO_CHAR_BUDGET
|
|
82
|
+
* characters. Excludes tool calls/results (role toolResult, plus toolCall/
|
|
83
|
+
* thinking content blocks dropped by messageText) and extension-injected
|
|
84
|
+
* custom messages (entry.type !== 'message'). Returns '' when there is nothing
|
|
85
|
+
* to summarize. */
|
|
86
|
+
function buildConversation(sm) {
|
|
87
|
+
let entries;
|
|
88
|
+
try {
|
|
89
|
+
entries = sm.getEntries();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return '';
|
|
93
|
+
}
|
|
94
|
+
const parts = [];
|
|
95
|
+
for (const e of entries) {
|
|
96
|
+
if (e.type !== 'message' || e.message === undefined)
|
|
97
|
+
continue;
|
|
98
|
+
const role = e.message.role;
|
|
99
|
+
if (role !== 'user' && role !== 'assistant')
|
|
100
|
+
continue; // drop toolResult etc.
|
|
101
|
+
const text = messageText(e.message);
|
|
102
|
+
if (text === '')
|
|
103
|
+
continue;
|
|
104
|
+
parts.push(`${role === 'user' ? 'User' : 'Agent'}: ${text}`);
|
|
105
|
+
}
|
|
106
|
+
if (parts.length === 0)
|
|
107
|
+
return '';
|
|
108
|
+
const full = parts.join('\n\n');
|
|
109
|
+
return full.length > CONVO_CHAR_BUDGET ? full.slice(full.length - CONVO_CHAR_BUDGET) : full;
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Extension
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Register the inactivity-recap chrome on `pi`.
|
|
116
|
+
*
|
|
117
|
+
* Returns immediately (inert) when CRTR_NODE_ID is absent — a plain pi session
|
|
118
|
+
* or legacy job agent loads it as a no-op.
|
|
119
|
+
*/
|
|
120
|
+
export function registerCanvasRecap(pi) {
|
|
121
|
+
const nodeId = process.env['CRTR_NODE_ID'];
|
|
122
|
+
if (nodeId === undefined || nodeId.trim() === '')
|
|
123
|
+
return; // not a canvas node
|
|
124
|
+
// Captured on session_start; used by the timer and the message handlers.
|
|
125
|
+
let ui;
|
|
126
|
+
let sessionManager;
|
|
127
|
+
/** Wall-clock of the most recent user/assistant message. The idle clock. */
|
|
128
|
+
let lastMessageAt = Date.now();
|
|
129
|
+
/** True while a recap is currently shown (so we generate at most once per
|
|
130
|
+
* idle window, and know whether a clear is needed on the next message). */
|
|
131
|
+
let recapShown = false;
|
|
132
|
+
/** True while a Haiku generation is in flight (so we don't fire a second). */
|
|
133
|
+
let generating = false;
|
|
134
|
+
const canPaint = () => ui !== undefined && typeof ui.setWidget === 'function';
|
|
135
|
+
const clearRecap = () => {
|
|
136
|
+
if (!canPaint())
|
|
137
|
+
return;
|
|
138
|
+
try {
|
|
139
|
+
ui.setWidget(WIDGET_KEY, undefined, { placement: 'aboveEditor' });
|
|
140
|
+
}
|
|
141
|
+
catch { /* best-effort */ }
|
|
142
|
+
};
|
|
143
|
+
/** Render the three fragments as the topmost above-editor card. */
|
|
144
|
+
const showRecap = (fragments) => {
|
|
145
|
+
if (!canPaint())
|
|
146
|
+
return;
|
|
147
|
+
const labels = ['◷ goal', '· now ', '→ next'];
|
|
148
|
+
const lines = fragments.slice(0, 3).map((f, i) => `${labels[i] ?? ' '} ${f}`);
|
|
149
|
+
if (lines.length === 0)
|
|
150
|
+
return;
|
|
151
|
+
try {
|
|
152
|
+
ui.setWidget(WIDGET_KEY, lines, { placement: 'aboveEditor' });
|
|
153
|
+
}
|
|
154
|
+
catch { /* best-effort */ }
|
|
155
|
+
// Re-assert the manager line BELOW us (pi's widget store is insertion-
|
|
156
|
+
// ordered; re-setting crtr-managers drops it under crtr-recap).
|
|
157
|
+
requestNavRerender();
|
|
158
|
+
};
|
|
159
|
+
/** A user or assistant message landed: reset the idle clock and clear any
|
|
160
|
+
* shown recap (the conversation has moved on). */
|
|
161
|
+
const onMessage = () => {
|
|
162
|
+
lastMessageAt = Date.now();
|
|
163
|
+
if (recapShown) {
|
|
164
|
+
recapShown = false;
|
|
165
|
+
clearRecap();
|
|
166
|
+
requestNavRerender();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
// -------------------------------------------------------------------------
|
|
170
|
+
// Events
|
|
171
|
+
// -------------------------------------------------------------------------
|
|
172
|
+
pi.on('session_start', (_event, ctx) => {
|
|
173
|
+
ui = ctx.ui;
|
|
174
|
+
sessionManager = ctx.sessionManager;
|
|
175
|
+
// Fresh session / hot-swap: start the idle clock now and drop any stale
|
|
176
|
+
// recap that bled through a /reload.
|
|
177
|
+
lastMessageAt = Date.now();
|
|
178
|
+
recapShown = false;
|
|
179
|
+
generating = false;
|
|
180
|
+
clearRecap();
|
|
181
|
+
});
|
|
182
|
+
pi.on('input', (_event, _ctx) => {
|
|
183
|
+
// Every user message (any source) is activity — reset + clear.
|
|
184
|
+
onMessage();
|
|
185
|
+
});
|
|
186
|
+
pi.on('turn_end', (_event, _ctx) => {
|
|
187
|
+
// A completed assistant turn is activity — reset + clear.
|
|
188
|
+
onMessage();
|
|
189
|
+
});
|
|
190
|
+
// -------------------------------------------------------------------------
|
|
191
|
+
// The single low-rate idle poll — no busy-loop, mirrors canvas-nav's timer.
|
|
192
|
+
// -------------------------------------------------------------------------
|
|
193
|
+
if (liveTimer !== undefined)
|
|
194
|
+
clearInterval(liveTimer);
|
|
195
|
+
const timer = setInterval(() => {
|
|
196
|
+
try {
|
|
197
|
+
if (!canPaint() || sessionManager === undefined)
|
|
198
|
+
return;
|
|
199
|
+
if (recapShown || generating)
|
|
200
|
+
return;
|
|
201
|
+
if (Date.now() - lastMessageAt < idleMs())
|
|
202
|
+
return;
|
|
203
|
+
const convo = buildConversation(sessionManager);
|
|
204
|
+
if (convo === '')
|
|
205
|
+
return; // nothing to summarize yet
|
|
206
|
+
// Snapshot the clock: if a message arrives while Haiku runs, discard the
|
|
207
|
+
// (now-stale) result instead of painting over the live conversation.
|
|
208
|
+
const startedAt = lastMessageAt;
|
|
209
|
+
generating = true;
|
|
210
|
+
generateRecap(convo, (fragments) => {
|
|
211
|
+
generating = false;
|
|
212
|
+
if (lastMessageAt !== startedAt)
|
|
213
|
+
return; // a message landed mid-flight
|
|
214
|
+
if (!canPaint())
|
|
215
|
+
return;
|
|
216
|
+
recapShown = true;
|
|
217
|
+
showRecap(fragments);
|
|
218
|
+
});
|
|
219
|
+
// generateRecap is silent on failure (never calls back), so clear the
|
|
220
|
+
// in-flight flag after the timeout window even if no callback fires.
|
|
221
|
+
setTimeout(() => { generating = false; }, 30_000).unref?.();
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
/* timer is best-effort */
|
|
225
|
+
}
|
|
226
|
+
}, POLL_MS);
|
|
227
|
+
if (typeof timer.unref === 'function')
|
|
228
|
+
timer.unref();
|
|
229
|
+
liveTimer = timer;
|
|
230
|
+
pi.on('session_shutdown', () => {
|
|
231
|
+
clearInterval(timer);
|
|
232
|
+
if (liveTimer === timer)
|
|
233
|
+
liveTimer = undefined;
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
export default registerCanvasRecap;
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
// inside crouter's own tsc build without a dep on the pi packages (mirrors
|
|
28
28
|
// canvas-nav.ts / canvas-commands.ts).
|
|
29
29
|
import { execFile } from 'node:child_process';
|
|
30
|
+
import { surfaceTmuxStyleArgs } from '../core/runtime/surface-bg.js';
|
|
30
31
|
/** Single-quote a string for safe interpolation into a `sh -c` command line —
|
|
31
32
|
* tmux runs the display-popup trailing string through the shell, so a cwd with
|
|
32
33
|
* spaces or quotes must be escaped. */
|
|
@@ -66,7 +67,7 @@ export function registerCanvasResume(pi) {
|
|
|
66
67
|
const cwd = shellQuote(process.cwd());
|
|
67
68
|
const cmd = `crtr canvas browse --return-pane ${origPane} --cwd ${cwd}`;
|
|
68
69
|
try {
|
|
69
|
-
execFile('tmux', ['display-popup', '-E', '-w', '90%', '-h', '85%', cmd], () => { });
|
|
70
|
+
execFile('tmux', ['display-popup', '-E', '-w', '90%', '-h', '85%', ...surfaceTmuxStyleArgs(), cmd], () => { });
|
|
70
71
|
}
|
|
71
72
|
catch { /* best-effort */ }
|
|
72
73
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type PiEvents = 'agent_start' | 'turn_end' | 'agent_end' | 'session_shutdown' | 'session_start';
|
|
1
|
+
type PiEvents = 'agent_start' | 'turn_end' | 'agent_end' | 'session_shutdown' | 'session_start' | 'tool_execution_start';
|
|
2
2
|
interface PiLike {
|
|
3
3
|
on: (event: PiEvents, handler: (event: any, ctx: any) => void | Promise<void>) => void;
|
|
4
4
|
sendUserMessage: (content: string, options?: {
|
|
@@ -6,20 +6,22 @@ interface PiLike {
|
|
|
6
6
|
}) => void;
|
|
7
7
|
}
|
|
8
8
|
/** The nudge text for a crossed band, specialized to the node's (mode,
|
|
9
|
-
* lifecycle) persona + how far along the escalation it is.
|
|
9
|
+
* lifecycle) persona + how far along the escalation it is. `crtr node yield` is
|
|
10
|
+
* the single "keep going past this window" verb for every persona: it refreshes
|
|
11
|
+
* the node into a clean window against a roadmap, and for a base node
|
|
12
|
+
* auto-promotes transparently — so no persona is ever steered at a bare `node
|
|
13
|
+
* promote` (which framed promotion as a heavy "become an orchestrator" step and
|
|
14
|
+
* bred yield-avoidance).
|
|
10
15
|
*
|
|
11
|
-
* - orchestrator (terminal OR resident): checkpoint
|
|
12
|
-
* (
|
|
13
|
-
* - resident/base (root conversation):
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* - terminal/base (worker): PROMOTE itself — become an orchestrator — when
|
|
18
|
-
* work remains, with an "ignore if nearly done, finish with push final" once
|
|
19
|
-
* it's deeper in.
|
|
16
|
+
* - orchestrator (terminal OR resident): checkpoint context/roadmap.md, then
|
|
17
|
+
* yield (it already has a roadmap to bring current first).
|
|
18
|
+
* - resident/base (root conversation): yield to continue in a fresh window if
|
|
19
|
+
* the chat is growing into a job, else wrap up — a root can simply end.
|
|
20
|
+
* - terminal/base (worker): yield to continue if work remains, or `push final`
|
|
21
|
+
* when close.
|
|
20
22
|
*
|
|
21
|
-
*
|
|
22
|
-
* drifting further risks an overflow. */
|
|
23
|
+
* The wording strengthens with depth: gentle < 150k → firm < 185k → pushy at/
|
|
24
|
+
* past 185k, where drifting further risks an overflow. */
|
|
23
25
|
export declare function steerNote(at: number, lifecycle: string, mode: string): string;
|
|
24
26
|
/**
|
|
25
27
|
* Register the canvas turn_end / agent_end handlers on `pi`.
|