@north-light/crouter 0.3.173 → 0.3.175
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/bin/runtime-selector.mjs +8 -1
- package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
- package/dist/api/client.d.ts +12 -21
- package/dist/api/client.js +22 -31
- package/dist/api/dto/broker-ops.d.ts +158 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/crons.d.ts +6 -0
- package/dist/api/dto/human.d.ts +7 -1
- package/dist/api/dto/inbox.d.ts +1 -71
- package/dist/api/dto/inbox.js +1 -9
- package/dist/api/dto/nodes.d.ts +6 -7
- package/dist/api/dto/reviews.d.ts +1 -11
- package/dist/api/routes.d.ts +7 -4
- package/dist/api/routes.js +8 -5
- package/dist/build-root.js +3 -3
- package/dist/builtin-memory/04-base-worker.md +1 -4
- package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
- package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
- package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
- package/dist/builtin-memory/advisor/council.md +1 -6
- package/dist/builtin-memory/design.md +2 -7
- package/dist/builtin-memory/development.md +9 -14
- package/dist/builtin-memory/internal/marketplaces.md +2 -6
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +2 -8
- package/dist/builtin-memory/internal/storage-tiers.md +1 -2
- package/dist/builtin-memory/testing.md +41 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +27 -179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +7 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +9 -1
- package/dist/cli.js +2 -2
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
- package/dist/clients/attach/__tests__/context-message.test.js +16 -174
- package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
- package/dist/clients/attach/__tests__/diagram.test.js +2 -2
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
- package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
- package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
- package/dist/clients/attach/command.d.ts +2 -1
- package/dist/clients/attach/command.js +81 -76
- package/dist/clients/attach/input/capabilities.d.ts +27 -0
- package/dist/clients/attach/input/capabilities.js +96 -0
- package/dist/clients/attach/input/controller.d.ts +20 -182
- package/dist/clients/attach/input/controller.js +128 -537
- package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
- package/dist/clients/attach/input/overlay-owner.js +199 -0
- package/dist/clients/attach/overlays/file-review.d.ts +0 -4
- package/dist/clients/attach/overlays/file-review.js +13 -5
- package/dist/clients/attach/overlays/graph.js +2 -10
- package/dist/clients/attach/render/chat-view.d.ts +4 -3
- package/dist/clients/attach/render/chat-view.js +39 -33
- package/dist/clients/attach/render/group-activity.d.ts +1 -0
- package/dist/clients/attach/render/group-activity.js +20 -13
- package/dist/clients/attach/render/group-recap.js +12 -3
- package/dist/clients/attach/session/connection.js +9 -15
- package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
- package/dist/clients/attach/session/editor-inventory.js +7 -8
- package/dist/clients/attach/session/file-links.d.ts +13 -0
- package/dist/clients/attach/session/file-links.js +107 -0
- package/dist/clients/attach/session/frame.d.ts +3 -0
- package/dist/clients/attach/session/frame.js +10 -1
- package/dist/clients/attach/session/frames.js +2 -3
- package/dist/clients/attach/session/input-wiring.d.ts +4 -1
- package/dist/clients/attach/session/input-wiring.js +15 -14
- package/dist/clients/attach/session/mouse.d.ts +6 -1
- package/dist/clients/attach/session/mouse.js +8 -5
- package/dist/clients/attach/session/profile-files.js +18 -12
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/session/state-sync.js +1 -2
- package/dist/clients/attach/session/surface-host.d.ts +3 -2
- package/dist/clients/attach/session/surface-host.js +4 -4
- package/dist/clients/attach/slash/dispatch.d.ts +8 -31
- package/dist/clients/attach/slash/dispatch.js +34 -81
- package/dist/clients/attach/viewer.js +820 -860
- package/dist/clients/conversation/projection.d.ts +79 -0
- package/dist/clients/conversation/projection.js +341 -0
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
- package/dist/clients/inbox/controller.d.ts +0 -4
- package/dist/clients/inbox/controller.js +0 -2
- package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
- package/dist/clients/inbox/review/comments-client.d.ts +3 -2
- package/dist/clients/inbox/review/comments-client.js +12 -12
- package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
- package/dist/clients/inbox/review/companion-pane.js +86 -0
- package/dist/clients/inbox/review/document-surface.d.ts +182 -0
- package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
- package/dist/clients/inbox/review/frame.js +5 -4
- package/dist/clients/inbox/review/launch.d.ts +8 -8
- package/dist/clients/inbox/review/launch.js +52 -92
- package/dist/clients/inbox/review/nvim.d.ts +2 -0
- package/dist/clients/inbox/review/nvim.js +14 -12
- package/dist/clients/inbox/review/review-client.d.ts +12 -8
- package/dist/clients/inbox/review/review-client.js +46 -35
- package/dist/clients/inbox/review-adapter.d.ts +3 -10
- package/dist/clients/inbox/review-adapter.js +27 -19
- package/dist/clients/inbox/surface.d.ts +0 -4
- package/dist/clients/inbox/surface.js +0 -2
- package/dist/clients/surfaces/host.d.ts +11 -3
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
- package/dist/commands/__tests__/human.test.js +11 -322
- package/dist/commands/api-client.d.ts +5 -5
- package/dist/commands/api-client.js +6 -85
- package/dist/commands/canvas-browse.js +3 -29
- package/dist/commands/canvas-config.js +1 -1
- package/dist/commands/canvas-use.js +3 -3
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/cron.js +5 -1
- package/dist/commands/human/queue.d.ts +0 -4
- package/dist/commands/human/queue.js +7 -40
- package/dist/commands/memory/list.d.ts +14 -0
- package/dist/commands/memory/list.js +35 -31
- package/dist/commands/memory/read.d.ts +7 -0
- package/dist/commands/memory/read.js +14 -8
- package/dist/commands/memory/write.js +13 -12
- package/dist/commands/node/bash.d.ts +1 -0
- package/dist/commands/node/bash.js +198 -0
- package/dist/commands/node/create.d.ts +23 -0
- package/dist/commands/node/create.js +207 -0
- package/dist/commands/node/inspect.d.ts +2 -0
- package/dist/commands/node/inspect.js +302 -0
- package/dist/commands/node/lifecycle.d.ts +4 -0
- package/dist/commands/node/lifecycle.js +415 -0
- package/dist/commands/node/message.d.ts +1 -0
- package/dist/commands/node/message.js +164 -0
- package/dist/commands/node/pyramid.d.ts +2 -0
- package/dist/commands/node/pyramid.js +79 -0
- package/dist/commands/node/subscription.d.ts +1 -0
- package/dist/commands/node/subscription.js +82 -0
- package/dist/commands/node/wait.d.ts +1 -0
- package/dist/commands/node/wait.js +159 -0
- package/dist/commands/node-lifecycle-revive.js +10 -57
- package/dist/commands/node.d.ts +0 -42
- package/dist/commands/node.js +11 -2065
- package/dist/commands/search.js +1 -1
- package/dist/commands/surface/node/cycle.d.ts +1 -0
- package/dist/commands/surface/node/cycle.js +83 -0
- package/dist/commands/surface/node/focus.d.ts +1 -0
- package/dist/commands/surface/node/focus.js +67 -0
- package/dist/commands/surface/node/id.d.ts +1 -0
- package/dist/commands/surface/node/id.js +38 -0
- package/dist/commands/surface/node/pin.d.ts +1 -0
- package/dist/commands/surface/node/pin.js +42 -0
- package/dist/commands/surface/node/placement.d.ts +46 -0
- package/dist/commands/surface/node/placement.js +124 -0
- package/dist/commands/surface-node.js +4 -1
- package/dist/commands/surface-reload.js +1 -2
- package/dist/commands/surface-tmux-spread.js +1 -1
- package/dist/commands/surface.js +5 -20
- package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
- package/dist/commands/sys/config.js +6 -6
- package/dist/commands/sys/logs.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
- package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
- package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
- package/dist/commands/sys/panels/dependencies-panel.js +80 -0
- package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
- package/dist/commands/sys/panels/keybindings-panel.js +703 -0
- package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
- package/dist/commands/sys/panels/keys-panel.js +60 -0
- package/dist/commands/sys/panels/models-panel.d.ts +77 -0
- package/dist/commands/sys/panels/models-panel.js +647 -0
- package/dist/commands/sys/panels/panel.d.ts +45 -0
- package/dist/commands/sys/panels/panel.js +137 -0
- package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
- package/dist/commands/sys/panels/plugins-panel.js +80 -0
- package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
- package/dist/commands/sys/panels/prefs-panel.js +85 -0
- package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
- package/dist/commands/sys/panels/provider-panel.js +538 -0
- package/dist/commands/sys/settings-shell.d.ts +55 -0
- package/dist/commands/sys/settings-shell.js +400 -0
- package/dist/commands/sys/settings.d.ts +2 -0
- package/dist/commands/sys/settings.js +31 -0
- package/dist/commands/sys/setup-core.d.ts +3 -33
- package/dist/commands/sys/setup-core.js +27 -78
- package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
- package/dist/commands/sys/setup-settings-runner.js +63 -0
- package/dist/commands/sys/setup-wizard.d.ts +26 -125
- package/dist/commands/sys/setup-wizard.js +209 -2473
- package/dist/commands/sys/setup.js +5 -7
- package/dist/commands/sys.js +3 -2
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
- package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
- package/dist/core/__tests__/broker-preflight.test.js +1 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
- package/dist/core/__tests__/canvas.test.js +2 -36
- package/dist/core/__tests__/close.test.js +14 -3
- package/dist/core/__tests__/context-intro.test.js +32 -143
- package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
- package/dist/core/__tests__/daemon-boot.test.js +2 -20
- package/dist/core/__tests__/daemon-wedge.test.js +1 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +4 -98
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
- package/dist/core/__tests__/helpers/broker-clients.js +0 -14
- package/dist/core/__tests__/helpers/harness.d.ts +0 -8
- package/dist/core/__tests__/helpers/harness.js +7 -87
- package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
- package/dist/core/__tests__/kickoff.test.js +1 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
- package/dist/core/__tests__/migration.test.js +35 -48
- package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
- package/dist/core/__tests__/passive-subscription.test.js +26 -49
- package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
- package/dist/core/__tests__/prune.test.js +94 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -32
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
- package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
- package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
- package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
- package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
- package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
- package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
- package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
- package/dist/core/__tests__/secrets.test.js +1 -7
- package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
- package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
- package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
- package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
- package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
- package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
- package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
- package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
- package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
- package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
- package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
- package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
- package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
- package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
- package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
- package/dist/core/__tests__/session-model.test.js +0 -18
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
- package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
- package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
- package/dist/core/broker-client/client.d.ts +2 -2
- package/dist/core/broker-client/client.js +4 -7
- package/dist/core/broker-client/transport-relay.d.ts +13 -19
- package/dist/core/broker-client/transport-relay.js +19 -34
- package/dist/core/broker-client/transport-socket.d.ts +2 -2
- package/dist/core/broker-client/transport-socket.js +9 -2
- package/dist/core/broker-client/transport.d.ts +7 -3
- package/dist/core/broker-client/transport.js +4 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -18
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
- package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
- package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
- package/dist/core/canvas/browse/app.d.ts +2 -17
- package/dist/core/canvas/browse/app.js +16 -88
- package/dist/core/canvas/browse/model.d.ts +0 -4
- package/dist/core/canvas/browse/model.js +1 -12
- package/dist/core/canvas/browse/render.js +6 -3
- package/dist/core/canvas/crons.d.ts +8 -5
- package/dist/core/canvas/crons.js +7 -6
- package/dist/core/canvas/extensions.d.ts +7 -3
- package/dist/core/canvas/extensions.js +16 -4
- package/dist/core/canvas/nav-model.d.ts +0 -4
- package/dist/core/canvas/nav-model.js +2 -14
- package/dist/core/canvas/node-order.d.ts +3 -0
- package/dist/core/canvas/node-order.js +12 -0
- package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
- package/dist/core/canvas/remote-canvas-source.js +8 -15
- package/dist/core/command.js +11 -4
- package/dist/core/config.js +3 -1
- package/dist/core/events/envelope.js +1 -1
- package/dist/core/events/read.js +7 -21
- package/dist/core/events/source.d.ts +0 -2
- package/dist/core/events/source.js +0 -16
- package/dist/core/events/types.d.ts +1 -1
- package/dist/core/fault-classifier.d.ts +1 -1
- package/dist/core/feed/passive.d.ts +0 -11
- package/dist/core/feed/passive.js +1 -62
- package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
- package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
- package/dist/core/keybindings/background-bash.js +3 -4
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/memory/inline-ref-grammar.js +3 -3
- package/dist/core/memory-resolver.d.ts +11 -25
- package/dist/core/memory-resolver.js +51 -33
- package/dist/core/model-routes.d.ts +15 -0
- package/dist/core/model-routes.js +12 -0
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/preview-registry.js +8 -9
- package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
- package/dist/core/review/realize.d.ts +0 -13
- package/dist/core/review/realize.js +0 -40
- package/dist/core/review/types.d.ts +1 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
- package/dist/core/runtime/bearings.js +1 -11
- package/dist/core/runtime/broker/client-registry.d.ts +33 -0
- package/dist/core/runtime/broker/client-registry.js +164 -0
- package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
- package/dist/core/runtime/broker/daemon-ops.js +49 -0
- package/dist/core/runtime/broker/event-projection.d.ts +42 -0
- package/dist/core/runtime/broker/event-projection.js +178 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
- package/dist/core/runtime/broker/fault-retry.js +277 -0
- package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
- package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
- package/dist/core/runtime/broker/inbox.d.ts +22 -0
- package/dist/core/runtime/broker/inbox.js +167 -0
- package/dist/core/runtime/broker/passive.d.ts +16 -0
- package/dist/core/runtime/broker/passive.js +44 -0
- package/dist/core/runtime/broker/read-ops.d.ts +23 -0
- package/dist/core/runtime/broker/read-ops.js +150 -0
- package/dist/core/runtime/broker/rebind.d.ts +74 -0
- package/dist/core/runtime/broker/rebind.js +211 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
- package/dist/core/runtime/broker/tool-groups.js +244 -0
- package/dist/core/runtime/broker-extension-render.d.ts +11 -0
- package/dist/core/runtime/broker-extension-render.js +181 -0
- package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
- package/dist/core/runtime/broker-persona-guidance.js +58 -0
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/broker-protocol.js +1 -1
- package/dist/core/runtime/broker.d.ts +5 -196
- package/dist/core/runtime/broker.js +276 -3059
- package/dist/core/runtime/canvas-extensions.js +11 -2
- package/dist/core/runtime/fault.js +1 -1
- package/dist/core/runtime/model-selection.d.ts +9 -0
- package/dist/core/runtime/model-selection.js +12 -0
- package/dist/core/runtime/model-swap.d.ts +3 -3
- package/dist/core/runtime/model-swap.js +33 -25
- package/dist/core/runtime/placement-tmux.d.ts +3 -14
- package/dist/core/runtime/placement-tmux.js +11 -80
- package/dist/core/runtime/placement.d.ts +4 -2
- package/dist/core/runtime/placement.js +7 -12
- package/dist/core/runtime/promote.d.ts +14 -1
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/reset.d.ts +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/runtime/spawn.d.ts +8 -0
- package/dist/core/runtime/spawn.js +36 -6
- package/dist/core/runtime/stop-guard.d.ts +4 -3
- package/dist/core/runtime/stop-guard.js +36 -18
- package/dist/core/runtime/stop-signals.d.ts +4 -1
- package/dist/core/runtime/stream-watchdog.js +4 -5
- package/dist/core/runtime/structured-output.d.ts +15 -2
- package/dist/core/runtime/structured-output.js +35 -12
- package/dist/core/runtime/tmux-bindings.d.ts +25 -0
- package/dist/core/runtime/tmux-bindings.js +682 -0
- package/dist/core/runtime/tmux-chrome.d.ts +2 -1
- package/dist/core/runtime/tmux-chrome.js +3 -2
- package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
- package/dist/core/runtime/tmux-driver.js +598 -0
- package/dist/core/runtime/view-socket.d.ts +14 -0
- package/dist/core/runtime/view-socket.js +83 -0
- package/dist/core/session-model/session-state.d.ts +1 -2
- package/dist/core/session-model/session-state.js +5 -8
- package/dist/core/spawn.d.ts +1 -1
- package/dist/core/spawn.js +2 -2
- package/dist/core/substrate/gate.d.ts +1 -1
- package/dist/core/substrate/on-read-pure.d.ts +7 -0
- package/dist/core/substrate/on-read-pure.js +272 -0
- package/dist/core/termrender/termrender.js +32 -2
- package/dist/core/user-settings.d.ts +23 -1
- package/dist/core/user-settings.js +18 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
- package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
- package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
- package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
- package/dist/daemon/api/bridge.js +40 -81
- package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
- package/dist/daemon/api/handlers/broker-ops.js +383 -0
- package/dist/daemon/api/handlers/crons.js +9 -4
- package/dist/daemon/api/handlers/files.js +6 -7
- package/dist/daemon/api/handlers/inbox.js +2 -340
- package/dist/daemon/api/handlers/nodes.d.ts +10 -1
- package/dist/daemon/api/handlers/nodes.js +74 -39
- package/dist/daemon/api/handlers/review-comments.js +5 -1
- package/dist/daemon/api/handlers/reviews.js +0 -19
- package/dist/daemon/api/map.js +25 -4
- package/dist/daemon/api/router.js +2 -3
- package/dist/daemon/api/server.js +5 -7
- package/dist/daemon/cron-run.d.ts +4 -0
- package/dist/daemon/cron-run.js +30 -13
- package/dist/daemon/crtrd.d.ts +3 -58
- package/dist/daemon/crtrd.js +28 -1244
- package/dist/daemon/manage.js +0 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
- package/dist/daemon/reconcilers/broker-supervision.js +549 -0
- package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
- package/dist/daemon/reconcilers/cron-lane.js +32 -0
- package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
- package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
- package/dist/daemon/review/finish.js +2 -5
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
- package/dist/pi-extensions/broker-local.d.ts +20 -0
- package/dist/pi-extensions/broker-local.js +89 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
- package/dist/pi-extensions/canvas-context-intro.js +22 -11
- package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
- package/dist/pi-extensions/canvas-goal-capture.js +7 -12
- package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
- package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
- package/dist/pi-extensions/canvas-passive-context.js +22 -18
- package/dist/pi-extensions/canvas-recap.d.ts +2 -2
- package/dist/pi-extensions/canvas-recap.js +48 -21
- package/dist/pi-extensions/canvas-review-boundary.js +10 -4
- package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
- package/dist/pi-extensions/canvas-stophook.js +149 -431
- package/dist/pi-extensions/canvas-structured-output.js +52 -30
- package/dist/pi-extensions/envelope-merge.d.ts +13 -0
- package/dist/pi-extensions/envelope-merge.js +29 -0
- package/dist/shared/working-activity.d.ts +3 -2
- package/dist/shared/working-activity.js +3 -2
- package/dist/types.d.ts +6 -5
- package/dist/types.js +2 -2
- package/docs/compat/hearth-crtr-v1.md +4 -12
- package/docs/compat/hearth-crtr-v2.md +3 -11
- package/docs/compat/hearth-crtr-v3.md +4 -12
- package/docs/compat/hearth-crtr-v4.md +3 -11
- package/docs/compat/hearth-crtr-v5.md +3 -11
- package/docs/public-api.md +3 -7
- package/package.json +7 -49
- package/runtime.lock.json +2766 -14533
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
- package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
- package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
- package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
- package/dist/clients/conversation/conversation.d.ts +0 -65
- package/dist/clients/conversation/conversation.js +0 -318
- package/dist/clients/conversation/frames.d.ts +0 -30
- package/dist/clients/conversation/frames.js +0 -52
- package/dist/clients/conversation/region.d.ts +0 -51
- package/dist/clients/conversation/region.js +0 -265
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
- package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
- package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
- package/dist/clients/inbox/review/columns.d.ts +0 -22
- package/dist/clients/inbox/review/columns.js +0 -40
- package/dist/clients/inbox/review/composition.d.ts +0 -60
- package/dist/clients/inbox/review/composition.js +0 -278
- package/dist/clients/inbox/review/document-region.d.ts +0 -120
- package/dist/clients/surfaces/region.d.ts +0 -16
- package/dist/clients/web/__tests__/push-engine.test.js +0 -158
- package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
- package/dist/clients/web/__tests__/push-registry.test.js +0 -177
- package/dist/clients/web/dev-server.d.ts +0 -7
- package/dist/clients/web/dev-server.js +0 -46
- package/dist/clients/web/events.d.ts +0 -19
- package/dist/clients/web/events.js +0 -163
- package/dist/clients/web/push-engine.d.ts +0 -44
- package/dist/clients/web/push-engine.js +0 -125
- package/dist/clients/web/push-registry.d.ts +0 -85
- package/dist/clients/web/push-registry.js +0 -373
- package/dist/clients/web/server.d.ts +0 -19
- package/dist/clients/web/server.js +0 -661
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
- package/dist/clients/web/web-client/shared/protocol.js +0 -8
- package/dist/clients/web/web-cmd.d.ts +0 -2
- package/dist/clients/web/web-cmd.js +0 -141
- package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
- package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
- package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
- package/dist/commands/__tests__/canvas-config.test.js +0 -107
- package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
- package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
- package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
- package/dist/commands/__tests__/search-contents.test.js +0 -52
- package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/lint.test.js +0 -15
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
- package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
- package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
- package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
- package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
- package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
- package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
- package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
- package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
- package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
- package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
- package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
- package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
- package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
- package/dist/core/__tests__/finalization-migration.test.js +0 -38
- package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
- package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
- package/dist/core/__tests__/fork.test.d.ts +0 -1
- package/dist/core/__tests__/fork.test.js +0 -108
- package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
- package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
- package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
- package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
- package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
- package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
- package/dist/core/__tests__/full/cascade-close.test.js +0 -240
- package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/detach-focus.test.js +0 -126
- package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
- package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
- package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
- package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.js +0 -60
- package/dist/core/__tests__/model-routes.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes.test.js +0 -41
- package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-identity.test.js +0 -61
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
- package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
- package/dist/core/__tests__/prune-to-limit.test.js +0 -126
- package/dist/core/__tests__/reset.test.d.ts +0 -1
- package/dist/core/__tests__/reset.test.js +0 -69
- package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
- package/dist/core/__tests__/steer-note.test.d.ts +0 -1
- package/dist/core/__tests__/steer-note.test.js +0 -41
- package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
- package/dist/core/__tests__/subcommand-tier.test.js +0 -99
- package/dist/core/__tests__/subscription-delivery.test.js +0 -211
- package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
- package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
- package/dist/core/__tests__/tmux-surface.test.js +0 -484
- package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
- package/dist/core/__tests__/wake-bearings.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
- package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
- package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
- package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
- package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
- package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
- package/dist/core/canvas/remote-event-stream.d.ts +0 -24
- package/dist/core/canvas/remote-event-stream.js +0 -94
- package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
- package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
- package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
- package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
- package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
- package/dist/core/human/__tests__/visible-paths.test.js +0 -28
- package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
- package/dist/core/review/__tests__/project.test.d.ts +0 -1
- package/dist/core/review/__tests__/project.test.js +0 -71
- package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
- package/dist/core/runtime/tmux.js +0 -1314
- package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
- package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/inbox.test.js +0 -489
- package/dist/web-client/apple-touch-icon.png +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
- package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
- package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
- package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
- package/dist/web-client/icon-192.png +0 -0
- package/dist/web-client/icon-512.png +0 -0
- package/dist/web-client/icon-maskable-512.png +0 -0
- package/dist/web-client/index.html +0 -17
- package/dist/web-client/manifest.webmanifest +0 -1
- package/dist/web-client/sw.js +0 -1
- /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
- /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
- /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
- /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
- /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
- /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
- /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
- /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
- /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
- /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
- /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
- /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
- /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
- /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
- /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
- /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
- /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// remote-event-stream.test.ts — `RemoteEventStream` (`../remote-event-stream.ts`),
|
|
2
|
-
// a manual SSE client over `/__crtr/events`. Covers the wire parse (only
|
|
3
|
-
// known `kind`s fire listeners; comments/pings/unknown kinds are silently
|
|
4
|
-
// ignored) and that `stop()` actually halts the reconnect loop rather than
|
|
5
|
-
// leaving it retrying forever in the background.
|
|
6
|
-
//
|
|
7
|
-
// Reconnect/backoff timing uses an INJECTABLE backoff (`RemoteEventStreamOptions`)
|
|
8
|
-
// so these tests run against a small, fast backoff window instead of the
|
|
9
|
-
// production 1s→30s one, and every wait is a condition-poll on an observed
|
|
10
|
-
// request/event count (`waitFor`) rather than a fixed wall-clock sleep —
|
|
11
|
-
// less flaky under scheduler variance, and fast.
|
|
12
|
-
import { test } from 'node:test';
|
|
13
|
-
import assert from 'node:assert/strict';
|
|
14
|
-
import { createServer } from 'node:http';
|
|
15
|
-
import { RemoteEventStream } from '../remote-event-stream.js';
|
|
16
|
-
function startSseServer(onRequest) {
|
|
17
|
-
return new Promise((resolve) => {
|
|
18
|
-
let hits = 0;
|
|
19
|
-
const requests = [];
|
|
20
|
-
const server = createServer((req, res) => {
|
|
21
|
-
hits += 1;
|
|
22
|
-
requests.push({ method: req.method, url: req.url ?? '', headers: req.headers });
|
|
23
|
-
onRequest(res, req);
|
|
24
|
-
});
|
|
25
|
-
server.listen(0, '127.0.0.1', () => {
|
|
26
|
-
const addr = server.address();
|
|
27
|
-
const port = typeof addr === 'object' && addr !== null ? addr.port : 0;
|
|
28
|
-
resolve({
|
|
29
|
-
url: `http://127.0.0.1:${port}`,
|
|
30
|
-
hitCount: () => hits,
|
|
31
|
-
requests,
|
|
32
|
-
close: () => new Promise((res) => server.close(() => res())),
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
/** Poll `predicate` until it's true, or throw after `timeoutMs` — used in
|
|
38
|
-
* place of a fixed sleep so tests assert on the OBSERVED condition (a
|
|
39
|
-
* request landed, an event fired) rather than a guessed timing window. */
|
|
40
|
-
async function waitFor(predicate, timeoutMs = 2000, intervalMs = 5) {
|
|
41
|
-
const deadline = Date.now() + timeoutMs;
|
|
42
|
-
while (!predicate()) {
|
|
43
|
-
if (Date.now() > deadline)
|
|
44
|
-
throw new Error(`waitFor: condition not met within ${timeoutMs}ms`);
|
|
45
|
-
await new Promise((r) => setTimeout(r, intervalMs));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
test('a listener fires once per known-kind SSE event, and never for a ping or an unknown kind', async (t) => {
|
|
49
|
-
const server = await startSseServer((res) => {
|
|
50
|
-
res.writeHead(200, { 'content-type': 'text/event-stream' });
|
|
51
|
-
res.write(': connected\n\n');
|
|
52
|
-
res.write('data: {"kind":"nodes"}\n\n');
|
|
53
|
-
res.write(': ping\n\n');
|
|
54
|
-
res.write('data: {"kind":"bogus"}\n\n');
|
|
55
|
-
res.end();
|
|
56
|
-
});
|
|
57
|
-
const stream = new RemoteEventStream(server.url, 'tok');
|
|
58
|
-
// Register cleanup BEFORE any assertion runs — a thrown assertion must not
|
|
59
|
-
// leave the client's reconnect loop or the server's listening socket alive
|
|
60
|
-
// (see the CI-hang postmortem on rebuild-coalescer.test.ts).
|
|
61
|
-
t.after(() => { stream.stop(); return server.close(); });
|
|
62
|
-
const seen = [];
|
|
63
|
-
stream.subscribe((kind) => seen.push(kind));
|
|
64
|
-
stream.start();
|
|
65
|
-
await waitFor(() => seen.length > 0);
|
|
66
|
-
stream.stop();
|
|
67
|
-
assert.deepEqual(seen, ['nodes']);
|
|
68
|
-
});
|
|
69
|
-
test('the SSE connection carries the token ONLY in the Authorization header — not in the URL or any other header', async (t) => {
|
|
70
|
-
const server = await startSseServer((res) => {
|
|
71
|
-
res.writeHead(200, { 'content-type': 'text/event-stream' });
|
|
72
|
-
res.end();
|
|
73
|
-
});
|
|
74
|
-
// A token that cannot collide with a hostname/port (unlike 'tok', which is a
|
|
75
|
-
// substring of numeric-looking noise) so a pass here can't be a coincidence —
|
|
76
|
-
// no header, including Host, is permitted to carry it.
|
|
77
|
-
const token = 'secret-sse-token-value';
|
|
78
|
-
const stream = new RemoteEventStream(server.url, token);
|
|
79
|
-
t.after(() => { stream.stop(); return server.close(); });
|
|
80
|
-
stream.start();
|
|
81
|
-
await waitFor(() => server.requests.length > 0);
|
|
82
|
-
stream.stop();
|
|
83
|
-
assert.equal(server.requests.length, 1);
|
|
84
|
-
const req = server.requests[0];
|
|
85
|
-
assert.equal(req.method, 'GET');
|
|
86
|
-
assert.equal(req.url, '/__crtr/events');
|
|
87
|
-
assert.equal(req.headers['authorization'], `Bearer ${token}`);
|
|
88
|
-
for (const [k, v] of Object.entries(req.headers)) {
|
|
89
|
-
if (k.toLowerCase() === 'authorization')
|
|
90
|
-
continue;
|
|
91
|
-
assert.ok(!String(v).includes(token), `header ${k} must not carry the token`);
|
|
92
|
-
}
|
|
93
|
-
assert.ok(!req.url.includes(token));
|
|
94
|
-
});
|
|
95
|
-
test('stop() cancels a pending reconnect timer — no zombie loop survives a stop()+start() cycle', async (t) => {
|
|
96
|
-
const server = await startSseServer((res) => {
|
|
97
|
-
res.writeHead(500);
|
|
98
|
-
res.end();
|
|
99
|
-
});
|
|
100
|
-
// A small injected backoff (200ms, not production's 1s) — the test asserts
|
|
101
|
-
// the SAME relative-timing invariant (a stopped loop's dangling reconnect
|
|
102
|
-
// timer must not fire) but the deliberate gap below (half the backoff)
|
|
103
|
-
// between the stale deadline and the new deadline is kept proportionally
|
|
104
|
-
// wide enough that ordinary event-loop/scheduler jitter can't flip it.
|
|
105
|
-
const BACKOFF = 200;
|
|
106
|
-
const stream = new RemoteEventStream(server.url, 'tok', { initialBackoffMs: BACKOFF });
|
|
107
|
-
t.after(() => { stream.stop(); return server.close(); });
|
|
108
|
-
stream.start();
|
|
109
|
-
// t≈0: first request fires+fails, backoff(BACKOFF) scheduled → stale deadline ≈ BACKOFF.
|
|
110
|
-
await waitFor(() => server.hitCount() >= 1);
|
|
111
|
-
assert.equal(server.hitCount(), 1);
|
|
112
|
-
// Deliberate mid-backoff gap (half the window) before stop()+start(), so the
|
|
113
|
-
// stale deadline (hit1 + BACKOFF) and the new loop's own deadline
|
|
114
|
-
// (hit2 + BACKOFF) land ~BACKOFF/2 apart — the window this test inspects.
|
|
115
|
-
await new Promise((r) => setTimeout(r, BACKOFF / 2));
|
|
116
|
-
stream.stop();
|
|
117
|
-
stream.start();
|
|
118
|
-
await waitFor(() => server.hitCount() >= 2);
|
|
119
|
-
assert.equal(server.hitCount(), 2, 'restart fires its own immediate request');
|
|
120
|
-
// Wait past the STALE timer's deadline (~BACKOFF from the first request) but
|
|
121
|
-
// well before the NEW loop's own deadline (~BACKOFF from the second,
|
|
122
|
-
// later, request). A dangling old-loop timer (bug) would add a 3rd hit in
|
|
123
|
-
// this window; a cleared one (fixed) leaves it at 2.
|
|
124
|
-
await new Promise((r) => setTimeout(r, BACKOFF * 0.7));
|
|
125
|
-
assert.equal(server.hitCount(), 2, "no zombie request from the stopped loop's dangling timer");
|
|
126
|
-
});
|
|
127
|
-
test('stop() halts the reconnect loop — no further requests after it is called', async (t) => {
|
|
128
|
-
const server = await startSseServer((res) => {
|
|
129
|
-
// Every connection is refused immediately (no SSE headers, just a close)
|
|
130
|
-
// so the client's loop falls into its backoff-and-retry path.
|
|
131
|
-
res.writeHead(500);
|
|
132
|
-
res.end();
|
|
133
|
-
});
|
|
134
|
-
const BACKOFF = 20;
|
|
135
|
-
const stream = new RemoteEventStream(server.url, 'tok', { initialBackoffMs: BACKOFF });
|
|
136
|
-
t.after(() => { stream.stop(); return server.close(); });
|
|
137
|
-
stream.start();
|
|
138
|
-
await waitFor(() => server.hitCount() >= 1);
|
|
139
|
-
const hitsAtStop = server.hitCount();
|
|
140
|
-
stream.stop();
|
|
141
|
-
// The reconnect backoff is BACKOFF ms; wait well past it and confirm no new
|
|
142
|
-
// connection was attempted — proves the loop actually stopped rather than
|
|
143
|
-
// continuing to retry in the background after stop() returned.
|
|
144
|
-
await new Promise((r) => setTimeout(r, BACKOFF * 5));
|
|
145
|
-
assert.equal(server.hitCount(), hitsAtStop);
|
|
146
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
// source-resolve.test.ts — `resolveCanvasSource` (`../source.ts`), the
|
|
2
|
-
// --canvas > activeCanvas > local precedence a command's read path goes
|
|
3
|
-
// through. The one invariant worth pinning: the local case returns the SAME
|
|
4
|
-
// `localCanvasSource` singleton by identity, not a structurally-equal copy —
|
|
5
|
-
// callers that hold onto a source reference (e.g. `canvas browse`'s
|
|
6
|
-
// `instanceof RemoteCanvasSource` checks) depend on that.
|
|
7
|
-
import { test, before, after, beforeEach } from 'node:test';
|
|
8
|
-
import assert from 'node:assert/strict';
|
|
9
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
10
|
-
import { tmpdir } from 'node:os';
|
|
11
|
-
import { join } from 'node:path';
|
|
12
|
-
import { resolveCanvasSource, localCanvasSource } from '../source.js';
|
|
13
|
-
import { RemoteCanvasSource } from '../remote-canvas-source.js';
|
|
14
|
-
import { updateConfig, updateState } from '../../config.js';
|
|
15
|
-
import { setRelayToken } from '../../secrets.js';
|
|
16
|
-
let home;
|
|
17
|
-
let realHome;
|
|
18
|
-
before(() => {
|
|
19
|
-
realHome = process.env['HOME'];
|
|
20
|
-
home = mkdtempSync(join(tmpdir(), 'crtr-source-resolve-'));
|
|
21
|
-
process.env['HOME'] = home;
|
|
22
|
-
});
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
rmSync(home, { recursive: true, force: true });
|
|
25
|
-
});
|
|
26
|
-
after(() => {
|
|
27
|
-
rmSync(home, { recursive: true, force: true });
|
|
28
|
-
if (realHome !== undefined)
|
|
29
|
-
process.env['HOME'] = realHome;
|
|
30
|
-
else
|
|
31
|
-
delete process.env['HOME'];
|
|
32
|
-
});
|
|
33
|
-
test('no --canvas and no activeCanvas resolves to the local singleton by identity', () => {
|
|
34
|
-
const source = resolveCanvasSource();
|
|
35
|
-
assert.equal(source, localCanvasSource);
|
|
36
|
-
});
|
|
37
|
-
test('an explicit canvasName wins over local, even with no activeCanvas set', () => {
|
|
38
|
-
updateConfig('user', (cfg) => {
|
|
39
|
-
cfg.remoteCanvas.targets['cloud'] = { previewEndpoint: 'https://x.preview.bl.run', relayTokenRef: 'cloud' };
|
|
40
|
-
});
|
|
41
|
-
setRelayToken('cloud', 'tok', 'user');
|
|
42
|
-
const source = resolveCanvasSource({ canvasName: 'cloud' });
|
|
43
|
-
assert.ok(source instanceof RemoteCanvasSource);
|
|
44
|
-
assert.notEqual(source, localCanvasSource);
|
|
45
|
-
});
|
|
46
|
-
test('the durable activeCanvas selection is honored when no explicit canvasName is passed', () => {
|
|
47
|
-
updateConfig('user', (cfg) => {
|
|
48
|
-
cfg.remoteCanvas.targets['cloud'] = { previewEndpoint: 'https://x.preview.bl.run', relayTokenRef: 'cloud' };
|
|
49
|
-
});
|
|
50
|
-
setRelayToken('cloud', 'tok', 'user');
|
|
51
|
-
updateState('user', (s) => {
|
|
52
|
-
s.activeCanvas = 'cloud';
|
|
53
|
-
});
|
|
54
|
-
const source = resolveCanvasSource();
|
|
55
|
-
assert.ok(source instanceof RemoteCanvasSource);
|
|
56
|
-
});
|
|
57
|
-
test('an explicit --canvas wins over a different durable activeCanvas selection', () => {
|
|
58
|
-
updateConfig('user', (cfg) => {
|
|
59
|
-
cfg.remoteCanvas.targets['cloud-a'] = { previewEndpoint: 'https://a.preview.bl.run', relayTokenRef: 'cloud-a' };
|
|
60
|
-
cfg.remoteCanvas.targets['cloud-b'] = { previewEndpoint: 'https://b.preview.bl.run', relayTokenRef: 'cloud-b' };
|
|
61
|
-
});
|
|
62
|
-
setRelayToken('cloud-a', 'tok-a', 'user');
|
|
63
|
-
setRelayToken('cloud-b', 'tok-b', 'user');
|
|
64
|
-
updateState('user', (s) => {
|
|
65
|
-
s.activeCanvas = 'cloud-a';
|
|
66
|
-
});
|
|
67
|
-
const source = resolveCanvasSource({ canvasName: 'cloud-b' });
|
|
68
|
-
assert.ok(source instanceof RemoteCanvasSource);
|
|
69
|
-
assert.equal(source.previewEndpoint, 'https://b.preview.bl.run');
|
|
70
|
-
});
|
|
71
|
-
test('activeCanvas set to null (explicit local) falls back to the local singleton', () => {
|
|
72
|
-
updateState('user', (s) => {
|
|
73
|
-
s.activeCanvas = null;
|
|
74
|
-
});
|
|
75
|
-
const source = resolveCanvasSource();
|
|
76
|
-
assert.equal(source, localCanvasSource);
|
|
77
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { test } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import { buildTree, flatten, fuzzyMatch, pruneNode, tabPredicate, TABS, attentionTier, attentionMtime } from '../model.js';
|
|
4
|
-
// ── Fixture canvas ───────────────────────────────────────────────────────────
|
|
5
|
-
// root1 (active) ← rank 0
|
|
6
|
-
// child-a (idle)
|
|
7
|
-
// grand-x (done)
|
|
8
|
-
// child-b (active, ⚑2)
|
|
9
|
-
// root2 (done) ← rank 2 (dormant root, but ancestor of a live node)
|
|
10
|
-
// child-c (active)
|
|
11
|
-
// lonely (idle) ← straggler: in rows, no edge reaches it, not a root
|
|
12
|
-
function row(node_id, name, status, asks = 0) {
|
|
13
|
-
return { node_id, name, status, kind: 'general', mode: 'base', ctx_tokens: 0, asks, cwd: '/tmp/proj', created: '2026-01-01T00:00:00.000Z' };
|
|
14
|
-
}
|
|
15
|
-
function lrow(node_id, name, status, lifecycle) {
|
|
16
|
-
return { ...row(node_id, name, status), lifecycle };
|
|
17
|
-
}
|
|
18
|
-
const ROWS = [
|
|
19
|
-
row('root1', 'root-one', 'active'),
|
|
20
|
-
row('child-a', 'child-a', 'idle'),
|
|
21
|
-
row('grand-x', 'grand-x', 'done'),
|
|
22
|
-
row('child-b', 'child-b', 'active', 2),
|
|
23
|
-
row('root2', 'root-two', 'done'),
|
|
24
|
-
row('child-c', 'child-c', 'active'),
|
|
25
|
-
row('lonely', 'lonely-node', 'idle'),
|
|
26
|
-
];
|
|
27
|
-
// rootIds intentionally unsorted to prove buildTree sorts live-first.
|
|
28
|
-
const ROOT_IDS = ['root2', 'root1'];
|
|
29
|
-
const CHILDREN = {
|
|
30
|
-
root1: ['child-a', 'child-b'],
|
|
31
|
-
'child-a': ['grand-x'],
|
|
32
|
-
root2: ['child-c'],
|
|
33
|
-
};
|
|
34
|
-
const childIdsOf = (id) => CHILDREN[id] ?? [];
|
|
35
|
-
function tree() {
|
|
36
|
-
return buildTree(ROWS, ROOT_IDS, childIdsOf);
|
|
37
|
-
}
|
|
38
|
-
// ── fuzzyMatch ───────────────────────────────────────────────────────────────
|
|
39
|
-
test('fuzzyMatch: empty query matches everything', () => {
|
|
40
|
-
assert.equal(fuzzyMatch('', 'whatever'), true);
|
|
41
|
-
});
|
|
42
|
-
test('fuzzyMatch: case-insensitive subsequence', () => {
|
|
43
|
-
assert.equal(fuzzyMatch('abc', 'aXbXc'), true);
|
|
44
|
-
assert.equal(fuzzyMatch('AB', 'xaYbz'), true);
|
|
45
|
-
assert.equal(fuzzyMatch('grandx', 'grand-x'), true);
|
|
46
|
-
});
|
|
47
|
-
test('fuzzyMatch: out-of-order is not a match', () => {
|
|
48
|
-
assert.equal(fuzzyMatch('abc', 'acb'), false);
|
|
49
|
-
assert.equal(fuzzyMatch('zz', 'z'), false);
|
|
50
|
-
});
|
|
51
|
-
// ── buildTree ────────────────────────────────────────────────────────────────
|
|
52
|
-
test('buildTree: roots sorted live-first, stragglers appended', () => {
|
|
53
|
-
const t = tree();
|
|
54
|
-
assert.deepEqual(t.roots, ['root1', 'root2', 'lonely']);
|
|
55
|
-
});
|
|
56
|
-
test('buildTree: depth, parentId, childIds', () => {
|
|
57
|
-
const t = tree();
|
|
58
|
-
assert.equal(t.nodes.size, 7);
|
|
59
|
-
assert.deepEqual(t.nodes.get('root1'), {
|
|
60
|
-
row: ROWS[0], depth: 0, parentId: null, childIds: ['child-a', 'child-b'],
|
|
61
|
-
});
|
|
62
|
-
assert.equal(t.nodes.get('child-a').depth, 1);
|
|
63
|
-
assert.equal(t.nodes.get('child-a').parentId, 'root1');
|
|
64
|
-
assert.deepEqual(t.nodes.get('child-a').childIds, ['grand-x']);
|
|
65
|
-
assert.equal(t.nodes.get('grand-x').depth, 2);
|
|
66
|
-
assert.equal(t.nodes.get('grand-x').parentId, 'child-a');
|
|
67
|
-
// straggler attaches at depth 0 with no parent
|
|
68
|
-
assert.equal(t.nodes.get('lonely').depth, 0);
|
|
69
|
-
assert.equal(t.nodes.get('lonely').parentId, null);
|
|
70
|
-
});
|
|
71
|
-
test('buildTree: unknown child ids are dropped (missing meta safe)', () => {
|
|
72
|
-
const t = buildTree(ROWS, ['root1'], (id) => (id === 'root1' ? ['child-a', 'ghost'] : childIdsOf(id)));
|
|
73
|
-
assert.deepEqual(t.nodes.get('root1').childIds, ['child-a']);
|
|
74
|
-
assert.equal(t.nodes.has('ghost'), false);
|
|
75
|
-
});
|
|
76
|
-
// ── pruneNode ────────────────────────────────────────────────────────────────
|
|
77
|
-
// Regression: pressing `x` in canvas browse on an EMPTY active node looked like a
|
|
78
|
-
// no-op — closeNode hard-deletes (reaps) an empty node, but doClose never removed
|
|
79
|
-
// it from the in-memory tree, so the stale active row kept painting. pruneNode is
|
|
80
|
-
// the splice doClose now applies for a reaped (getNode===null) close.
|
|
81
|
-
test('pruneNode: reaping a leaf removes it from its parent and the node map', () => {
|
|
82
|
-
const t = tree();
|
|
83
|
-
pruneNode(t, 'grand-x'); // leaf under child-a
|
|
84
|
-
assert.equal(t.nodes.has('grand-x'), false);
|
|
85
|
-
assert.deepEqual(t.nodes.get('child-a').childIds, []);
|
|
86
|
-
});
|
|
87
|
-
test('pruneNode: reaping a mid-tree node re-homes its children to its parent', () => {
|
|
88
|
-
const t = tree();
|
|
89
|
-
pruneNode(t, 'child-a'); // child-a (under root1) owns grand-x
|
|
90
|
-
assert.equal(t.nodes.has('child-a'), false);
|
|
91
|
-
// grand-x lifts into child-a's slot in root1's child order (before child-b).
|
|
92
|
-
assert.deepEqual(t.nodes.get('root1').childIds, ['grand-x', 'child-b']);
|
|
93
|
-
assert.equal(t.nodes.get('grand-x').parentId, 'root1');
|
|
94
|
-
});
|
|
95
|
-
test('pruneNode: reaping a root lifts its children into the root list', () => {
|
|
96
|
-
const t = tree();
|
|
97
|
-
const rootIdx = t.roots.indexOf('root2');
|
|
98
|
-
pruneNode(t, 'root2'); // root2 owns child-c
|
|
99
|
-
assert.equal(t.nodes.has('root2'), false);
|
|
100
|
-
assert.equal(t.roots.includes('root2'), false);
|
|
101
|
-
assert.equal(t.roots[rootIdx], 'child-c'); // child-c took root2's slot
|
|
102
|
-
assert.equal(t.nodes.get('child-c').parentId, null);
|
|
103
|
-
});
|
|
104
|
-
test('pruneNode: absent id is a no-op', () => {
|
|
105
|
-
const t = tree();
|
|
106
|
-
const before = t.nodes.size;
|
|
107
|
-
pruneNode(t, 'ghost');
|
|
108
|
-
assert.equal(t.nodes.size, before);
|
|
109
|
-
});
|
|
110
|
-
// ── tab predicates ───────────────────────────────────────────────────────────
|
|
111
|
-
test('tabPredicate: All / Live / Dormant / Attention / Pinned', () => {
|
|
112
|
-
assert.deepEqual([...TABS], ['All', 'Live', 'Dormant', 'Attention', 'Pinned']);
|
|
113
|
-
const active = ROWS[0]; // root1 active
|
|
114
|
-
const idle = ROWS[1]; // child-a idle
|
|
115
|
-
const done = ROWS[2]; // grand-x done
|
|
116
|
-
const attention = ROWS[3]; // child-b active asks 2
|
|
117
|
-
assert.equal(tabPredicate('All', done), true);
|
|
118
|
-
assert.equal(tabPredicate('Live', active), true);
|
|
119
|
-
assert.equal(tabPredicate('Live', idle), true);
|
|
120
|
-
assert.equal(tabPredicate('Live', done), false);
|
|
121
|
-
assert.equal(tabPredicate('Dormant', done), true);
|
|
122
|
-
assert.equal(tabPredicate('Dormant', active), false);
|
|
123
|
-
// Attention = pending asks OR a fault.
|
|
124
|
-
assert.equal(tabPredicate('Attention', attention), true);
|
|
125
|
-
assert.equal(tabPredicate('Attention', active), false);
|
|
126
|
-
assert.equal(tabPredicate('Attention', { ...active, asks: 0, hanging: { kind: 'provider' } }), true);
|
|
127
|
-
// Pinned reads the isPinned arg, not the row.
|
|
128
|
-
assert.equal(tabPredicate('Pinned', active), false);
|
|
129
|
-
assert.equal(tabPredicate('Pinned', active, true), true);
|
|
130
|
-
});
|
|
131
|
-
// ── flatten: pins ────────────────────────────────────────────────────────────
|
|
132
|
-
test('flatten: profile scope keeps only the launching profile, with ancestors for context', () => {
|
|
133
|
-
const profileRows = [
|
|
134
|
-
{ ...row('profile-root', 'profile-root', 'active'), profile_id: 'alpha-11111111' },
|
|
135
|
-
{ ...row('profile-child', 'profile-child', 'idle'), profile_id: 'beta-22222222' },
|
|
136
|
-
{ ...row('other-root', 'other-root', 'active'), profile_id: 'beta-22222222' },
|
|
137
|
-
];
|
|
138
|
-
const t = buildTree(profileRows, ['profile-root', 'other-root'], (id) => id === 'profile-root' ? ['profile-child'] : []);
|
|
139
|
-
const v = flatten(t, { collapsed: new Set(), tab: 'All', query: '', profileScope: 'alpha-11111111' });
|
|
140
|
-
assert.deepEqual(v.map((r) => r.id), ['profile-root']);
|
|
141
|
-
assert.equal(v[0].matched, true);
|
|
142
|
-
});
|
|
143
|
-
test('flatten: Pinned tab shows only pinned rows', () => {
|
|
144
|
-
const pinned = new Set(['child-c']);
|
|
145
|
-
const v = flatten(tree(), { collapsed: new Set(), tab: 'Pinned', query: '', pinned });
|
|
146
|
-
// child-c is directly matched; root2 rides along as its ancestor (context).
|
|
147
|
-
const matched = v.filter((r) => r.matched).map((r) => r.id);
|
|
148
|
-
assert.deepEqual(matched, ['child-c']);
|
|
149
|
-
});
|
|
150
|
-
test('flatten: pinned rows float to the top in a flat sort', () => {
|
|
151
|
-
const pinned = new Set(['lonely']); // an idle straggler that would otherwise sort late
|
|
152
|
-
const v = flatten(tree(), { collapsed: new Set(), tab: 'All', query: '', sort: 'recency', pinned });
|
|
153
|
-
assert.equal(v[0].id, 'lonely');
|
|
154
|
-
});
|
|
155
|
-
// ── flatten: collapse / expand ───────────────────────────────────────────────
|
|
156
|
-
const allCollapsed = () => new Set(['root1', 'child-a', 'root2']); // every node with children
|
|
157
|
-
test('flatten: default-collapsed shows only top-level', () => {
|
|
158
|
-
const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'All', query: '' });
|
|
159
|
-
assert.deepEqual(v.map((r) => r.id), ['root1', 'root2', 'lonely']);
|
|
160
|
-
// root1 has children and is collapsed → glyph state
|
|
161
|
-
assert.equal(v[0].hasChildren, true);
|
|
162
|
-
assert.equal(v[0].collapsed, true);
|
|
163
|
-
assert.equal(v[2].hasChildren, false); // lonely is a leaf
|
|
164
|
-
});
|
|
165
|
-
test('flatten: expanding a root reveals its (still-collapsed) children', () => {
|
|
166
|
-
const collapsed = allCollapsed();
|
|
167
|
-
collapsed.delete('root1');
|
|
168
|
-
const v = flatten(tree(), { collapsed, tab: 'All', query: '' });
|
|
169
|
-
assert.deepEqual(v.map((r) => r.id), ['root1', 'child-a', 'child-b', 'root2', 'lonely']);
|
|
170
|
-
// child-a still collapsed → grand-x hidden
|
|
171
|
-
assert.equal(v.find((r) => r.id === 'child-a').collapsed, true);
|
|
172
|
-
});
|
|
173
|
-
test('flatten: fully expanded shows the whole subtree', () => {
|
|
174
|
-
const collapsed = new Set(); // nothing collapsed
|
|
175
|
-
const v = flatten(tree(), { collapsed, tab: 'All', query: '' });
|
|
176
|
-
assert.deepEqual(v.map((r) => r.id), ['root1', 'child-a', 'grand-x', 'child-b', 'root2', 'child-c', 'lonely']);
|
|
177
|
-
});
|
|
178
|
-
// ── flatten: tab filtering + ancestor context ────────────────────────────────
|
|
179
|
-
test('flatten: Live tab dims dormant ancestors, keeps live matches', () => {
|
|
180
|
-
const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'Live', query: '' });
|
|
181
|
-
assert.deepEqual(v.map((r) => r.id), ['root1', 'root2', 'lonely']);
|
|
182
|
-
const byId = Object.fromEntries(v.map((r) => [r.id, r]));
|
|
183
|
-
assert.equal(byId['root1'].matched, true); // active
|
|
184
|
-
assert.equal(byId['lonely'].matched, true); // idle
|
|
185
|
-
assert.equal(byId['root2'].matched, false); // dormant, shown only as ancestor of child-c
|
|
186
|
-
});
|
|
187
|
-
test('flatten: Dormant tab excludes live-only branches', () => {
|
|
188
|
-
const v = flatten(tree(), { collapsed: new Set(), tab: 'Dormant', query: '' });
|
|
189
|
-
const ids = v.map((r) => r.id);
|
|
190
|
-
assert.ok(ids.includes('grand-x')); // done
|
|
191
|
-
assert.ok(ids.includes('root2')); // done
|
|
192
|
-
assert.ok(!ids.includes('child-b')); // active → excluded
|
|
193
|
-
assert.ok(!ids.includes('lonely')); // idle → excluded
|
|
194
|
-
});
|
|
195
|
-
// ── flatten: query auto-expands ancestors of matches ─────────────────────────
|
|
196
|
-
test('flatten: query force-expands ancestors even when collapsed', () => {
|
|
197
|
-
// Everything collapsed; query targets a deep leaf. Its ancestors must appear.
|
|
198
|
-
const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'All', query: 'grandx' });
|
|
199
|
-
assert.deepEqual(v.map((r) => r.id), ['root1', 'child-a', 'grand-x']);
|
|
200
|
-
const byId = Object.fromEntries(v.map((r) => [r.id, r]));
|
|
201
|
-
assert.equal(byId['grand-x'].matched, true); // the actual match
|
|
202
|
-
assert.equal(byId['child-a'].matched, false); // ancestor for context
|
|
203
|
-
assert.equal(byId['root1'].matched, false); // ancestor for context
|
|
204
|
-
});
|
|
205
|
-
test('flatten: query with no matches yields nothing', () => {
|
|
206
|
-
const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'All', query: 'zzzznope' });
|
|
207
|
-
assert.deepEqual(v, []);
|
|
208
|
-
});
|
|
209
|
-
// ── flatten: residentsOnly fold-reveal ───────────────────────────────────────
|
|
210
|
-
// resident-root → terminal-worker (child) → terminal-grand (grandchild)
|
|
211
|
-
// resident-only must hide the terminals from the TOP LEVEL + flat search, yet
|
|
212
|
-
// still reveal them once you expand the resident fold that owns them.
|
|
213
|
-
const RES_ROWS = [
|
|
214
|
-
lrow('res-root', 'resident-root', 'idle', 'resident'),
|
|
215
|
-
lrow('term-a', 'worker-a', 'active', 'terminal'),
|
|
216
|
-
lrow('term-g', 'worker-grand', 'active', 'terminal'),
|
|
217
|
-
lrow('term-root', 'lone-worker', 'active', 'terminal'), // pure-terminal root
|
|
218
|
-
];
|
|
219
|
-
const RES_CHILDREN = { 'res-root': ['term-a'], 'term-a': ['term-g'] };
|
|
220
|
-
function resTree() {
|
|
221
|
-
return buildTree(RES_ROWS, ['res-root', 'term-root'], (id) => RES_CHILDREN[id] ?? []);
|
|
222
|
-
}
|
|
223
|
-
test('flatten: residentsOnly hides terminal top-level rows (incl. terminal roots)', () => {
|
|
224
|
-
// Everything collapsed → only the resident root shows; the lone terminal root
|
|
225
|
-
// and the worker subtree are hidden at the top level.
|
|
226
|
-
const v = flatten(resTree(), { collapsed: new Set(['res-root', 'term-a']), tab: 'All', query: '', residentsOnly: true });
|
|
227
|
-
assert.deepEqual(v.map((r) => r.id), ['res-root']);
|
|
228
|
-
});
|
|
229
|
-
test('flatten: residentsOnly reveals terminal children once their fold is expanded', () => {
|
|
230
|
-
// Expand the resident root → its terminal worker appears (still collapsed, so
|
|
231
|
-
// its own terminal grandchild stays hidden).
|
|
232
|
-
const v1 = flatten(resTree(), { collapsed: new Set(['term-a']), tab: 'All', query: '', residentsOnly: true });
|
|
233
|
-
assert.deepEqual(v1.map((r) => r.id), ['res-root', 'term-a']);
|
|
234
|
-
// Expand the worker too → the terminal grandchild is revealed.
|
|
235
|
-
const v2 = flatten(resTree(), { collapsed: new Set(), tab: 'All', query: '', residentsOnly: true });
|
|
236
|
-
assert.deepEqual(v2.map((r) => r.id), ['res-root', 'term-a', 'term-g']);
|
|
237
|
-
});
|
|
238
|
-
test('flatten: residentsOnly keeps terminals out of flat (relevance) search results', () => {
|
|
239
|
-
// A query that matches the workers must not surface them in the flat search —
|
|
240
|
-
// resident-only de-clutters search even though the fold would reveal them.
|
|
241
|
-
const v = flatten(resTree(), { collapsed: new Set(), tab: 'All', query: 'worker', residentsOnly: true, sort: 'relevance' });
|
|
242
|
-
assert.deepEqual(v.map((r) => r.id), []);
|
|
243
|
-
});
|
|
244
|
-
test('flatten: residentsOnly off shows every lifecycle at the top level', () => {
|
|
245
|
-
// Roots are live-first: term-root (active) ranks ahead of res-root (idle).
|
|
246
|
-
const v = flatten(resTree(), { collapsed: new Set(['res-root', 'term-a']), tab: 'All', query: '', residentsOnly: false });
|
|
247
|
-
assert.deepEqual(v.map((r) => r.id), ['term-root', 'res-root']);
|
|
248
|
-
});
|
|
249
|
-
function arow(node_id, status, opts) {
|
|
250
|
-
return { ...row(node_id, node_id, status), ...opts };
|
|
251
|
-
}
|
|
252
|
-
test('attentionTier: classifies each cheap-field combination', () => {
|
|
253
|
-
assert.equal(attentionTier(arow('x', 'active', { viewed: true, streaming: true })), 0);
|
|
254
|
-
assert.equal(attentionTier(arow('x', 'active', { viewed: true })), 1);
|
|
255
|
-
assert.equal(attentionTier(arow('x', 'active', { streaming: true, viewed: false })), 2);
|
|
256
|
-
assert.equal(attentionTier(arow('x', 'active', {})), 3);
|
|
257
|
-
assert.equal(attentionTier(arow('x', 'idle', {})), 3);
|
|
258
|
-
assert.equal(attentionTier(arow('x', 'done', {})), 4);
|
|
259
|
-
assert.equal(attentionTier(arow('x', 'dead', {})), 4);
|
|
260
|
-
assert.equal(attentionTier(arow('x', 'canceled', {})), 4);
|
|
261
|
-
});
|
|
262
|
-
test('attentionMtime: prefers mtimeMs, falls back to created', () => {
|
|
263
|
-
assert.equal(attentionMtime(arow('x', 'active', { mtimeMs: 1234 })), 1234);
|
|
264
|
-
// No mtimeMs → epoch-ms of the ISO `created` (fixture is 2026-01-01T00:00:00Z).
|
|
265
|
-
assert.equal(attentionMtime(arow('x', 'active', {})), Date.parse('2026-01-01T00:00:00.000Z'));
|
|
266
|
-
});
|
|
267
|
-
test('flatten: attention sort tiers rows (attached/streaming/live first)', () => {
|
|
268
|
-
// One row per tier, deliberately shuffled in input order.
|
|
269
|
-
const rows = [
|
|
270
|
-
arow('dormant', 'done', { mtimeMs: 100 }), // T4
|
|
271
|
-
arow('live', 'active', { mtimeMs: 100 }), // T3
|
|
272
|
-
arow('streaming', 'active', { streaming: true, mtimeMs: 100 }), // T2
|
|
273
|
-
arow('attached', 'idle', { viewed: true, mtimeMs: 100 }), // T1
|
|
274
|
-
arow('both', 'active', { viewed: true, streaming: true, mtimeMs: 100 }), // T0
|
|
275
|
-
];
|
|
276
|
-
const t = buildTree(rows, [], () => []);
|
|
277
|
-
const v = flatten(t, { collapsed: new Set(), tab: 'All', query: '', sort: 'attention' });
|
|
278
|
-
assert.deepEqual(v.map((r) => r.id), ['both', 'attached', 'streaming', 'live', 'dormant']);
|
|
279
|
-
});
|
|
280
|
-
test('flatten: attention sort orders newest-message-first WITHIN a tier', () => {
|
|
281
|
-
// All dormant (T4) → ordering is purely by mtime, newest first.
|
|
282
|
-
const rows = [
|
|
283
|
-
arow('old', 'done', { mtimeMs: 1000 }),
|
|
284
|
-
arow('newest', 'done', { mtimeMs: 3000 }),
|
|
285
|
-
arow('mid', 'done', { mtimeMs: 2000 }),
|
|
286
|
-
];
|
|
287
|
-
const t = buildTree(rows, [], () => []);
|
|
288
|
-
const v = flatten(t, { collapsed: new Set(), tab: 'All', query: '', sort: 'attention' });
|
|
289
|
-
assert.deepEqual(v.map((r) => r.id), ['newest', 'mid', 'old']);
|
|
290
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|