@north-light/crouter 0.3.170 → 0.3.172
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/api/client.d.ts +37 -11
- package/dist/api/client.js +84 -15
- package/dist/api/dto/human.d.ts +53 -39
- package/dist/api/dto/human.js +2 -3
- package/dist/api/dto/inbox.d.ts +0 -1
- package/dist/api/dto/nodes.d.ts +12 -0
- package/dist/api/dto/review-comments.d.ts +137 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +109 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/routes.d.ts +17 -4
- package/dist/api/routes.js +21 -5
- package/dist/build-root.d.ts +1 -16
- package/dist/build-root.js +1 -25
- package/dist/builtin-memory/00-runtime-base.md +7 -5
- package/dist/builtin-memory/04-base-worker.md +1 -1
- package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
- package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
- package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
- package/dist/builtin-memory/design.md +2 -2
- package/dist/builtin-memory/insights/capture.md +50 -0
- package/dist/builtin-memory/insights/init.md +45 -0
- package/dist/builtin-memory/insights/listen.md +9 -0
- package/dist/builtin-memory/internal/agent-shaping.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +12 -11
- package/dist/builtin-memory/internal/storage-tiers.md +2 -2
- package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
- package/dist/builtin-memory/plan.md +19 -0
- package/dist/builtin-memory/spec/guide.md +38 -0
- package/dist/builtin-memory/spec/requirements.md +31 -0
- package/dist/builtin-memory/spec/roadmap.md +35 -0
- package/dist/builtin-memory/spec.md +10 -86
- package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
- package/dist/cli.js +2 -6
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
- package/dist/clients/attach/__tests__/context-message.test.js +142 -6
- package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
- package/dist/clients/attach/__tests__/diagram.test.js +1 -1
- package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
- package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
- package/dist/clients/attach/chrome/header.d.ts +10 -0
- package/dist/clients/attach/chrome/header.js +30 -0
- package/dist/clients/attach/chrome/recap.d.ts +7 -0
- package/dist/clients/attach/chrome/recap.js +19 -0
- package/dist/clients/attach/chrome/status-line.d.ts +3 -0
- package/dist/clients/attach/chrome/status-line.js +5 -0
- package/dist/clients/attach/chrome/widgets.js +11 -21
- package/dist/clients/attach/command.js +11 -7
- package/dist/clients/attach/config.d.ts +4 -0
- package/dist/clients/attach/config.js +3 -0
- package/dist/clients/attach/input/controller.d.ts +19 -0
- package/dist/clients/attach/input/controller.js +62 -28
- package/dist/clients/attach/input/titled-editor.d.ts +0 -4
- package/dist/clients/attach/input/titled-editor.js +2 -10
- package/dist/clients/attach/overlays/file-review.d.ts +9 -5
- package/dist/clients/attach/overlays/file-review.js +9 -70
- package/dist/clients/attach/overlays/help.d.ts +33 -0
- package/dist/clients/attach/overlays/help.js +204 -0
- package/dist/clients/attach/render/activity-slot.d.ts +4 -0
- package/dist/clients/attach/render/activity-slot.js +13 -0
- package/dist/clients/attach/render/chat-view.d.ts +117 -12
- package/dist/clients/attach/render/chat-view.js +604 -135
- package/dist/clients/attach/render/context-message.d.ts +2 -1
- package/dist/clients/attach/render/context-message.js +17 -13
- package/dist/clients/attach/render/crtr-output.js +1 -3
- package/dist/clients/attach/render/diagram.js +2 -2
- package/dist/clients/attach/render/edit-diff.d.ts +4 -1
- package/dist/clients/attach/render/edit-diff.js +7 -11
- package/dist/clients/attach/render/group-activity.d.ts +32 -0
- package/dist/clients/attach/render/group-activity.js +206 -0
- package/dist/clients/attach/render/group-recap.d.ts +10 -0
- package/dist/clients/attach/render/group-recap.js +93 -0
- package/dist/clients/attach/render/html-markdown.d.ts +17 -0
- package/dist/clients/attach/render/html-markdown.js +228 -0
- package/dist/clients/attach/render/measured-container.d.ts +96 -0
- package/dist/clients/attach/render/measured-container.js +322 -0
- package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
- package/dist/clients/attach/render/scroll-animation.js +80 -0
- package/dist/clients/attach/render/tool-calls.js +6 -6
- package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
- package/dist/clients/attach/render/transcript-copy.js +81 -0
- package/dist/clients/attach/render/viewport.d.ts +29 -0
- package/dist/clients/attach/render/viewport.js +159 -0
- package/dist/clients/attach/session/bindings.d.ts +10 -7
- package/dist/clients/attach/session/bindings.js +23 -8
- package/dist/clients/attach/session/connection.js +4 -5
- package/dist/clients/attach/session/context.d.ts +6 -4
- package/dist/clients/attach/session/frame.d.ts +34 -0
- package/dist/clients/attach/session/frame.js +176 -0
- package/dist/clients/attach/session/frames.d.ts +4 -1
- package/dist/clients/attach/session/frames.js +14 -1
- package/dist/clients/attach/session/identity.js +4 -3
- package/dist/clients/attach/session/input-wiring.d.ts +14 -4
- package/dist/clients/attach/session/input-wiring.js +15 -13
- package/dist/clients/attach/session/invariant.d.ts +9 -0
- package/dist/clients/attach/session/invariant.js +15 -0
- package/dist/clients/attach/session/keys.d.ts +10 -2
- package/dist/clients/attach/session/keys.js +13 -5
- package/dist/clients/attach/session/layout.d.ts +10 -8
- package/dist/clients/attach/session/layout.js +33 -34
- package/dist/clients/attach/session/mouse.d.ts +18 -0
- package/dist/clients/attach/session/mouse.js +64 -0
- package/dist/clients/attach/session/pane-tag.d.ts +3 -0
- package/dist/clients/attach/session/pane-tag.js +51 -8
- package/dist/clients/attach/session/reconnect.d.ts +3 -0
- package/dist/clients/attach/session/reconnect.js +42 -5
- package/dist/clients/attach/session/surface-frame.d.ts +20 -0
- package/dist/clients/attach/session/surface-frame.js +73 -0
- package/dist/clients/attach/session/surface-host.d.ts +64 -0
- package/dist/clients/attach/session/surface-host.js +255 -0
- package/dist/clients/attach/session/whip.d.ts +17 -0
- package/dist/clients/attach/session/whip.js +334 -0
- package/dist/clients/attach/slash/dispatch.d.ts +13 -1
- package/dist/clients/attach/slash/dispatch.js +51 -29
- package/dist/clients/attach/viewer.js +907 -819
- package/dist/clients/conversation/conversation.d.ts +65 -0
- package/dist/clients/conversation/conversation.js +318 -0
- package/dist/clients/conversation/frames.d.ts +30 -0
- package/dist/clients/conversation/frames.js +52 -0
- package/dist/clients/conversation/region.d.ts +51 -0
- package/dist/clients/conversation/region.js +265 -0
- package/dist/clients/conversation/submit.d.ts +38 -0
- package/dist/clients/conversation/submit.js +51 -0
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
- package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
- package/dist/clients/inbox/controller.d.ts +79 -0
- package/dist/clients/inbox/controller.js +448 -0
- package/dist/clients/inbox/deck-adapter.d.ts +29 -0
- package/dist/clients/inbox/deck-adapter.js +62 -0
- package/dist/clients/inbox/layout.d.ts +8 -0
- package/dist/clients/inbox/layout.js +9 -0
- package/dist/clients/inbox/resolve.d.ts +10 -0
- package/dist/clients/inbox/resolve.js +34 -0
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
- package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
- package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
- package/dist/clients/inbox/review/anchors.d.ts +41 -0
- package/dist/clients/inbox/review/anchors.js +89 -0
- package/dist/clients/inbox/review/columns.d.ts +22 -0
- package/dist/clients/inbox/review/columns.js +40 -0
- package/dist/clients/inbox/review/comments-client.d.ts +66 -0
- package/dist/clients/inbox/review/comments-client.js +98 -0
- package/dist/clients/inbox/review/composition.d.ts +60 -0
- package/dist/clients/inbox/review/composition.js +278 -0
- package/dist/clients/inbox/review/document-region.d.ts +120 -0
- package/dist/clients/inbox/review/document-region.js +902 -0
- package/dist/clients/inbox/review/frame.d.ts +45 -0
- package/dist/clients/inbox/review/frame.js +215 -0
- package/dist/clients/inbox/review/keys.d.ts +67 -0
- package/dist/clients/inbox/review/keys.js +130 -0
- package/dist/clients/inbox/review/launch.d.ts +10 -0
- package/dist/clients/inbox/review/launch.js +129 -0
- package/dist/clients/inbox/review/live-source.d.ts +24 -0
- package/dist/clients/inbox/review/live-source.js +160 -0
- package/dist/clients/inbox/review/nvim.d.ts +13 -0
- package/dist/clients/inbox/review/nvim.js +42 -0
- package/dist/clients/inbox/review/remap.d.ts +51 -0
- package/dist/clients/inbox/review/remap.js +157 -0
- package/dist/clients/inbox/review/review-client.d.ts +30 -0
- package/dist/clients/inbox/review/review-client.js +107 -0
- package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
- package/dist/clients/inbox/review/roundtrip.js +36 -0
- package/dist/clients/inbox/review/state.d.ts +143 -0
- package/dist/clients/inbox/review/state.js +282 -0
- package/dist/clients/inbox/review-adapter.d.ts +29 -0
- package/dist/clients/inbox/review-adapter.js +92 -0
- package/dist/clients/inbox/review-visibility.d.ts +5 -0
- package/dist/clients/inbox/review-visibility.js +19 -0
- package/dist/clients/inbox/surface.d.ts +19 -0
- package/dist/clients/inbox/surface.js +128 -0
- package/dist/clients/inbox/tui/ansi.d.ts +66 -0
- package/dist/clients/inbox/tui/ansi.js +317 -0
- package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
- package/dist/clients/inbox/tui/clipboard.js +26 -0
- package/dist/clients/inbox/tui/input.d.ts +7 -0
- package/dist/clients/inbox/tui/input.js +653 -0
- package/dist/clients/inbox/tui/keys.d.ts +28 -0
- package/dist/clients/inbox/tui/keys.js +111 -0
- package/dist/clients/inbox/tui/panel.d.ts +2 -0
- package/dist/clients/inbox/tui/panel.js +217 -0
- package/dist/clients/inbox/tui/render.d.ts +37 -0
- package/dist/clients/inbox/tui/render.js +476 -0
- package/dist/clients/inbox/tui/types.d.ts +57 -0
- package/dist/clients/inbox/tui/types.js +1 -0
- package/dist/clients/inbox/tui.d.ts +6 -0
- package/dist/clients/inbox/tui.js +74 -0
- package/dist/clients/surfaces/host.d.ts +66 -0
- package/dist/clients/surfaces/host.js +1 -0
- package/dist/clients/surfaces/region.d.ts +16 -0
- package/dist/clients/surfaces/region.js +1 -0
- package/dist/clients/web/__tests__/push-engine.test.js +14 -158
- package/dist/clients/web/dev-server.d.ts +3 -3
- package/dist/clients/web/dev-server.js +9 -23
- package/dist/clients/web/events.js +4 -6
- package/dist/clients/web/push-engine.d.ts +2 -66
- package/dist/clients/web/push-engine.js +30 -161
- package/dist/clients/web/push-registry.d.ts +0 -4
- package/dist/clients/web/push-registry.js +2 -7
- package/dist/clients/web/server.js +3 -35
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
- package/dist/clients/web/web-cmd.js +2 -2
- package/dist/commands/__tests__/human.test.js +27 -15
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/canvas-browse.js +1 -1
- package/dist/commands/canvas-issue.js +1 -1
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human/doc.d.ts +2 -0
- package/dist/commands/human/doc.js +98 -0
- package/dist/commands/human/inbox.d.ts +2 -0
- package/dist/commands/human/inbox.js +101 -0
- package/dist/commands/human/prompts.d.ts +2 -3
- package/dist/commands/human/prompts.js +27 -180
- package/dist/commands/human/queue.d.ts +1 -5
- package/dist/commands/human/queue.js +54 -216
- package/dist/commands/human/review.d.ts +2 -0
- package/dist/commands/human/review.js +298 -0
- package/dist/commands/human/shared.d.ts +2 -69
- package/dist/commands/human/shared.js +1 -181
- package/dist/commands/human.js +15 -20
- package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
- package/dist/commands/memory/__tests__/lint.test.js +15 -0
- package/dist/commands/memory/delete.js +2 -2
- package/dist/commands/memory/lint.d.ts +1 -0
- package/dist/commands/memory/lint.js +21 -3
- package/dist/commands/memory/read.js +4 -4
- package/dist/commands/node.js +8 -7
- package/dist/commands/pkg/plugin-manage.js +143 -68
- package/dist/commands/surface-inspect.js +2 -2
- package/dist/commands/surface.js +6 -12
- package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
- package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
- package/dist/commands/sys/config.js +29 -3
- package/dist/commands/sys/feedback.js +1 -1
- package/dist/commands/sys/setup-core.d.ts +12 -11
- package/dist/commands/sys/setup-core.js +55 -46
- package/dist/commands/sys/setup-wizard.d.ts +4 -1
- package/dist/commands/sys/setup-wizard.js +50 -9
- package/dist/commands/sys/sync-deps.js +1 -1
- package/dist/commands/sys.js +4 -6
- package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
- package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
- package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
- package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
- package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
- package/dist/core/__tests__/full/detach-focus.test.js +1 -1
- package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
- package/dist/core/__tests__/human-deliver.test.js +71 -345
- package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
- package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
- package/dist/core/__tests__/migration.test.js +10 -0
- package/dist/core/__tests__/model-pin-durability.test.js +14 -0
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
- package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-store.test.js +143 -0
- package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
- package/dist/core/__tests__/revive.test.js +22 -53
- package/dist/core/__tests__/session-cycles.test.js +48 -18
- package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
- package/dist/core/__tests__/stop-guard.test.js +16 -1
- package/dist/core/__tests__/tmux-surface.test.js +21 -25
- package/dist/core/asset-root.d.ts +7 -0
- package/dist/core/asset-root.js +18 -0
- package/dist/core/broker-client/client.d.ts +0 -7
- package/dist/core/broker-client/client.js +4 -10
- package/dist/core/broker-client/transport-relay.d.ts +3 -4
- package/dist/core/broker-client/transport-relay.js +3 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
- package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
- package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
- package/dist/core/canvas/attention.js +4 -4
- package/dist/core/canvas/canvas.d.ts +6 -11
- package/dist/core/canvas/canvas.js +11 -33
- package/dist/core/canvas/db.js +207 -38
- package/dist/core/canvas/extensions.d.ts +1 -1
- package/dist/core/canvas/extensions.js +8 -1
- package/dist/core/canvas/index.d.ts +0 -1
- package/dist/core/canvas/index.js +0 -1
- package/dist/core/canvas/nav-model.d.ts +1 -1
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/paths.d.ts +5 -0
- package/dist/core/canvas/paths.js +16 -0
- package/dist/core/canvas/remote-canvas-source.js +2 -2
- package/dist/core/canvas/remote-transport.d.ts +7 -0
- package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/status-glyph.js +4 -12
- package/dist/core/canvas/types.d.ts +10 -35
- package/dist/core/clipboard-text.d.ts +8 -0
- package/dist/core/clipboard-text.js +18 -0
- package/dist/core/command-manifests/registry.d.ts +1 -3
- package/dist/core/command-plugins/bundle.d.ts +29 -0
- package/dist/core/command-plugins/bundle.js +198 -0
- package/dist/core/command-plugins/discovery.d.ts +0 -8
- package/dist/core/command-plugins/discovery.js +2 -39
- package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
- package/dist/core/command-plugins/transport/http-fetch.js +17 -95
- package/dist/core/command.d.ts +1 -13
- package/dist/core/command.js +1 -16
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +28 -3
- package/dist/core/document-lines.d.ts +4 -0
- package/dist/core/document-lines.js +6 -0
- package/dist/core/feed/feed.d.ts +2 -0
- package/dist/core/feed/feed.js +11 -7
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
- package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-core.test.js +144 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
- package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
- package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
- package/dist/core/human/claim.d.ts +23 -0
- package/dist/core/human/claim.js +67 -0
- package/dist/core/human/convention.d.ts +30 -0
- package/dist/core/human/convention.js +202 -0
- package/dist/core/human/deck-factories.d.ts +8 -0
- package/dist/core/human/deck-factories.js +15 -0
- package/dist/core/human/deck-schema.d.ts +70 -0
- package/dist/core/human/deck-schema.js +92 -0
- package/dist/core/human/root.d.ts +7 -0
- package/dist/core/human/root.js +37 -0
- package/dist/core/human/scan.d.ts +3 -0
- package/dist/core/human/scan.js +76 -0
- package/dist/core/human/summary.d.ts +8 -0
- package/dist/core/human/summary.js +44 -0
- package/dist/core/human/tickets.d.ts +49 -0
- package/dist/core/human/tickets.js +190 -0
- package/dist/core/human/types.d.ts +136 -0
- package/dist/core/human/types.js +5 -0
- package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
- package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
- package/dist/core/inspector/chrome.d.ts +6 -0
- package/dist/core/inspector/chrome.js +14 -0
- package/dist/core/inspector/contract.d.ts +105 -0
- package/dist/core/inspector/contract.js +1 -0
- package/dist/core/inspector/core.d.ts +4 -5
- package/dist/core/inspector/core.js +3 -5
- package/dist/core/inspector/host.d.ts +46 -0
- package/dist/core/{tui → inspector}/host.js +42 -208
- package/dist/core/inspector/text.d.ts +2 -2
- package/dist/core/inspector/transport.d.ts +6 -0
- package/dist/core/inspector/transport.js +36 -0
- package/dist/core/inspector/tui.d.ts +2 -2
- package/dist/core/inspector/tui.js +15 -15
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
- package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
- package/dist/core/keybindings/attach-control.d.ts +9 -3
- package/dist/core/keybindings/attach-control.js +3 -1
- package/dist/core/keybindings/catalog.d.ts +6 -5
- package/dist/core/keybindings/catalog.js +61 -133
- package/dist/core/keybindings/inbox.d.ts +5 -6
- package/dist/core/keybindings/inbox.js +9 -10
- package/dist/core/keybindings/index.d.ts +3 -3
- package/dist/core/keybindings/index.js +3 -3
- package/dist/core/keybindings/persistence.d.ts +5 -1
- package/dist/core/keybindings/persistence.js +24 -6
- package/dist/core/keybindings/resolve.d.ts +6 -0
- package/dist/core/keybindings/resolve.js +10 -3
- package/dist/core/memory/inline-ref-grammar.js +2 -3
- package/dist/core/memory-resolver.d.ts +27 -29
- package/dist/core/memory-resolver.js +45 -39
- package/dist/core/model-routes.d.ts +33 -0
- package/dist/core/model-routes.js +42 -3
- package/dist/core/preview-registry.js +17 -55
- package/dist/core/profiles/select.js +3 -3
- package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
- package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
- package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
- package/dist/core/review/__tests__/capture-origin.test.js +139 -0
- package/dist/core/review/__tests__/comments.test.d.ts +1 -0
- package/dist/core/review/__tests__/comments.test.js +98 -0
- package/dist/core/review/__tests__/project.test.d.ts +1 -0
- package/dist/core/review/__tests__/project.test.js +71 -0
- package/dist/core/review/__tests__/remap.test.d.ts +1 -0
- package/dist/core/review/__tests__/remap.test.js +159 -0
- package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
- package/dist/core/review/__tests__/stage-identity.test.js +140 -0
- package/dist/core/review/birth.d.ts +7 -0
- package/dist/core/review/birth.js +23 -0
- package/dist/core/review/comments.d.ts +69 -0
- package/dist/core/review/comments.js +295 -0
- package/dist/core/review/companion.d.ts +35 -0
- package/dist/core/review/companion.js +205 -0
- package/dist/core/review/document.d.ts +27 -0
- package/dist/core/review/document.js +138 -0
- package/dist/core/review/project.d.ts +13 -0
- package/dist/core/review/project.js +58 -0
- package/dist/core/review/realize.d.ts +19 -0
- package/dist/core/review/realize.js +217 -0
- package/dist/core/review/remap.d.ts +24 -0
- package/dist/core/review/remap.js +156 -0
- package/dist/core/review/signal.d.ts +5 -0
- package/dist/core/review/signal.js +31 -0
- package/dist/core/review/stage.d.ts +26 -0
- package/dist/core/review/stage.js +184 -0
- package/dist/core/review/store.d.ts +46 -0
- package/dist/core/review/store.js +163 -0
- package/dist/core/review/ticket-filter.d.ts +17 -0
- package/dist/core/review/ticket-filter.js +32 -0
- package/dist/core/review/types.d.ts +130 -0
- package/dist/core/review/types.js +23 -0
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
- package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
- package/dist/core/runtime/bearings.d.ts +5 -17
- package/dist/core/runtime/bearings.js +88 -71
- package/dist/core/runtime/broker-protocol.d.ts +31 -8
- package/dist/core/runtime/broker.d.ts +15 -1
- package/dist/core/runtime/broker.js +573 -141
- package/dist/core/runtime/canvas-extensions.d.ts +4 -5
- package/dist/core/runtime/canvas-extensions.js +5 -5
- package/dist/core/runtime/front-door.js +4 -4
- package/dist/core/runtime/headless-pi.d.ts +24 -0
- package/dist/core/runtime/headless-pi.js +152 -0
- package/dist/core/runtime/kickoff.d.ts +1 -5
- package/dist/core/runtime/kickoff.js +1 -5
- package/dist/core/runtime/model-registry.d.ts +3 -0
- package/dist/core/runtime/model-registry.js +13 -0
- package/dist/core/runtime/naming-persist.d.ts +4 -0
- package/dist/core/runtime/naming-persist.js +27 -1
- package/dist/core/runtime/naming.d.ts +17 -12
- package/dist/core/runtime/naming.js +91 -140
- package/dist/core/runtime/node-read.js +19 -10
- package/dist/core/runtime/nodes.d.ts +9 -14
- package/dist/core/runtime/nodes.js +3 -53
- package/dist/core/runtime/package-health.d.ts +6 -21
- package/dist/core/runtime/package-health.js +12 -123
- package/dist/core/runtime/placement-tmux.d.ts +2 -1
- package/dist/core/runtime/placement-tmux.js +6 -4
- package/dist/core/runtime/placement.d.ts +1 -0
- package/dist/core/runtime/placement.js +4 -8
- package/dist/core/runtime/promote.js +3 -0
- package/dist/core/runtime/recap.d.ts +2 -7
- package/dist/core/runtime/recap.js +35 -69
- package/dist/core/runtime/revive.js +34 -77
- package/dist/core/runtime/session-cycles.d.ts +4 -0
- package/dist/core/runtime/session-cycles.js +14 -1
- package/dist/core/runtime/session-visibility.d.ts +37 -0
- package/dist/core/runtime/session-visibility.js +83 -0
- package/dist/core/runtime/spawn.js +10 -22
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +18 -13
- package/dist/core/runtime/surface-bg.js +1 -1
- package/dist/core/runtime/tmux-chrome.d.ts +1 -1
- package/dist/core/runtime/tmux-chrome.js +1 -1
- package/dist/core/runtime/tmux.d.ts +35 -7
- package/dist/core/runtime/tmux.js +439 -62
- package/dist/core/runtime/tool-group-summary.d.ts +19 -0
- package/dist/core/runtime/tool-group-summary.js +88 -0
- package/dist/core/scope.d.ts +2 -7
- package/dist/core/scope.js +9 -35
- package/dist/core/substrate/schema.d.ts +2 -2
- package/dist/core/termrender/code-doc.d.ts +12 -0
- package/dist/core/termrender/code-doc.js +92 -0
- package/dist/core/termrender/display.d.ts +12 -0
- package/dist/core/termrender/display.js +19 -0
- package/dist/core/termrender/termrender.d.ts +73 -0
- package/dist/core/termrender/termrender.js +795 -0
- package/dist/core/termrender/version.d.ts +1 -0
- package/dist/core/termrender/version.js +1 -0
- package/dist/core/tui/terminal.js +1 -2
- package/dist/core/user-settings.d.ts +71 -3
- package/dist/core/user-settings.js +83 -1
- package/dist/daemon/api/__tests__/inbox.test.js +44 -133
- package/dist/daemon/api/handlers/human.d.ts +0 -10
- package/dist/daemon/api/handlers/human.js +104 -702
- package/dist/daemon/api/handlers/inbox.js +113 -142
- package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
- package/dist/daemon/api/handlers/review-comments.js +500 -0
- package/dist/daemon/api/handlers/reviews.d.ts +2 -0
- package/dist/daemon/api/handlers/reviews.js +287 -0
- package/dist/daemon/api/map.d.ts +22 -7
- package/dist/daemon/api/map.js +159 -11
- package/dist/daemon/api/server.js +4 -0
- package/dist/daemon/cron-run.js +6 -9
- package/dist/daemon/crtrd.js +17 -33
- package/dist/daemon/fleet.d.ts +1 -8
- package/dist/daemon/fleet.js +4 -30
- package/dist/daemon/human/finish.d.ts +14 -0
- package/dist/daemon/human/finish.js +115 -0
- package/dist/daemon/human/sweep.d.ts +6 -0
- package/dist/daemon/human/sweep.js +49 -0
- package/dist/daemon/messaging/node-message.d.ts +18 -0
- package/dist/daemon/messaging/node-message.js +70 -0
- package/dist/daemon/review/comment-notify.d.ts +26 -0
- package/dist/daemon/review/comment-notify.js +107 -0
- package/dist/daemon/review/deliver.d.ts +7 -0
- package/dist/daemon/review/deliver.js +56 -0
- package/dist/daemon/review/finish.d.ts +22 -0
- package/dist/daemon/review/finish.js +254 -0
- package/dist/daemon/review/sweep.d.ts +11 -0
- package/dist/daemon/review/sweep.js +120 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
- package/dist/pi-extensions/canvas-context-intro.js +50 -104
- package/dist/pi-extensions/canvas-recap.d.ts +15 -2
- package/dist/pi-extensions/canvas-recap.js +192 -69
- package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
- package/dist/pi-extensions/canvas-review-boundary.js +81 -0
- package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
- package/dist/pi-extensions/canvas-stophook.js +78 -128
- package/dist/pi-extensions/canvas-structured-output.js +52 -8
- package/dist/shared/generated-context.d.ts +29 -4
- package/dist/shared/generated-context.js +122 -7
- package/dist/shared/tool-groups.d.ts +23 -0
- package/dist/shared/tool-groups.js +60 -0
- package/dist/shared/working-activity.d.ts +8 -0
- package/dist/shared/working-activity.js +26 -0
- package/dist/types.d.ts +36 -2
- package/dist/types.js +51 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
- package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
- package/dist/web-client/index.html +2 -2
- package/dist/web-client/sw.js +1 -1
- package/docs/compat/hearth-crtr-v4.md +2 -2
- package/docs/compat/hearth-crtr-v5.md +4 -2
- package/docs/public-api.md +3 -3
- package/package.json +21 -14
- package/runtime.lock.json +4661 -1453
- package/scripts/postinstall.mjs +15 -2
- package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
- package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
- package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
- package/dist/builtin-views/_lib/states.mjs +0 -161
- package/dist/builtin-views/canvas/core.mjs +0 -657
- package/dist/builtin-views/canvas/text.mjs +0 -58
- package/dist/builtin-views/canvas/tui.mjs +0 -168
- package/dist/builtin-views/canvas/web.jsx +0 -121
- package/dist/builtin-views/chat/core.mjs +0 -684
- package/dist/builtin-views/chat/text.mjs +0 -101
- package/dist/builtin-views/chat/tui.mjs +0 -360
- package/dist/builtin-views/chat/web.jsx +0 -362
- package/dist/builtin-views/git-pr/core.mjs +0 -673
- package/dist/builtin-views/git-pr/text.mjs +0 -84
- package/dist/builtin-views/git-pr/tui.mjs +0 -301
- package/dist/builtin-views/git-pr/web.jsx +0 -216
- package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
- package/dist/builtin-views/inbox/core.mjs +0 -1273
- package/dist/builtin-views/inbox/text.mjs +0 -73
- package/dist/builtin-views/inbox/tui.mjs +0 -314
- package/dist/builtin-views/inbox/web.jsx +0 -188
- package/dist/builtin-views/linkedin/core.mjs +0 -906
- package/dist/builtin-views/linkedin/text.mjs +0 -69
- package/dist/builtin-views/linkedin/tui.mjs +0 -413
- package/dist/builtin-views/linkedin/web.jsx +0 -206
- package/dist/builtin-views/prompt-review/core.mjs +0 -735
- package/dist/builtin-views/prompt-review/text.mjs +0 -15
- package/dist/builtin-views/prompt-review/tui.mjs +0 -196
- package/dist/builtin-views/prompt-review/web.jsx +0 -484
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
- package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
- package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
- package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
- package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
- package/dist/clients/attach/session/mode.d.ts +0 -25
- package/dist/clients/attach/session/mode.js +0 -97
- package/dist/commands/sys/promptstudio.d.ts +0 -2
- package/dist/commands/sys/promptstudio.js +0 -65
- package/dist/commands/view-cycle.d.ts +0 -2
- package/dist/commands/view-cycle.js +0 -130
- package/dist/commands/view-list.d.ts +0 -2
- package/dist/commands/view-list.js +0 -66
- package/dist/commands/view-new.d.ts +0 -2
- package/dist/commands/view-new.js +0 -74
- package/dist/commands/view-pick.d.ts +0 -6
- package/dist/commands/view-pick.js +0 -129
- package/dist/commands/view-run.d.ts +0 -2
- package/dist/commands/view-run.js +0 -214
- package/dist/commands/view.d.ts +0 -2
- package/dist/commands/view.js +0 -31
- package/dist/commands/workspace.d.ts +0 -2
- package/dist/commands/workspace.js +0 -165
- package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
- package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
- package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
- package/dist/core/canvas/human-work-outbox.d.ts +0 -73
- package/dist/core/canvas/human-work-outbox.js +0 -261
- package/dist/core/command-plugins/store.d.ts +0 -16
- package/dist/core/command-plugins/store.js +0 -64
- package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
- package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
- package/dist/core/runtime/fault-recovery-nudge.js +0 -3
- package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
- package/dist/core/tui/host.d.ts +0 -66
- package/dist/core/view/__tests__/transport-cache.test.js +0 -62
- package/dist/core/view/bridge.d.ts +0 -10
- package/dist/core/view/bridge.js +0 -31
- package/dist/core/view/chrome.d.ts +0 -9
- package/dist/core/view/chrome.js +0 -22
- package/dist/core/view/contract.d.ts +0 -205
- package/dist/core/view/contract.js +0 -23
- package/dist/core/view/loader.d.ts +0 -31
- package/dist/core/view/loader.js +0 -188
- package/dist/core/view/stream-local.d.ts +0 -3
- package/dist/core/view/stream-local.js +0 -231
- package/dist/core/view/transport-cache.d.ts +0 -8
- package/dist/core/view/transport-cache.js +0 -38
- package/dist/core/view/transport-local.d.ts +0 -7
- package/dist/core/view/transport-local.js +0 -83
- package/dist/core/view/transport-remote.d.ts +0 -2
- package/dist/core/view/transport.d.ts +0 -10
- package/dist/core/view/transport.js +0 -15
- package/dist/pi-extensions/naming-tool.d.ts +0 -24
- package/dist/pi-extensions/naming-tool.js +0 -67
- package/dist/prompts/view.d.ts +0 -7
- package/dist/prompts/view.js +0 -172
- package/dist/web/ViewChrome.d.ts +0 -7
- package/dist/web/ViewChrome.js +0 -28
- package/dist/web/ViewPane.d.ts +0 -39
- package/dist/web/ViewPane.js +0 -48
- package/dist/web/index.d.ts +0 -8
- package/dist/web/index.js +0 -22
- package/dist/web/runtime.d.ts +0 -39
- package/dist/web/runtime.js +0 -232
- package/dist/web/states.d.ts +0 -24
- package/dist/web/states.js +0 -24
- package/dist/web/transport-http.d.ts +0 -5
- package/dist/web/transport-http.js +0 -34
- package/dist/web/transport-stream.d.ts +0 -3
- package/dist/web/transport-stream.js +0 -204
- package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
- package/dist/web-client/assets/index-aaeu4adv.css +0 -2
- /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
- /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
- /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
- /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
- /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
interface SessionEntryLike {
|
|
2
|
+
type: string;
|
|
3
|
+
customType?: string;
|
|
4
|
+
details?: {
|
|
5
|
+
reviewId?: string;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
interface SessionStartCtxLike {
|
|
9
|
+
sessionManager: {
|
|
10
|
+
getEntries: () => SessionEntryLike[];
|
|
11
|
+
getBranch?: (fromId?: string) => SessionEntryLike[];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface CustomMessageLike {
|
|
15
|
+
customType: string;
|
|
16
|
+
content: string;
|
|
17
|
+
display?: boolean;
|
|
18
|
+
details?: {
|
|
19
|
+
reviewId: string;
|
|
20
|
+
originNodeId: string;
|
|
21
|
+
targetFile: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
interface RenderedMessageLike {
|
|
25
|
+
customType: string;
|
|
26
|
+
content: string | Array<{
|
|
27
|
+
type: string;
|
|
28
|
+
text?: string;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
interface ComponentLike {
|
|
32
|
+
render: (width: number) => string[];
|
|
33
|
+
invalidate: () => void;
|
|
34
|
+
}
|
|
35
|
+
interface ThemeLike {
|
|
36
|
+
fg?: (color: string, text: string) => string;
|
|
37
|
+
}
|
|
38
|
+
interface PiLike {
|
|
39
|
+
on: (event: 'session_start', handler: (event: unknown, ctx: SessionStartCtxLike) => void | Promise<void>) => void;
|
|
40
|
+
sendMessage: (message: CustomMessageLike, options?: {
|
|
41
|
+
deliverAs?: string;
|
|
42
|
+
triggerTurn?: boolean;
|
|
43
|
+
}) => void;
|
|
44
|
+
registerMessageRenderer: (customType: string, renderer: (message: RenderedMessageLike, options: {
|
|
45
|
+
expanded?: boolean;
|
|
46
|
+
}, theme: ThemeLike) => ComponentLike | undefined) => void;
|
|
47
|
+
}
|
|
48
|
+
/** Render the marker as a single compact divider; its full content remains in
|
|
49
|
+
* the message list for the model and generated-context presenters. */
|
|
50
|
+
export declare function renderReviewBoundary(_message: RenderedMessageLike, _options: {
|
|
51
|
+
expanded?: boolean;
|
|
52
|
+
}, theme: ThemeLike): ComponentLike;
|
|
53
|
+
/**
|
|
54
|
+
* Register the review boundary marker. Companion nodes receive one boundary
|
|
55
|
+
* marker on session_start that separates inherited context from the visible
|
|
56
|
+
* transcript. Ordinary nodes get nothing.
|
|
57
|
+
*/
|
|
58
|
+
export declare function registerCanvasReviewBoundary(pi: PiLike): void;
|
|
59
|
+
export default registerCanvasReviewBoundary;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// canvas-review-boundary.ts — durable visible-transcript boundary for review companions.
|
|
2
|
+
//
|
|
3
|
+
// On session_start, a review companion appends one custom_message after its
|
|
4
|
+
// inherited fork context and before canvas-context-intro appends fork bearings.
|
|
5
|
+
// The display projection starts at this marker while the model keeps the full
|
|
6
|
+
// inherited context.
|
|
7
|
+
import { getNode } from '../core/canvas/index.js';
|
|
8
|
+
import { isReviewBoundary, REVIEW_BOUNDARY_CUSTOM_TYPE } from '../core/runtime/session-visibility.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Collapsed-by-default rendering
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/** Truncate plain text to at most `width` columns, appending an ellipsis when it
|
|
13
|
+
* would overflow. Content here is ANSI-free plain text, so code-point count
|
|
14
|
+
* stands in for visible width. The renderer MUST keep every emitted line within
|
|
15
|
+
* the terminal width or pi's TUI aborts the whole render. */
|
|
16
|
+
function truncateToWidth(text, width) {
|
|
17
|
+
if (width <= 0)
|
|
18
|
+
return '';
|
|
19
|
+
const chars = Array.from(text);
|
|
20
|
+
if (chars.length <= width)
|
|
21
|
+
return text;
|
|
22
|
+
if (width === 1)
|
|
23
|
+
return '…';
|
|
24
|
+
return chars.slice(0, width - 1).join('') + '…';
|
|
25
|
+
}
|
|
26
|
+
/** Render the marker as a single compact divider; its full content remains in
|
|
27
|
+
* the message list for the model and generated-context presenters. */
|
|
28
|
+
export function renderReviewBoundary(_message, _options, theme) {
|
|
29
|
+
const paint = (color, text) => typeof theme?.fg === 'function' ? theme.fg(color, text) : text;
|
|
30
|
+
return {
|
|
31
|
+
render(width) {
|
|
32
|
+
const w = typeof width === 'number' && width > 0 ? width : 80;
|
|
33
|
+
return [paint('dim', truncateToWidth('[review boundary] earlier conversation is not shown', w))];
|
|
34
|
+
},
|
|
35
|
+
invalidate() {
|
|
36
|
+
/* stateless — nothing to clear */
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Extension
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Register the review boundary marker. Companion nodes receive one boundary
|
|
45
|
+
* marker on session_start that separates inherited context from the visible
|
|
46
|
+
* transcript. Ordinary nodes get nothing.
|
|
47
|
+
*/
|
|
48
|
+
export function registerCanvasReviewBoundary(pi) {
|
|
49
|
+
pi.registerMessageRenderer(REVIEW_BOUNDARY_CUSTOM_TYPE, renderReviewBoundary);
|
|
50
|
+
pi.on('session_start', (_event, ctx) => {
|
|
51
|
+
const nodeId = process.env['CRTR_NODE_ID'];
|
|
52
|
+
if (!nodeId || nodeId.trim() === '')
|
|
53
|
+
return;
|
|
54
|
+
const node = getNode(nodeId);
|
|
55
|
+
if (node?.review_binding == null)
|
|
56
|
+
return;
|
|
57
|
+
// The active branch, not the whole session file, is the context the next
|
|
58
|
+
// turn sees. Check for an existing boundary marker on this branch.
|
|
59
|
+
const scan = typeof ctx.sessionManager.getBranch === 'function'
|
|
60
|
+
? ctx.sessionManager.getBranch()
|
|
61
|
+
: ctx.sessionManager.getEntries();
|
|
62
|
+
const alreadyMarked = scan.some((entry) => isReviewBoundary(entry, node.review_binding?.review_id));
|
|
63
|
+
if (alreadyMarked)
|
|
64
|
+
return;
|
|
65
|
+
const { review_id: reviewId, origin_node_id: originNodeId, target_file: targetFile, } = node.review_binding;
|
|
66
|
+
const content = [
|
|
67
|
+
`Reviewed file: ${targetFile}`,
|
|
68
|
+
`Review ID: ${reviewId}`,
|
|
69
|
+
`Origin node: ${originNodeId}`,
|
|
70
|
+
'',
|
|
71
|
+
"The person's visible transcript starts here. Everything above this marker is inherited context they have not seen.",
|
|
72
|
+
].join('\n');
|
|
73
|
+
pi.sendMessage({
|
|
74
|
+
customType: REVIEW_BOUNDARY_CUSTOM_TYPE,
|
|
75
|
+
content,
|
|
76
|
+
display: true,
|
|
77
|
+
details: { reviewId, originNodeId, targetFile },
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
export default registerCanvasReviewBoundary;
|
|
@@ -26,9 +26,9 @@ interface PiLike {
|
|
|
26
26
|
* the single "keep going past this window" verb for every persona: it refreshes
|
|
27
27
|
* the node into a clean window, MODE-PRESERVING — a base node stays base,
|
|
28
28
|
* continuing fresh against its goal and its note. `--promote` is a separate,
|
|
29
|
-
* explicit opt-in (never steered here as auto-behavior) for when
|
|
30
|
-
*
|
|
31
|
-
* is ever steered at a bare `node promote` (which framed promotion as a heavy
|
|
29
|
+
* explicit opt-in (never steered here as auto-behavior) for when worthwhile
|
|
30
|
+
* independent work can run in parallel and coordination should become the
|
|
31
|
+
* node's primary job — so no persona is ever steered at a bare `node promote` (which framed promotion as a heavy
|
|
32
32
|
* "become an orchestrator" step and bred yield-avoidance).
|
|
33
33
|
*
|
|
34
34
|
* - orchestrator (terminal OR resident): checkpoint context/roadmap.md, then
|
|
@@ -21,17 +21,16 @@
|
|
|
21
21
|
// (c) Natural stop ('stop' | 'length') — run the stop-guard (the node is
|
|
22
22
|
// NEVER auto-pushed; it reports only via its own explicit `crtr push`):
|
|
23
23
|
// • 'reprompt' → pi.sendUserMessage so the node finishes or escalates.
|
|
24
|
-
// • 'allow' (awaiting) →
|
|
25
|
-
//
|
|
26
|
-
//
|
|
24
|
+
// • 'allow' (awaiting) → stay dormant when focused; otherwise release
|
|
25
|
+
// and shut down. A subscribed node, controller, or
|
|
26
|
+
// background bash job delivers the inbox wake.
|
|
27
27
|
// • 'allow' (attended root) → stay alive, dormant; the human wakes it.
|
|
28
28
|
//
|
|
29
29
|
// Plain TS-with-types — no imports from @earendil-works/* so this compiles inside
|
|
30
30
|
// crouter's own tsc build without a dep on the pi packages.
|
|
31
31
|
import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
|
|
32
32
|
import { join } from 'node:path';
|
|
33
|
-
import {
|
|
34
|
-
import { getNode, jobDir, updateNode, recordPid, setPresence, dispatchFollowUpWork, dispatchVisualWork, getFollowUpWorkRow, getHumanWorkRow, reconcileFollowUpWork, reconcileVisualWork } from '../core/canvas/index.js';
|
|
33
|
+
import { getNode, jobDir, updateNode, recordPid, setPresence } from '../core/canvas/index.js';
|
|
35
34
|
import { transition } from '../core/runtime/lifecycle.js';
|
|
36
35
|
import { markBusy, clearBusy, touchBusy, isBusy } from '../core/runtime/busy.js';
|
|
37
36
|
import { clearFault, readFault } from '../core/runtime/fault.js';
|
|
@@ -44,7 +43,8 @@ import { clearStopSignals, consumeStopSignals } from '../core/runtime/stop-signa
|
|
|
44
43
|
import { cliClient } from '../commands/api-client.js';
|
|
45
44
|
import { focusOf, tearDownNode } from '../core/runtime/placement.js';
|
|
46
45
|
import { readCursor, readInboxSince } from '../core/feed/inbox.js';
|
|
47
|
-
import { CONTEXT_NUDGE_CUSTOM_TYPE, formatContextNudge } from '../shared/generated-context.js';
|
|
46
|
+
import { CONTEXT_NUDGE_CUSTOM_TYPE, formatContextNudge, formatPersonaTransition } from '../shared/generated-context.js';
|
|
47
|
+
import { isReviewBoundary } from '../core/runtime/session-visibility.js';
|
|
48
48
|
/** Universal upper bound for an unfocused broker parked without runnable work. */
|
|
49
49
|
export const UNATTENDED_PARK_MS = (() => {
|
|
50
50
|
const testOverride = process.env['CRTR_TEST_UNATTENDED_PARK_MS'];
|
|
@@ -134,8 +134,8 @@ function lastAssistantMessage(messages) {
|
|
|
134
134
|
// told to checkpoint one. `crtr node yield` is still its continue
|
|
135
135
|
// verb — mode-preserving, continuing fresh against its goal and its
|
|
136
136
|
// note — offered against wrap-up, since a root chat can simply end.
|
|
137
|
-
// `--promote` is mentioned only
|
|
138
|
-
//
|
|
137
|
+
// `--promote` is mentioned only when worthwhile independent work
|
|
138
|
+
// can run in parallel and coordination should become primary. Gentle → firm → pushy.
|
|
139
139
|
// terminal/base (a worker): steered to `crtr node yield` to continue in a
|
|
140
140
|
// fresh window, mode-preserving, when work remains, or `push final`
|
|
141
141
|
// when close. Gentle → firm → pushy.
|
|
@@ -145,7 +145,7 @@ function lastAssistantMessage(messages) {
|
|
|
145
145
|
// bred yield-avoidance. A plain yield is always mode-preserving — a base node's
|
|
146
146
|
// yield never auto-promotes, so the agent is never steered to decide about
|
|
147
147
|
// promotion at all; `--promote` is a separate opt-in mentioned only for
|
|
148
|
-
//
|
|
148
|
+
// worthwhile parallel work. Only a terminal node is ever told `push final` (a
|
|
149
149
|
// resident finishes by yielding or being closed); only an orchestrator already
|
|
150
150
|
// HAS a roadmap to checkpoint before it yields.
|
|
151
151
|
// ---------------------------------------------------------------------------
|
|
@@ -174,9 +174,9 @@ function steerBand(tokens) {
|
|
|
174
174
|
* the single "keep going past this window" verb for every persona: it refreshes
|
|
175
175
|
* the node into a clean window, MODE-PRESERVING — a base node stays base,
|
|
176
176
|
* continuing fresh against its goal and its note. `--promote` is a separate,
|
|
177
|
-
* explicit opt-in (never steered here as auto-behavior) for when
|
|
178
|
-
*
|
|
179
|
-
* is ever steered at a bare `node promote` (which framed promotion as a heavy
|
|
177
|
+
* explicit opt-in (never steered here as auto-behavior) for when worthwhile
|
|
178
|
+
* independent work can run in parallel and coordination should become the
|
|
179
|
+
* node's primary job — so no persona is ever steered at a bare `node promote` (which framed promotion as a heavy
|
|
180
180
|
* "become an orchestrator" step and bred yield-avoidance).
|
|
181
181
|
*
|
|
182
182
|
* - orchestrator (terminal OR resident): checkpoint context/roadmap.md, then
|
|
@@ -206,10 +206,10 @@ export function steerNote(at, lifecycle, mode) {
|
|
|
206
206
|
// resident/base — a root conversation, mode-preserving `crtr node yield` is
|
|
207
207
|
// the natural "carry this forward" verb: it refreshes into a clean window
|
|
208
208
|
// and continues fresh against your goal and your note — no "become
|
|
209
|
-
// something" decision.
|
|
210
|
-
//
|
|
211
|
-
// chat can simply end.
|
|
212
|
-
const grow = `If
|
|
209
|
+
// something" decision. Mention --promote only when worthwhile independent
|
|
210
|
+
// work can run in parallel and coordination should become primary. Offer
|
|
211
|
+
// wrap-up as the alternative — a root chat can simply end.
|
|
212
|
+
const grow = `If substantial work remains, \`crtr node yield\` to continue fresh against your goal and your note. Add --promote only when worthwhile independent work can run in parallel and coordinating it should become your primary job; \`crtr node yield -h\` has the boundary.`;
|
|
213
213
|
if (at < 150_000) {
|
|
214
214
|
return `Context ~${k}k and growing. ${grow} Otherwise no rush — wrap up when you reach a good stopping point.`;
|
|
215
215
|
}
|
|
@@ -221,8 +221,7 @@ export function steerNote(at, lifecycle, mode) {
|
|
|
221
221
|
// terminal/base — a worker. The natural "keep going past this window" verb is
|
|
222
222
|
// `crtr node yield`: it refreshes into a clean window, mode-preserving, and
|
|
223
223
|
// continues fresh against your goal and your note. --promote is a separate
|
|
224
|
-
// opt-in for
|
|
225
|
-
// only for became-multi-phase work, never steered as automatic. Steer it to
|
|
224
|
+
// opt-in for worthwhile parallel work, never steered as automatic. Steer it to
|
|
226
225
|
// yield-or-finish, never a bare promote.
|
|
227
226
|
if (at < 150_000) {
|
|
228
227
|
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 your goal and your note — no rush yet.`;
|
|
@@ -260,30 +259,13 @@ export function registerCanvasStophook(pi) {
|
|
|
260
259
|
// a tool_execution_start flush (activity-only) preserves the latest token figure.
|
|
261
260
|
let lastContext = null;
|
|
262
261
|
let lastActivity = null;
|
|
263
|
-
// If this node IS a follow-up consult fork, its ticket binding never changes,
|
|
264
|
-
// so resolve it once and reuse it to narrate live activity back into the
|
|
265
|
-
// waiting ticket. `undefined` = not yet looked up, `null` = not a consult.
|
|
266
|
-
let consultTicket;
|
|
267
|
-
function narrateToTicket(line) {
|
|
268
|
-
if (line === null || line === '')
|
|
269
|
-
return;
|
|
270
|
-
if (consultTicket === undefined) {
|
|
271
|
-
const row = getFollowUpWorkRow(String(nodeId));
|
|
272
|
-
consultTicket = row === null ? null : { root: row.root, dir: row.dir, requestId: row.request_id };
|
|
273
|
-
}
|
|
274
|
-
if (consultTicket === null)
|
|
275
|
-
return;
|
|
276
|
-
// humanloop itself gates on the request still being the running one, so a
|
|
277
|
-
// superseded or already-answered ticket silently ignores this.
|
|
278
|
-
publishFollowUpProgress(consultTicket.root, consultTicket.dir, { requestId: consultTicket.requestId, line });
|
|
279
|
-
}
|
|
280
262
|
// Context-size steering. As input context grows we nudge the node once per
|
|
281
263
|
// band on an escalating, persona-specific schedule (see steerBand/steerNote).
|
|
282
264
|
// The node's (lifecycle, mode) persona is read at fire time, since a terminal
|
|
283
265
|
// worker can promote mid-session: an orchestrator is steered to checkpoint
|
|
284
266
|
// its roadmap + yield; a resident base (root chat) to yield-or-wrap-up (or
|
|
285
|
-
// yield --promote only
|
|
286
|
-
// worker to yield-or-push-final.
|
|
267
|
+
// yield --promote only when worthwhile independent work can run in parallel);
|
|
268
|
+
// a terminal worker to yield-or-push-final.
|
|
287
269
|
const firedBands = new Set();
|
|
288
270
|
// Every broker enters this bounded-release path at session_start, including a
|
|
289
271
|
// boot-revived settled node that never produces another agent_settled event.
|
|
@@ -409,6 +391,30 @@ export function registerCanvasStophook(pi) {
|
|
|
409
391
|
// whereas a bare id is resolved cwd-relative and forks across projects.
|
|
410
392
|
const filed = ctx?.sessionManager?.getSessionFile?.();
|
|
411
393
|
const sessionFile = typeof filed === 'string' && filed !== '' ? filed : null;
|
|
394
|
+
const existing = getNode(nodeId);
|
|
395
|
+
const reviewId = existing?.review_binding?.review_id;
|
|
396
|
+
if (reviewId !== undefined) {
|
|
397
|
+
let hasBoundary = false;
|
|
398
|
+
try {
|
|
399
|
+
const manager = ctx?.sessionManager;
|
|
400
|
+
const entries = typeof manager?.getBranch === 'function'
|
|
401
|
+
? manager.getBranch()
|
|
402
|
+
: typeof manager?.getEntries === 'function'
|
|
403
|
+
? manager.getEntries()
|
|
404
|
+
: [];
|
|
405
|
+
hasBoundary = entries.some((entry) => isReviewBoundary(entry, reviewId));
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
hasBoundary = false;
|
|
409
|
+
}
|
|
410
|
+
if (!hasBoundary) {
|
|
411
|
+
try {
|
|
412
|
+
ctx?.shutdown?.();
|
|
413
|
+
}
|
|
414
|
+
catch { /* best-effort */ }
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
412
418
|
// `/new` — a brand-new conversation in the same process. The broker already
|
|
413
419
|
// drove the engine-side new_session (the viewer's /new → broker
|
|
414
420
|
// new_session frame); the runtime side then splits on root-ness: a ROOT
|
|
@@ -417,13 +423,12 @@ export function registerCanvasStophook(pi) {
|
|
|
417
423
|
// its session id on the SAME node.
|
|
418
424
|
if (event?.reason === 'new') {
|
|
419
425
|
try {
|
|
420
|
-
const m = getNode(nodeId);
|
|
421
426
|
// A root relaunch LAUNCHES a broker, and launches are daemon-owned
|
|
422
427
|
// (fleet-bound) — so the broker never runs relaunchRoot in-process.
|
|
423
428
|
// It asks crtrd via POST /v1/nodes/:id/relaunch-root instead; the
|
|
424
429
|
// rejection is swallowed here (the enclosing sync catch can't catch
|
|
425
430
|
// an async one) to keep `/new` best-effort.
|
|
426
|
-
if (
|
|
431
|
+
if (existing?.parent == null)
|
|
427
432
|
void cliClient().relaunchRoot(nodeId).catch(() => { });
|
|
428
433
|
else
|
|
429
434
|
handleNewSession(nodeId, id, sessionFile);
|
|
@@ -446,36 +451,27 @@ export function registerCanvasStophook(pi) {
|
|
|
446
451
|
// proof for reviveNode's cycling-attempt marker and the one-shot yield
|
|
447
452
|
// note — both remain pending through any pre-session_start failure and are
|
|
448
453
|
// safe to clear on any confirmed boot (cycling, resuming, or fresh).
|
|
449
|
-
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
//
|
|
453
|
-
|
|
454
|
-
// state that could fork provenance twice.
|
|
455
|
-
if (existing?.private_fork_phase === 'fork_pending' && sessionFile === null) {
|
|
454
|
+
// An ordinary fork is not bound until Pi exposes BOTH the fresh child id
|
|
455
|
+
// and its writable session file. Recovery sees either an unbound fork or
|
|
456
|
+
// complete child coordinates, never a mixed state that could fork
|
|
457
|
+
// provenance twice.
|
|
458
|
+
if (existing?.fork_from != null && existing?.pi_session_id == null && sessionFile === null) {
|
|
456
459
|
try {
|
|
457
460
|
ctx?.shutdown?.();
|
|
458
461
|
}
|
|
459
462
|
catch { /* best-effort */ }
|
|
460
463
|
return;
|
|
461
464
|
}
|
|
462
|
-
// Identity (session id/file
|
|
463
|
-
//
|
|
465
|
+
// Identity (session id/file) → meta; runtime (pid, intent) → atomic row
|
|
466
|
+
// setters. Any confirmed boot owns the one-shot yield note, if any;
|
|
464
467
|
// clear it once here so a pre-session_start retry preserves it, but a
|
|
465
468
|
// successful revival can still only consume it once.
|
|
466
469
|
clearYieldMessage(nodeId);
|
|
467
|
-
updateNode(nodeId,
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
cycle_pending: false,
|
|
473
|
-
}
|
|
474
|
-
: {
|
|
475
|
-
pi_session_id: id,
|
|
476
|
-
pi_session_file: sessionFile,
|
|
477
|
-
cycle_pending: false,
|
|
478
|
-
});
|
|
470
|
+
updateNode(nodeId, {
|
|
471
|
+
pi_session_id: id,
|
|
472
|
+
pi_session_file: sessionFile,
|
|
473
|
+
cycle_pending: false,
|
|
474
|
+
});
|
|
479
475
|
recordPid(nodeId, process.pid);
|
|
480
476
|
if (existing?.intent === 'refresh')
|
|
481
477
|
transition(nodeId, 'revive');
|
|
@@ -525,7 +521,6 @@ export function registerCanvasStophook(pi) {
|
|
|
525
521
|
try {
|
|
526
522
|
lastActivity = summarizeActivity(String(event?.toolName ?? ''), event?.args);
|
|
527
523
|
flushTelemetry(jobDirPath, totalIn, totalOut, model, lastContext, lastActivity);
|
|
528
|
-
narrateToTicket(lastActivity); // a consult fork streams its activity to the waiting ticket
|
|
529
524
|
touchBusy(nodeId); // wedge heartbeat: a fresh tool starting is a sign of life
|
|
530
525
|
clearFault(nodeId, { link: 'daemon→node' }); // a tool actually starting clears any prior wedge notice
|
|
531
526
|
}
|
|
@@ -720,7 +715,7 @@ export function registerCanvasStophook(pi) {
|
|
|
720
715
|
try {
|
|
721
716
|
const drift = personaDrift(nodeId);
|
|
722
717
|
if (drift !== null) {
|
|
723
|
-
pi.sendUserMessage(drift.guidance, { deliverAs: 'steer' });
|
|
718
|
+
pi.sendUserMessage(formatPersonaTransition(drift.guidance), { deliverAs: 'steer' });
|
|
724
719
|
commitPersonaAck(nodeId, drift.to);
|
|
725
720
|
}
|
|
726
721
|
}
|
|
@@ -764,59 +759,19 @@ export function registerCanvasStophook(pi) {
|
|
|
764
759
|
const stopReason = last?.stopReason ?? '';
|
|
765
760
|
// Interrupted or errored runs stay alive for re-steering. The broker
|
|
766
761
|
// publishes any settled provider fault from its subscriber event stream.
|
|
767
|
-
//
|
|
768
|
-
// EXCEPT a follow-up consultation fork (design-followup-consult-v2.md
|
|
769
|
-
// §B.2/§B.4; integrated-review Major-2): it is born `parent:null` with
|
|
770
|
-
// no subscriber and nothing left to re-steer it — there is no human or
|
|
771
|
-
// sibling that will ever send it another message. An exact-model turn
|
|
772
|
-
// failure (the broker's `modelExact` fail-closed gates deliberately
|
|
773
|
-
// refuse to substitute a different model/provider, so the turn just
|
|
774
|
-
// errors) would otherwise leave it parked here forever: `armed`/`pending`
|
|
775
|
-
// in the outbox with no future event guaranteed to reach it (the daemon
|
|
776
|
-
// only reconciles at its own startup, and `_consult`/`_deliver` only
|
|
777
|
-
// fire on a LATER human action on this SAME ticket). Identify it by the
|
|
778
|
-
// presence of its own outbox row (the delivery record) and settle it
|
|
779
|
-
// right here instead: crash the
|
|
780
|
-
// node (frees it from the daemon's supervised LIVE set) and reconcile
|
|
781
|
-
// its outbox immediately — `reconcileFollowUpWork`'s armed+dead branch
|
|
782
|
-
// turns this into the ticket's `error` result, event-driven, no polling.
|
|
783
762
|
if (stopReason !== 'stop' && stopReason !== 'length') {
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
/* best-effort read — treat as ordinary work on storage failure */
|
|
793
|
-
}
|
|
794
|
-
if (isConsultFork || isVisualFork) {
|
|
795
|
-
// Minor-6 (integrated review): shutdown must fire even when
|
|
796
|
-
// transition/reconcile throws — sharing one try with the shutdown
|
|
797
|
-
// call let a reconciliation exception skip it entirely, stranding
|
|
798
|
-
// an already-crashed consult broker (settlement then waits on
|
|
799
|
-
// NOTHING, since this fork has no subscriber to ever retry it).
|
|
800
|
-
// `finally` guarantees the shutdown regardless of the outcome
|
|
801
|
-
// above; the outbox row itself is unaffected either way —
|
|
802
|
-
// `reconcileFollowUpWork` is retried at the next
|
|
803
|
-
// daemon-crash/startup/_consult/_deliver touchpoint.
|
|
763
|
+
// A refresh-yield aborts its OWN turn (the tool_execution_end handler
|
|
764
|
+
// above calls ctx.abort() the instant `crtr node yield` returns), so a
|
|
765
|
+
// non-'stop' stopReason here is the deliberate refresh, never a failed
|
|
766
|
+
// run. Shut down and let the daemon relaunch the node fresh against
|
|
767
|
+
// its roadmap; classifying it below would crash the node instead and
|
|
768
|
+
// the daemon's exit policy would then forget an already-dead row,
|
|
769
|
+
// stranding the yield.
|
|
770
|
+
if (getNode(nodeId)?.intent === 'refresh') {
|
|
804
771
|
try {
|
|
805
|
-
|
|
806
|
-
if (cur !== null && (cur.status === 'active' || cur.status === 'idle'))
|
|
807
|
-
transition(nodeId, 'crash');
|
|
808
|
-
reconcileFollowUpWork();
|
|
809
|
-
reconcileVisualWork();
|
|
810
|
-
}
|
|
811
|
-
catch {
|
|
812
|
-
/* best-effort — reconcileFollowUpWork is retried at the next daemon-crash/startup/_consult/_deliver touchpoint */
|
|
813
|
-
}
|
|
814
|
-
finally {
|
|
815
|
-
try {
|
|
816
|
-
ctx?.shutdown?.();
|
|
817
|
-
}
|
|
818
|
-
catch { /* ignore */ }
|
|
772
|
+
ctx?.shutdown?.();
|
|
819
773
|
}
|
|
774
|
+
catch { /* ignore */ }
|
|
820
775
|
}
|
|
821
776
|
return;
|
|
822
777
|
}
|
|
@@ -847,17 +802,6 @@ export function registerCanvasStophook(pi) {
|
|
|
847
802
|
setPresence(nodeId, { pane: null, tmux_session: null, window: null });
|
|
848
803
|
}
|
|
849
804
|
catch { /* best-effort */ }
|
|
850
|
-
// Consult-outbox dispatch (design-followup-consult-v2.md §B.4): if this
|
|
851
|
-
// node is a follow-up consultation fork, its outbox row was promoted
|
|
852
|
-
// armed→pending inside the SAME transaction that just committed this
|
|
853
|
-
// final (feed.ts commitCanonicalFinal). Deliver it now, in-process, on
|
|
854
|
-
// this fork's own settlement — the happy-path dispatch, event-driven,
|
|
855
|
-
// no polling. A no-op for every non-consult node (no outbox row).
|
|
856
|
-
try {
|
|
857
|
-
dispatchFollowUpWork(nodeId);
|
|
858
|
-
dispatchVisualWork(nodeId);
|
|
859
|
-
}
|
|
860
|
-
catch { /* best-effort — durable reconcilers retry */ }
|
|
861
805
|
}
|
|
862
806
|
finally {
|
|
863
807
|
try {
|
|
@@ -935,6 +879,11 @@ export function registerCanvasStophook(pi) {
|
|
|
935
879
|
}
|
|
936
880
|
catch { /* best-effort */ }
|
|
937
881
|
if (decision.reason === 'finished') {
|
|
882
|
+
// A canonical final can race the in-process watcher just like an
|
|
883
|
+
// awaiting stop: keep the broker alive until any non-deferred entry
|
|
884
|
+
// beyond the durable cursor has been delivered and committed.
|
|
885
|
+
if (readInboxSince(nodeId, readCursor(nodeId)).some((entry) => entry.tier !== 'deferred'))
|
|
886
|
+
return;
|
|
938
887
|
try {
|
|
939
888
|
ctx?.shutdown?.();
|
|
940
889
|
}
|
|
@@ -942,11 +891,12 @@ export function registerCanvasStophook(pi) {
|
|
|
942
891
|
return;
|
|
943
892
|
}
|
|
944
893
|
//
|
|
945
|
-
// Idle-release:
|
|
946
|
-
//
|
|
947
|
-
//
|
|
948
|
-
//
|
|
949
|
-
// is its wake source, so we keep
|
|
894
|
+
// Idle-release: an unfocused node awaiting a subscribed node, controller,
|
|
895
|
+
// or background bash job (reason 'awaiting') is holding a live broker for
|
|
896
|
+
// nothing. Mark it idle-released and shut pi down; the daemon watches its
|
|
897
|
+
// inbox and revives it (resume) when the awaited delivery arrives. A
|
|
898
|
+
// resident node never releases: the human is its wake source, so we keep
|
|
899
|
+
// its broker live and dormant.
|
|
950
900
|
if (decision.reason === 'awaiting' || decision.reason === 'scheduled') {
|
|
951
901
|
// AWAITING ≠ done (no manager-takeover). What happens next splits on
|
|
952
902
|
// whether the user is WATCHING this node:
|
|
@@ -27,6 +27,50 @@ function retireTool(pi) {
|
|
|
27
27
|
/* best-effort; the execute handler is inert when no schema file exists */
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
function strictToolSchema(schema) {
|
|
31
|
+
const transform = (value) => {
|
|
32
|
+
if (Array.isArray(value))
|
|
33
|
+
return value.map(transform);
|
|
34
|
+
if (value === null || typeof value !== 'object')
|
|
35
|
+
return value;
|
|
36
|
+
const source = value;
|
|
37
|
+
const transformed = {};
|
|
38
|
+
for (const [key, child] of Object.entries(source)) {
|
|
39
|
+
if (key === 'properties' && child !== null && typeof child === 'object' && !Array.isArray(child)) {
|
|
40
|
+
transformed[key] = Object.fromEntries(Object.entries(child).map(([name, property]) => [name, transform(property)]));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
transformed[key] = transform(child);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const properties = transformed['properties'];
|
|
47
|
+
if (properties === null || typeof properties !== 'object' || Array.isArray(properties))
|
|
48
|
+
return transformed;
|
|
49
|
+
const required = new Set(Array.isArray(source['required']) ? source['required'].filter((name) => typeof name === 'string') : []);
|
|
50
|
+
transformed['properties'] = Object.fromEntries(Object.entries(properties).map(([name, property]) => [
|
|
51
|
+
name,
|
|
52
|
+
required.has(name) ? property : { anyOf: [property, { type: 'null' }] },
|
|
53
|
+
]));
|
|
54
|
+
transformed['required'] = Object.keys(properties);
|
|
55
|
+
return transformed;
|
|
56
|
+
};
|
|
57
|
+
return transform(schema);
|
|
58
|
+
}
|
|
59
|
+
function omitStrictNulls(value, schema) {
|
|
60
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value) || schema === null || typeof schema !== 'object' || Array.isArray(schema))
|
|
61
|
+
return value;
|
|
62
|
+
const source = schema;
|
|
63
|
+
const properties = source['properties'];
|
|
64
|
+
if (properties === null || typeof properties !== 'object' || Array.isArray(properties))
|
|
65
|
+
return value;
|
|
66
|
+
const requiredNames = source['required'];
|
|
67
|
+
const required = new Set(Array.isArray(requiredNames) ? requiredNames.filter((name) => typeof name === 'string') : []);
|
|
68
|
+
return Object.fromEntries(Object.entries(value).flatMap(([name, child]) => {
|
|
69
|
+
if (child === null && !required.has(name) && Object.hasOwn(properties, name))
|
|
70
|
+
return [];
|
|
71
|
+
return [[name, omitStrictNulls(child, properties[name])]];
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
30
74
|
function toolDescription(request) {
|
|
31
75
|
if (request.mode === 'terminal') {
|
|
32
76
|
return 'Submit your final structured result. Calling this ends your run: the result is recorded and a final report is pushed automatically — do NOT call `crtr push final` yourself.';
|
|
@@ -66,11 +110,10 @@ export function registerCanvasStructuredOutput(pi) {
|
|
|
66
110
|
'Use submit to answer the pending one-off structured-output request before stopping or going dormant.',
|
|
67
111
|
'After one-off submit succeeds, continue with any remaining work normally.',
|
|
68
112
|
],
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
// stay authoritative either way — this only makes a malformed submission rarer.
|
|
113
|
+
// OpenAI strict tools require every property to be required. Optional fields
|
|
114
|
+
// become nullable in the provider-only schema and null is removed before the
|
|
115
|
+
// original result is persisted.
|
|
116
|
+
parameters: strictToolSchema(request.schema),
|
|
74
117
|
constrainedSampling: { type: 'json_schema', strict: 'prefer' },
|
|
75
118
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
76
119
|
const current = readOutputRequest(nodeId);
|
|
@@ -88,8 +131,9 @@ export function registerCanvasStructuredOutput(pi) {
|
|
|
88
131
|
details: { submitted: false, reason: 'schema_replaced' },
|
|
89
132
|
};
|
|
90
133
|
}
|
|
134
|
+
const result = omitStrictNulls(params, current.schema);
|
|
91
135
|
const resultPath = outputResultPath(nodeId);
|
|
92
|
-
const json = JSON.stringify(
|
|
136
|
+
const json = JSON.stringify(result, null, 2);
|
|
93
137
|
mkdirSync(dirname(resultPath), { recursive: true });
|
|
94
138
|
writeFileSync(resultPath, `${json}\n`, 'utf8');
|
|
95
139
|
const body = reportBody(resultPath, json);
|
|
@@ -114,7 +158,7 @@ export function registerCanvasStructuredOutput(pi) {
|
|
|
114
158
|
catch { /* ignore */ }
|
|
115
159
|
return {
|
|
116
160
|
content: [{ type: 'text', text: `Structured output submitted and finalized: ${resultPath}` }],
|
|
117
|
-
details: { submitted: true, mode: current.mode, resultPath, result
|
|
161
|
+
details: { submitted: true, mode: current.mode, resultPath, result },
|
|
118
162
|
terminate: true,
|
|
119
163
|
};
|
|
120
164
|
}
|
|
@@ -124,7 +168,7 @@ export function registerCanvasStructuredOutput(pi) {
|
|
|
124
168
|
retireTool(pi);
|
|
125
169
|
return {
|
|
126
170
|
content: [{ type: 'text', text: `Structured output submitted: ${resultPath}` }],
|
|
127
|
-
details: { submitted: true, mode: current.mode, resultPath, result
|
|
171
|
+
details: { submitted: true, mode: current.mode, resultPath, result },
|
|
128
172
|
};
|
|
129
173
|
},
|
|
130
174
|
});
|