@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
|
@@ -1,657 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/**
|
|
3
|
-
* Canvas Dashboard — the PORTABLE CORE of the crtr `canvas` view (manifest ·
|
|
4
|
-
* init · sources · intents). The READ-ONLY monitor of the live agent graph: one
|
|
5
|
-
* core renders in BOTH targets — the tmux TUI (`crtr view run canvas`, via
|
|
6
|
-
* `tui.mjs`) and the React+Tailwind web page (`crtr view serve canvas`, via
|
|
7
|
-
* `web.jsx`).
|
|
8
|
-
*
|
|
9
|
-
* Runs in BOTH Node and the browser, so it imports NOTHING — no `node:*`, no
|
|
10
|
-
* crtr. The data layer is expressed as transport-agnostic `Source` descriptors:
|
|
11
|
-
* the core describes WHAT to run (`request()` → a SourceRequest for
|
|
12
|
-
* `crtr … --json`), the host's Transport runs it (local `execFile` for the TUI,
|
|
13
|
-
* the HTTP bridge for web), and the pure `parse()` turns bytes → typed data | a
|
|
14
|
-
* typed `SourceError`. The forest building + relative-age / chrome-copy logic is
|
|
15
|
-
* pure string/data work that runs anywhere.
|
|
16
|
-
*
|
|
17
|
-
* It rebuilds the forest from each node's `parent` edge, keeps only trees that
|
|
18
|
-
* contain live (active/idle) or human-blocked work, and renders them as a
|
|
19
|
-
* scrollable ASCII tree (TUI) / DOM tree (web). It auto-polls (refreshMs) — no
|
|
20
|
-
* node-focus / close / swap (views are sessionless). j/k move a read cursor; g
|
|
21
|
-
* forces a refresh; q quits.
|
|
22
|
-
*
|
|
23
|
-
* NOTHING throws. Sources return a `Result<T>` (a typed `SourceError` on
|
|
24
|
-
* failure); the `refresh` intent KEEPS the last-known forest on a transient
|
|
25
|
-
* failure and raises the cause as a banner, dropping to a guided takeover only
|
|
26
|
-
* when there is nothing to keep (graceful partial failure).
|
|
27
|
-
*
|
|
28
|
-
* @module canvas/core
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @typedef {import('../../core/view/contract.js').SourceError} SourceError
|
|
33
|
-
* @typedef {import('../../core/view/contract.js').IntentCtx<CanvasState>} Ctx
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* One canvas node, flattened from `node inspect list --json`.
|
|
38
|
-
* @typedef {Object} CanvasNode
|
|
39
|
-
* @property {string} nodeId Full node id (`<time>-<hash>`).
|
|
40
|
-
* @property {string} name Display name.
|
|
41
|
-
* @property {string} kind Node kind (general/developer/explore/human/…).
|
|
42
|
-
* @property {string} mode base | orchestrator.
|
|
43
|
-
* @property {string} lifecycle resident | terminal.
|
|
44
|
-
* @property {string} status active | idle | done | dead | canceled.
|
|
45
|
-
* @property {string|null} parent Spawn/subscription parent id (null ⇒ a forest root).
|
|
46
|
-
* @property {string} created ISO 8601 birth timestamp (drives child ordering).
|
|
47
|
-
* @property {Fault|null} hanging Non-null ⇒ the node is PARKED on an active
|
|
48
|
-
* fault (provider-owned faults only suppress when stale; manual/client faults
|
|
49
|
-
* stay visible until cleared).
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* The active-fault marker payload (mirrors core/runtime/fault.ts).
|
|
54
|
-
* @typedef {Object} FaultRetry
|
|
55
|
-
* @property {'auto'|'manual'|'fatal'} disposition
|
|
56
|
-
* @property {'sdk'|'daemon'|'client'=} by
|
|
57
|
-
* @property {number=} attempt
|
|
58
|
-
* @property {number=} max
|
|
59
|
-
* @property {string=} nextAt
|
|
60
|
-
*/
|
|
61
|
-
/**
|
|
62
|
-
* @typedef {Object} Fault
|
|
63
|
-
* @property {'pi→provider'|'viewer↔broker'|'relay↔broker'|'browser↔relay'|'cli→exa'|'daemon→node'} link
|
|
64
|
-
* @property {string} op
|
|
65
|
-
* @property {'rate-limit'|'overloaded'|'connection'|'auth'|'protocol'|'other'|'wedged'|'model-not-found'} kind
|
|
66
|
-
* @property {FaultRetry} retry
|
|
67
|
-
* @property {string} message The raw engine error (capped).
|
|
68
|
-
* @property {string} since ISO 8601 — when the fault was first observed.
|
|
69
|
-
* @property {string} operation_id Correlation identity for the fault operation.
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* One cwd with pending human asks, from `canvas attention list --json`.
|
|
74
|
-
* @typedef {Object} AttentionItem
|
|
75
|
-
* @property {string} nodeId
|
|
76
|
-
* @property {string} name
|
|
77
|
-
* @property {string} cwd
|
|
78
|
-
* @property {number} count Pending ask count.
|
|
79
|
-
*/
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* One rendered tree line (a flattened forest node). Width-independent, so it is
|
|
83
|
-
* built once per refresh and re-rendered on resize without a re-fetch.
|
|
84
|
-
* @typedef {Object} TreeRow
|
|
85
|
-
* @property {string} nodeId
|
|
86
|
-
* @property {string} prefix Tree-branch art (e.g. "│ └─ "); '' for a root.
|
|
87
|
-
* @property {string} glyph Status glyph.
|
|
88
|
-
* @property {string} status
|
|
89
|
-
* @property {string} name
|
|
90
|
-
* @property {string} kind
|
|
91
|
-
* @property {string} mode
|
|
92
|
-
* @property {string} lifecycle
|
|
93
|
-
* @property {string} shortId
|
|
94
|
-
* @property {string} created ISO 8601 birth timestamp (drives the right-flush age).
|
|
95
|
-
* @property {boolean} blocked True ⇒ this node has pending human asks.
|
|
96
|
-
* @property {number} askCount
|
|
97
|
-
* @property {Fault|null} hanging Non-null ⇒ parked on an active fault (⚠ +
|
|
98
|
-
* kind label + countdown/state cue).
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* The view's immutable state (the core owns it; intents replace it via ctx.set).
|
|
103
|
-
* @typedef {Object} CanvasState
|
|
104
|
-
* @property {TreeRow[]} rows Flattened active-tree forest (render source).
|
|
105
|
-
* @property {number} cursor Read cursor into rows (j/k).
|
|
106
|
-
* @property {number} scroll draw.list scroll, stored back each frame.
|
|
107
|
-
* @property {number} shownRoots How many trees survived the active filter.
|
|
108
|
-
* @property {number} totalNodes Total nodes on the canvas (all statuses).
|
|
109
|
-
* @property {number} activeCount Nodes with status 'active' (canvas-wide).
|
|
110
|
-
* @property {number} attnTotal Total pending human asks (canvas-wide).
|
|
111
|
-
* @property {number} lastFetch Epoch ms of the last successful refresh.
|
|
112
|
-
* @property {SourceError|null} sourceError Non-null ⇒ the data source failed;
|
|
113
|
-
* presenters render its `display` VERBATIM (the not-ready takeover when there
|
|
114
|
-
* is no data, and the dump fallback). Cleared on a successful refresh.
|
|
115
|
-
*/
|
|
116
|
-
|
|
117
|
-
// ── Result helpers (inlined — the core imports nothing) ───────────────────────
|
|
118
|
-
|
|
119
|
-
/** @template T @param {T} data @returns {{ok:true, data:T}} */
|
|
120
|
-
function ok(data) {
|
|
121
|
-
return { ok: true, data };
|
|
122
|
-
}
|
|
123
|
-
/** @param {SourceError} error @returns {{ok:false, error:SourceError}} */
|
|
124
|
-
function fail(error) {
|
|
125
|
-
return { ok: false, error };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ── Field mappers ───────────────────────────────────────────────────
|
|
129
|
-
|
|
130
|
-
/** @param {unknown} v @returns {string} */
|
|
131
|
-
function str(v) {
|
|
132
|
-
return v == null ? '' : String(v);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/** @param {any} n @returns {CanvasNode} */
|
|
136
|
-
function toNode(n) {
|
|
137
|
-
const o = n || {};
|
|
138
|
-
return {
|
|
139
|
-
nodeId: str(o.node_id),
|
|
140
|
-
name: str(o.name) || '(unnamed)',
|
|
141
|
-
kind: str(o.kind) || '?',
|
|
142
|
-
mode: str(o.mode) || '?',
|
|
143
|
-
lifecycle: str(o.lifecycle) || '?',
|
|
144
|
-
status: str(o.status) || '?',
|
|
145
|
-
parent: o.parent ? str(o.parent) : null,
|
|
146
|
-
created: str(o.created),
|
|
147
|
-
hanging: o.hanging && typeof o.hanging === 'object' ? o.hanging : null,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** @param {any} i @returns {AttentionItem} */
|
|
152
|
-
function toAttention(i) {
|
|
153
|
-
const o = i || {};
|
|
154
|
-
return {
|
|
155
|
-
nodeId: str(o.node_id),
|
|
156
|
-
name: str(o.name),
|
|
157
|
-
cwd: str(o.cwd),
|
|
158
|
-
count: typeof o.count === 'number' ? o.count : 0,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// ── Status vocabulary (mirrors core/canvas/browse/render.ts — single source) ──
|
|
163
|
-
|
|
164
|
-
const LIVE_STATUS = new Set(['active', 'idle']);
|
|
165
|
-
|
|
166
|
-
/** @type {Record<string,string>} */
|
|
167
|
-
export const STATUS_GLYPH = {
|
|
168
|
-
active: '●',
|
|
169
|
-
idle: '○',
|
|
170
|
-
done: '✓',
|
|
171
|
-
dead: '✗',
|
|
172
|
-
canceled: '⊘',
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Hanging overlay (parked on an active fault). The ⚠ glyph + per-kind label +
|
|
176
|
-
// countdown mirror core/canvas/status-glyph.ts — duplicated here (with the
|
|
177
|
-
// grace constant) because this portable .mjs view CANNOT import the TS dist.
|
|
178
|
-
// fault.ts is the source of truth; keep these in sync.
|
|
179
|
-
export const HANGING_GLYPH = '⚠';
|
|
180
|
-
/** Mirror of FAULT_QUIET_MS (core/runtime/fault.ts) — the browse rail's
|
|
181
|
-
* retry-countdown origin span. Source of truth is fault.ts; keep in sync. */
|
|
182
|
-
const FAULT_QUIET_MS = 5 * 60_000;
|
|
183
|
-
|
|
184
|
-
/** @param {string} kind @returns {string} */
|
|
185
|
-
export function hangingLabel(kind) {
|
|
186
|
-
if (kind === 'rate-limit') return 'rate-limited';
|
|
187
|
-
if (kind === 'overloaded') return 'overloaded';
|
|
188
|
-
if (kind === 'connection') return 'down';
|
|
189
|
-
if (kind === 'auth') return 'auth';
|
|
190
|
-
if (kind === 'protocol') return 'protocol';
|
|
191
|
-
if (kind === 'context-overflow') return 'context-overflow';
|
|
192
|
-
if (kind === 'wedged') return 'wedged';
|
|
193
|
-
if (kind === 'model-not-found') return 'model-not-found';
|
|
194
|
-
return 'other';
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function retryCountdown(iso, now) {
|
|
198
|
-
const at = Date.parse(iso);
|
|
199
|
-
if (Number.isNaN(at)) return 'now';
|
|
200
|
-
const remaining = at - now;
|
|
201
|
-
if (remaining <= 0) return 'now';
|
|
202
|
-
if (remaining >= 60_000) return `${Math.max(1, Math.round(remaining / 60_000))}m`;
|
|
203
|
-
return `${Math.max(1, Math.ceil(remaining / 1000))}s`;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function faultDispositionText(fault, now) {
|
|
207
|
-
if (fault.retry.disposition === 'auto') {
|
|
208
|
-
if (fault.retry.by === 'client') return 'redialing';
|
|
209
|
-
const progress = typeof fault.retry.attempt === 'number' && typeof fault.retry.max === 'number'
|
|
210
|
-
? `auto-retry ${fault.retry.attempt}/${fault.retry.max}`
|
|
211
|
-
: 'auto-retrying';
|
|
212
|
-
return fault.retry.nextAt ? `${progress}, next ${retryCountdown(fault.retry.nextAt, now)}` : progress;
|
|
213
|
-
}
|
|
214
|
-
return 'needs you';
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** One-line active-fault summary: `link kind · disposition`. */
|
|
218
|
-
export function faultSummary(fault, now) {
|
|
219
|
-
return `${fault.link} ${hangingLabel(fault.kind)} · ${faultDispositionText(fault, now)}`;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/** Elapsed counter kept for the browse rail's existing countdown slot. */
|
|
223
|
-
export function hangingCountdown(since, now) {
|
|
224
|
-
const start = Date.parse(since);
|
|
225
|
-
if (Number.isNaN(start)) return 'retrying…';
|
|
226
|
-
const remaining = FAULT_QUIET_MS - (now - start);
|
|
227
|
-
if (remaining <= 0) return 'retrying…';
|
|
228
|
-
if (remaining >= 60_000) return `retry in ~${Math.max(1, Math.round(remaining / 60_000))}m`;
|
|
229
|
-
return `retry in ~${Math.ceil(remaining / 1000)}s`;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/** @param {string} lifecycle @returns {string} */
|
|
233
|
-
export function lifeAbbr(lifecycle) {
|
|
234
|
-
if (lifecycle === 'resident') return 'res';
|
|
235
|
-
if (lifecycle === 'terminal') return 'term';
|
|
236
|
-
return lifecycle || '?';
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/** @param {string} id @returns {string} */
|
|
240
|
-
function shortId(id) {
|
|
241
|
-
const s = String(id || '');
|
|
242
|
-
const dash = s.indexOf('-');
|
|
243
|
-
return dash > 0 ? s.slice(0, dash) : s.slice(0, 8);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Relative-age ladder (design §5): `now` (<60s), `{m}m` (<60m), `{h}h` (<24h),
|
|
250
|
-
* `{d}d` (<7d), else a calendar date `Mon D` (`Mar 4`), prior-year `Mon ʼYY`.
|
|
251
|
-
* Max ~5 cols. Used for the right-flushed per-row age (the node's birth time).
|
|
252
|
-
* Shared by the TUI render + the text dump (both import it from here).
|
|
253
|
-
* @param {string} createdIso @param {number} now @returns {string}
|
|
254
|
-
*/
|
|
255
|
-
export function relAge(createdIso, now) {
|
|
256
|
-
const t = Date.parse(createdIso);
|
|
257
|
-
if (Number.isNaN(t)) return '';
|
|
258
|
-
const s = Math.max(0, Math.floor((now - t) / 1000));
|
|
259
|
-
if (s < 60) return 'now';
|
|
260
|
-
const m = Math.floor(s / 60);
|
|
261
|
-
if (m < 60) return `${m}m`;
|
|
262
|
-
const h = Math.floor(m / 60);
|
|
263
|
-
if (h < 24) return `${h}h`;
|
|
264
|
-
const d = Math.floor(h / 24);
|
|
265
|
-
if (d < 7) return `${d}d`;
|
|
266
|
-
const date = new Date(t);
|
|
267
|
-
const mon = MONTHS[date.getMonth()] || '?';
|
|
268
|
-
if (date.getFullYear() === new Date(now).getFullYear()) return `${mon} ${date.getDate()}`;
|
|
269
|
-
return `${mon} ʼ${String(date.getFullYear()).slice(-2)}`;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/** @param {number} n @param {string} w @returns {string} */
|
|
273
|
-
export function plural(n, w) {
|
|
274
|
-
return `${n} ${w}${n === 1 ? '' : 's'}`;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// ── Typed SourceError displays (the `display`/`kind` split; presenters render
|
|
278
|
-
// `display` verbatim and never branch on `kind`) ────────────────────────────
|
|
279
|
-
|
|
280
|
-
/** @type {SourceError} */
|
|
281
|
-
const CRTR_MISSING = {
|
|
282
|
-
kind: 'crtr-missing',
|
|
283
|
-
display: {
|
|
284
|
-
headline: 'Canvas unavailable',
|
|
285
|
-
explanation: 'crtr could not be found to read the canvas graph.',
|
|
286
|
-
nextStep: 'Install crtr (or set CRTR_BIN on PATH), then press g.',
|
|
287
|
-
level: 'error',
|
|
288
|
-
blocking: true,
|
|
289
|
-
},
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
/** @param {string} stderr @returns {SourceError} */
|
|
293
|
-
function crtrFailed(stderr) {
|
|
294
|
-
const s = String(stderr || '');
|
|
295
|
-
return {
|
|
296
|
-
kind: 'crtr-failed',
|
|
297
|
-
display: {
|
|
298
|
-
headline: 'Canvas unavailable',
|
|
299
|
-
explanation: 'crtr could not read the canvas graph: ' + (extractMessage(s) || 'unknown error'),
|
|
300
|
-
nextStep: 'Press g to retry.',
|
|
301
|
-
level: 'error',
|
|
302
|
-
blocking: true,
|
|
303
|
-
},
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/** @param {string} cmd @returns {SourceError} */
|
|
308
|
-
function parseError(cmd) {
|
|
309
|
-
return {
|
|
310
|
-
kind: 'parse',
|
|
311
|
-
display: {
|
|
312
|
-
headline: 'Canvas unavailable',
|
|
313
|
-
explanation: `Could not parse \`crtr ${cmd}\` output as JSON.`,
|
|
314
|
-
nextStep: 'Press g to retry.',
|
|
315
|
-
level: 'error',
|
|
316
|
-
blocking: true,
|
|
317
|
-
},
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Pull a human message out of crtr stderr: prefer the last `ERROR:` line, else
|
|
323
|
-
* the last non-empty line, else ''.
|
|
324
|
-
* @param {string} stderr @returns {string}
|
|
325
|
-
*/
|
|
326
|
-
function extractMessage(stderr) {
|
|
327
|
-
const lines = String(stderr || '')
|
|
328
|
-
.split(/\r?\n/)
|
|
329
|
-
.map((l) => l.trim())
|
|
330
|
-
.filter(Boolean);
|
|
331
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
332
|
-
if (/^ERROR:/i.test(lines[i])) return lines[i].replace(/^ERROR:\s*/i, '').trim();
|
|
333
|
-
}
|
|
334
|
-
if (lines.length) return lines[lines.length - 1];
|
|
335
|
-
return '';
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// ── Sources (reads): a request descriptor + a pure parse. The host's transport
|
|
339
|
-
// runs the request (local execFile for TUI, the HTTP bridge for web).
|
|
340
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Every node on the canvas (all statuses). The view rebuilds the forest from the
|
|
344
|
-
* `parent` edges and filters to active trees itself. The PRIMARY instrument —
|
|
345
|
-
* its parse owns the hard failure (crtr missing / a failing crtr command).
|
|
346
|
-
* @type {import('../../core/view/contract.js').Source<CanvasNode[]>}
|
|
347
|
-
*/
|
|
348
|
-
export const nodesSource = {
|
|
349
|
-
id: 'nodes',
|
|
350
|
-
request: () => ({ kind: 'exec', bin: 'crtr', args: ['node', 'inspect', 'list', '--json'] }),
|
|
351
|
-
parse: (raw) => {
|
|
352
|
-
if (!raw.ok) return fail(CRTR_MISSING);
|
|
353
|
-
if (raw.exitCode !== 0) return fail(crtrFailed(raw.stderr || raw.stdout));
|
|
354
|
-
const out = String(raw.stdout || '').trim();
|
|
355
|
-
let data;
|
|
356
|
-
try {
|
|
357
|
-
data = out === '' ? {} : JSON.parse(out);
|
|
358
|
-
} catch {
|
|
359
|
-
return fail(parseError('node inspect list'));
|
|
360
|
-
}
|
|
361
|
-
const arr = data && Array.isArray(data.nodes) ? data.nodes : [];
|
|
362
|
-
return ok(arr.map(toNode));
|
|
363
|
-
},
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Pending human asks across the canvas (the "blocked on a human" signal).
|
|
368
|
-
* BEST-EFFORT: any failure degrades to no flags (the graph still renders), so a
|
|
369
|
-
* parse never blocks the monitor — it returns an empty set instead of an error.
|
|
370
|
-
* @type {import('../../core/view/contract.js').Source<{items:AttentionItem[], total:number}>}
|
|
371
|
-
*/
|
|
372
|
-
export const attentionSource = {
|
|
373
|
-
id: 'attention',
|
|
374
|
-
request: () => ({ kind: 'exec', bin: 'crtr', args: ['canvas', 'attention', 'list', '--json'] }),
|
|
375
|
-
parse: (raw) => {
|
|
376
|
-
if (!raw.ok || raw.exitCode !== 0) return ok({ items: [], total: 0 });
|
|
377
|
-
const out = String(raw.stdout || '').trim();
|
|
378
|
-
let data;
|
|
379
|
-
try {
|
|
380
|
-
data = out === '' ? {} : JSON.parse(out);
|
|
381
|
-
} catch {
|
|
382
|
-
return ok({ items: [], total: 0 });
|
|
383
|
-
}
|
|
384
|
-
const items = data && Array.isArray(data.items) ? data.items : [];
|
|
385
|
-
const total = data && typeof data.total === 'number' ? data.total : 0;
|
|
386
|
-
return ok({ items: items.map(toAttention), total });
|
|
387
|
-
},
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
// ── Forest builder ─────────────────────────────────────────────
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Build the flattened active-tree forest from a flat node list + the
|
|
394
|
-
* human-blocked id→count map.
|
|
395
|
-
*
|
|
396
|
-
* A tree is shown iff its subtree contains any LIVE node (status active|idle) OR
|
|
397
|
-
* any human-blocked node — so a fully-finished tree drops out, but a blocked one
|
|
398
|
-
* always surfaces. Shown trees are rendered IN FULL (finished children included)
|
|
399
|
-
* to preserve context, mirroring `crtr canvas dashboard`.
|
|
400
|
-
*
|
|
401
|
-
* @param {CanvasNode[]} nodes
|
|
402
|
-
* @param {Map<string,number>} blockedById
|
|
403
|
-
* @returns {{rows: TreeRow[], shownRoots: number}}
|
|
404
|
-
*/
|
|
405
|
-
export function buildForest(nodes, blockedById) {
|
|
406
|
-
/** @type {Map<string, CanvasNode>} */
|
|
407
|
-
const byId = new Map();
|
|
408
|
-
for (const n of nodes) byId.set(n.nodeId, n);
|
|
409
|
-
|
|
410
|
-
/** @type {Map<string, CanvasNode[]>} */
|
|
411
|
-
const children = new Map();
|
|
412
|
-
/** @type {CanvasNode[]} */
|
|
413
|
-
const roots = [];
|
|
414
|
-
for (const n of nodes) {
|
|
415
|
-
const parent = n.parent && byId.has(n.parent) ? n.parent : null;
|
|
416
|
-
if (parent) {
|
|
417
|
-
const arr = children.get(parent);
|
|
418
|
-
if (arr) arr.push(n);
|
|
419
|
-
else children.set(parent, [n]);
|
|
420
|
-
} else {
|
|
421
|
-
roots.push(n);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
// Order siblings + roots by birth time (matches spawn order).
|
|
425
|
-
const cmp = (/** @type {CanvasNode} */ a, /** @type {CanvasNode} */ b) =>
|
|
426
|
-
a.created < b.created ? -1 : a.created > b.created ? 1 : 0;
|
|
427
|
-
for (const arr of children.values()) arr.sort(cmp);
|
|
428
|
-
roots.sort(cmp);
|
|
429
|
-
|
|
430
|
-
// Subtree liveness, memoised + cycle-guarded (the graph is a forest, but the
|
|
431
|
-
// db is mutable — guard defensively).
|
|
432
|
-
/** @type {Map<string, boolean>} */
|
|
433
|
-
const liveMemo = new Map();
|
|
434
|
-
/** @param {string} id @param {Set<string>} guard @returns {boolean} */
|
|
435
|
-
function subtreeLive(id, guard) {
|
|
436
|
-
const memo = liveMemo.get(id);
|
|
437
|
-
if (memo !== undefined) return memo;
|
|
438
|
-
if (guard.has(id)) return false;
|
|
439
|
-
guard.add(id);
|
|
440
|
-
const node = byId.get(id);
|
|
441
|
-
let res = !!node && (LIVE_STATUS.has(node.status) || blockedById.has(id));
|
|
442
|
-
if (!res) {
|
|
443
|
-
for (const c of children.get(id) || []) {
|
|
444
|
-
if (subtreeLive(c.nodeId, guard)) {
|
|
445
|
-
res = true;
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
guard.delete(id);
|
|
451
|
-
liveMemo.set(id, res);
|
|
452
|
-
return res;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/** @param {CanvasNode} node @param {string} prefix @returns {TreeRow} */
|
|
456
|
-
function makeRow(node, prefix) {
|
|
457
|
-
const askCount = blockedById.get(node.nodeId) || 0;
|
|
458
|
-
return {
|
|
459
|
-
nodeId: node.nodeId,
|
|
460
|
-
prefix,
|
|
461
|
-
glyph: node.hanging ? HANGING_GLYPH : (STATUS_GLYPH[node.status] || '?'),
|
|
462
|
-
status: node.status,
|
|
463
|
-
name: node.name,
|
|
464
|
-
kind: node.kind,
|
|
465
|
-
mode: node.mode,
|
|
466
|
-
lifecycle: node.lifecycle,
|
|
467
|
-
shortId: shortId(node.nodeId),
|
|
468
|
-
created: node.created,
|
|
469
|
-
blocked: askCount > 0,
|
|
470
|
-
askCount,
|
|
471
|
-
hanging: node.hanging || null,
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/** @type {TreeRow[]} */
|
|
476
|
-
const rows = [];
|
|
477
|
-
/** @type {Set<string>} */
|
|
478
|
-
const visited = new Set();
|
|
479
|
-
/** @param {CanvasNode} node @param {string} indent @param {boolean} isLast @param {boolean} isRoot */
|
|
480
|
-
function walk(node, indent, isLast, isRoot) {
|
|
481
|
-
if (visited.has(node.nodeId)) return; // cycle guard
|
|
482
|
-
visited.add(node.nodeId);
|
|
483
|
-
const prefix = isRoot ? '' : indent + (isLast ? '└─ ' : '├─ ');
|
|
484
|
-
rows.push(makeRow(node, prefix));
|
|
485
|
-
const kids = children.get(node.nodeId) || [];
|
|
486
|
-
const childIndent = isRoot ? '' : indent + (isLast ? ' ' : '│ ');
|
|
487
|
-
for (let i = 0; i < kids.length; i++) {
|
|
488
|
-
walk(kids[i], childIndent, i === kids.length - 1, false);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
let shownRoots = 0;
|
|
493
|
-
for (const r of roots) {
|
|
494
|
-
if (!subtreeLive(r.nodeId, new Set())) continue;
|
|
495
|
-
shownRoots++;
|
|
496
|
-
walk(r, '', true, true);
|
|
497
|
-
}
|
|
498
|
-
return { rows, shownRoots };
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// ── Chrome copy (subtitle / footer / dump; pure) ──────────────────────────────
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Live title subtitle — canvas-wide health (design §3 "a dim ` · <subtitle>`").
|
|
505
|
-
* `null` ⇒ no subtitle (the title leads alone) on an empty canvas.
|
|
506
|
-
* @param {CanvasState} state @returns {string|null}
|
|
507
|
-
*/
|
|
508
|
-
function subtitleFor(state) {
|
|
509
|
-
if (state.totalNodes === 0) return null;
|
|
510
|
-
return `${state.activeCount} active · ${plural(state.totalNodes, 'node')}`;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Footer status (left, transient) — the RENDERED forest scope, distinct from the
|
|
515
|
-
* canvas-wide subtitle. `null` ⇒ nothing (the empty/loading state speaks).
|
|
516
|
-
* @param {CanvasState} state @returns {string|null}
|
|
517
|
-
*/
|
|
518
|
-
function footerSummary(state) {
|
|
519
|
-
if (state.rows.length === 0) return null;
|
|
520
|
-
return `${plural(state.shownRoots, 'live tree')} · ${state.rows.length} shown`;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/** @param {CanvasState} state @returns {string} */
|
|
524
|
-
export function dumpSummary(state) {
|
|
525
|
-
return (
|
|
526
|
-
`${plural(state.shownRoots, 'tree')} · ${state.rows.length} shown · ` +
|
|
527
|
-
`${state.activeCount} active · ${plural(state.attnTotal, 'ask')} · ` +
|
|
528
|
-
`${state.totalNodes} total`
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
// ── The portable core ──────────────────────────────────────────────────────────
|
|
533
|
-
|
|
534
|
-
/** @type {import('../../core/view/contract.js').ViewCore<CanvasState>} */
|
|
535
|
-
const core = {
|
|
536
|
-
manifest: {
|
|
537
|
-
id: 'canvas',
|
|
538
|
-
title: 'Canvas',
|
|
539
|
-
description: 'Live agent graph — who is working, who is blocked',
|
|
540
|
-
refreshMs: 3000,
|
|
541
|
-
},
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Cheap + synchronous initial state — NO slow fetch (the host paints a loading
|
|
545
|
-
* frame, then dispatches the first 'refresh').
|
|
546
|
-
* @returns {CanvasState}
|
|
547
|
-
*/
|
|
548
|
-
init() {
|
|
549
|
-
return {
|
|
550
|
-
rows: [],
|
|
551
|
-
cursor: 0,
|
|
552
|
-
scroll: 0,
|
|
553
|
-
shownRoots: 0,
|
|
554
|
-
totalNodes: 0,
|
|
555
|
-
activeCount: 0,
|
|
556
|
-
attnTotal: 0,
|
|
557
|
-
lastFetch: 0,
|
|
558
|
-
sourceError: null,
|
|
559
|
-
};
|
|
560
|
-
},
|
|
561
|
-
|
|
562
|
-
sources: { nodesSource, attentionSource },
|
|
563
|
-
|
|
564
|
-
intents: {
|
|
565
|
-
/**
|
|
566
|
-
* Pull the node graph + attention, rebuild the active-tree forest. Runs in
|
|
567
|
-
* the host's single-flight lane (launch, refreshMs, and the `refresh`
|
|
568
|
-
* keybind). A nodes failure KEEPS the last-known forest and raises the cause
|
|
569
|
-
* as a banner (the not-ready takeover only owns the screen when there is
|
|
570
|
-
* nothing to keep — see the presenters). Attention is best-effort: a failure
|
|
571
|
-
* still renders the graph, just without the blocked flags.
|
|
572
|
-
* @param {Ctx} ctx
|
|
573
|
-
*/
|
|
574
|
-
async refresh(ctx) {
|
|
575
|
-
ctx.signal.setStatus('Loading the canvas…');
|
|
576
|
-
|
|
577
|
-
const rn = await ctx.resolve(nodesSource);
|
|
578
|
-
if (!rn.ok) {
|
|
579
|
-
// Data source down. KEEP the last-known forest; store the typed error
|
|
580
|
-
// (drives the BLOCKED chip + the not-ready takeover when rows are empty)
|
|
581
|
-
// and raise the cause as the error banner.
|
|
582
|
-
ctx.set((s) => ({ ...s, sourceError: rn.error }));
|
|
583
|
-
ctx.signal.setStatus(null);
|
|
584
|
-
ctx.signal.setBanner(rn.error.display.explanation, rn.error.display.level);
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
const nodes = rn.data;
|
|
588
|
-
|
|
589
|
-
/** @type {Map<string,number>} */
|
|
590
|
-
const blockedById = new Map();
|
|
591
|
-
let attnTotal = 0;
|
|
592
|
-
const ra = await ctx.resolve(attentionSource);
|
|
593
|
-
if (ra.ok) {
|
|
594
|
-
for (const it of ra.data.items) {
|
|
595
|
-
if (it.nodeId) blockedById.set(it.nodeId, it.count);
|
|
596
|
-
}
|
|
597
|
-
attnTotal = ra.data.total;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
const built = buildForest(nodes, blockedById);
|
|
601
|
-
ctx.set((s) => {
|
|
602
|
-
/** @type {CanvasState} */
|
|
603
|
-
const next = {
|
|
604
|
-
...s,
|
|
605
|
-
sourceError: null,
|
|
606
|
-
rows: built.rows,
|
|
607
|
-
shownRoots: built.shownRoots,
|
|
608
|
-
totalNodes: nodes.length,
|
|
609
|
-
activeCount: nodes.filter((n) => n.status === 'active').length,
|
|
610
|
-
attnTotal,
|
|
611
|
-
lastFetch: Date.now(),
|
|
612
|
-
};
|
|
613
|
-
if (next.cursor >= next.rows.length) next.cursor = Math.max(0, next.rows.length - 1);
|
|
614
|
-
return next;
|
|
615
|
-
});
|
|
616
|
-
|
|
617
|
-
ctx.signal.setSubtitle(subtitleFor(ctx.state));
|
|
618
|
-
|
|
619
|
-
// Data-freshness → state chip. Pending human asks are the one thing that
|
|
620
|
-
// wants a human: raise an ACTION banner → the host derives the ATTENTION
|
|
621
|
-
// (yellow) chip. Otherwise clear → READY (green). (busy→working is
|
|
622
|
-
// automatic.)
|
|
623
|
-
if (attnTotal > 0) {
|
|
624
|
-
ctx.signal.setBanner(`${plural(attnTotal, 'ask')} waiting on a human — see the ⚑ rows`, 'action');
|
|
625
|
-
} else {
|
|
626
|
-
ctx.signal.clearBanner();
|
|
627
|
-
}
|
|
628
|
-
ctx.signal.setStatus(footerSummary(ctx.state));
|
|
629
|
-
},
|
|
630
|
-
|
|
631
|
-
/** @param {Ctx} ctx */
|
|
632
|
-
cursorDown: (ctx) => ctx.set((s) => ({ ...s, cursor: s.rows.length ? Math.min(s.rows.length - 1, s.cursor + 1) : 0 })),
|
|
633
|
-
/** @param {Ctx} ctx */
|
|
634
|
-
cursorUp: (ctx) => ctx.set((s) => ({ ...s, cursor: Math.max(0, s.cursor - 1) })),
|
|
635
|
-
/**
|
|
636
|
-
* Activate (open) a node. STANDALONE this just sets the read cursor to the
|
|
637
|
-
* node's row — the view stays a read-only monitor. In the WEB SHELL the
|
|
638
|
-
* `{nodeId}` payload is what the host's intent TAP observes to open that
|
|
639
|
-
* node's conversation pane (§5): the core never imports the shell and never
|
|
640
|
-
* knows whether anyone is listening; it always emits the intent, and the
|
|
641
|
-
* payload carries the referent. Unknown/missing id ⇒ no-op.
|
|
642
|
-
* @param {Ctx} ctx @param {{nodeId?: string}} [payload]
|
|
643
|
-
*/
|
|
644
|
-
activate: (ctx, payload) => {
|
|
645
|
-
const id = payload && payload.nodeId;
|
|
646
|
-
if (!id) return;
|
|
647
|
-
ctx.set((s) => {
|
|
648
|
-
const i = s.rows.findIndex((r) => r.nodeId === id);
|
|
649
|
-
return i >= 0 ? { ...s, cursor: i } : s;
|
|
650
|
-
});
|
|
651
|
-
},
|
|
652
|
-
/** @param {Ctx} ctx */
|
|
653
|
-
quit: (ctx) => ctx.signal.quit(),
|
|
654
|
-
},
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
export default core;
|