@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,439 +0,0 @@
|
|
|
1
|
-
// attach-chrome-remote.test.ts — the safe-defaults contract for the attach
|
|
2
|
-
// chrome (buildCanvasPanelLines + GraphOverlay) when the `canvasSource` is a
|
|
3
|
-
// RemoteCanvasSource, i.e. `crtr surface attach --canvas <name>`.
|
|
4
|
-
//
|
|
5
|
-
// Adversarial, not merely a clean-machine assertion (mirrors
|
|
6
|
-
// core/canvas/__tests__/render-remote.test.ts): BEFORE rendering, this test
|
|
7
|
-
// seeds real, CONFLICTING local state for node id `a` — a poisoned telemetry
|
|
8
|
-
// reading (context tokens + a live-activity cue), an active fault, a local
|
|
9
|
-
// tmux focus, and a broker attach.json marking it human-watched — every
|
|
10
|
-
// historically-broken local read the remote suppression in nav-model.ts is
|
|
11
|
-
// supposed to bypass. If the production suppression ever regressed back to
|
|
12
|
-
// consulting local disk/SQLite for a remote id, the rendered lines below would
|
|
13
|
-
// carry the poisoned tokens/glyph/background instead of the safe defaults, so
|
|
14
|
-
// a clean-machine run could never mask the regression.
|
|
15
|
-
//
|
|
16
|
-
// Also proves the read-only contract: GraphOverlay's Enter/m/x key handlers
|
|
17
|
-
// must no-op against a remote graph row instead of shelling local
|
|
18
|
-
// `crtr surface node focus` / `crtr node lifecycle close`.
|
|
19
|
-
import { test, before, beforeEach, after } from 'node:test';
|
|
20
|
-
import assert from 'node:assert/strict';
|
|
21
|
-
import { createServer } from 'node:http';
|
|
22
|
-
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
23
|
-
import { tmpdir } from 'node:os';
|
|
24
|
-
import { join } from 'node:path';
|
|
25
|
-
import { RemoteCanvasSource } from '../../../core/canvas/remote-canvas-source.js';
|
|
26
|
-
import { createNode } from '../../../core/canvas/canvas.js';
|
|
27
|
-
import { closeDb } from '../../../core/canvas/db.js';
|
|
28
|
-
import { openFocusRow } from '../../../core/canvas/focuses.js';
|
|
29
|
-
import { jobDir } from '../../../core/canvas/paths.js';
|
|
30
|
-
import { recordFault } from '../../../core/runtime/fault.js';
|
|
31
|
-
import { BG_ATTACHED } from '../../../core/canvas/nav-model.js';
|
|
32
|
-
import { resolveKeybindings } from '../../../core/keybindings/index.js';
|
|
33
|
-
import { dispatchSlashCommand, slashCommandList } from '../slash/dispatch.js';
|
|
34
|
-
import { tagAttachPane, untagAttachPane } from '../session/pane-tag.js';
|
|
35
|
-
import { createMemoryRefRefreshCoordinator } from '../session/editor-inventory.js';
|
|
36
|
-
import { InputController } from '../input/controller.js';
|
|
37
|
-
import { buildCanvasPanelLines } from '../chrome/canvas-panels.js';
|
|
38
|
-
import { GraphOverlay } from '../overlays/graph.js';
|
|
39
|
-
function startMockCrtrServer(route) {
|
|
40
|
-
return new Promise((resolve) => {
|
|
41
|
-
const server = createServer((req, res) => {
|
|
42
|
-
const chunks = [];
|
|
43
|
-
req.on('data', (c) => chunks.push(c));
|
|
44
|
-
req.on('end', () => {
|
|
45
|
-
const bodyText = Buffer.concat(chunks).toString('utf8');
|
|
46
|
-
const parsed = JSON.parse(bodyText);
|
|
47
|
-
const result = route(parsed.args);
|
|
48
|
-
res.writeHead(result.status ?? 200, { 'content-type': 'application/json' });
|
|
49
|
-
res.end(JSON.stringify({ ok: true, exitCode: 0, stdout: JSON.stringify(result.body), stderr: '' }));
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
server.listen(0, '127.0.0.1', () => {
|
|
53
|
-
const addr = server.address();
|
|
54
|
-
const port = typeof addr === 'object' && addr !== null ? addr.port : 0;
|
|
55
|
-
resolve({
|
|
56
|
-
url: `http://127.0.0.1:${port}`,
|
|
57
|
-
close: () => new Promise((res) => server.close(() => res())),
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
function meta(id, extra) {
|
|
63
|
-
return {
|
|
64
|
-
node_id: id,
|
|
65
|
-
name: id,
|
|
66
|
-
created: new Date().toISOString(),
|
|
67
|
-
cwd: '/tmp/work',
|
|
68
|
-
kind: 'general',
|
|
69
|
-
mode: 'base',
|
|
70
|
-
lifecycle: 'terminal',
|
|
71
|
-
status: 'active',
|
|
72
|
-
...extra,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function show(node, reports, managers) {
|
|
76
|
-
return {
|
|
77
|
-
node,
|
|
78
|
-
reports: reports.map((id) => ({ node_id: id, name: id, kind: 'general', status: 'active', active: true })),
|
|
79
|
-
managers: managers.map((id) => ({ node_id: id, name: id, kind: 'general', status: 'active', active: true })),
|
|
80
|
-
artifacts: { report: 0, doc: 0, roadmap: 0 },
|
|
81
|
-
pending_crons: 0,
|
|
82
|
-
paths: { context_dir: '/tmp/context', reports_dir: '/tmp/reports', session_file: null },
|
|
83
|
-
follow_up: '',
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
const IDENTITY_PALETTE = {
|
|
87
|
-
accent: (s) => s,
|
|
88
|
-
active: (s) => s,
|
|
89
|
-
info: (s) => s,
|
|
90
|
-
muted: (s) => s,
|
|
91
|
-
faint: (s) => s,
|
|
92
|
-
border: (s) => s,
|
|
93
|
-
bold: (s) => s,
|
|
94
|
-
error: (s) => s,
|
|
95
|
-
warning: (s) => s,
|
|
96
|
-
diffAdded: (s) => s,
|
|
97
|
-
diffRemoved: (s) => s,
|
|
98
|
-
bashMode: (s) => s,
|
|
99
|
-
bashModeAlt: (s) => s,
|
|
100
|
-
surface: (s) => s,
|
|
101
|
-
};
|
|
102
|
-
/** A fake `TUI` carrying just what `GraphOverlay` touches: `showOverlay` (a
|
|
103
|
-
* no-op handle) and `requestRender`. GraphOverlay's key handlers only shell
|
|
104
|
-
* `crtr` (via execFile) and toggle local overlay/handle state — they never
|
|
105
|
-
* reach into the real TUI beyond these two calls. */
|
|
106
|
-
function fakeTui() {
|
|
107
|
-
let renders = 0;
|
|
108
|
-
const tui = {
|
|
109
|
-
showOverlay: () => ({
|
|
110
|
-
hide: () => { },
|
|
111
|
-
setHidden: () => { },
|
|
112
|
-
isHidden: () => false,
|
|
113
|
-
focus: () => { },
|
|
114
|
-
unfocus: () => { },
|
|
115
|
-
isFocused: () => true,
|
|
116
|
-
}),
|
|
117
|
-
requestRender: () => { renders++; },
|
|
118
|
-
};
|
|
119
|
-
return { tui, renderCount: () => renders };
|
|
120
|
-
}
|
|
121
|
-
let home;
|
|
122
|
-
let localCwd;
|
|
123
|
-
before(() => {
|
|
124
|
-
home = mkdtempSync(join(tmpdir(), 'crtr-attach-chrome-remote-'));
|
|
125
|
-
localCwd = mkdtempSync(join(tmpdir(), 'crtr-attach-chrome-remote-cwd-'));
|
|
126
|
-
process.env['CRTR_HOME'] = home;
|
|
127
|
-
});
|
|
128
|
-
beforeEach(() => {
|
|
129
|
-
closeDb();
|
|
130
|
-
rmSync(home, { recursive: true, force: true });
|
|
131
|
-
});
|
|
132
|
-
after(() => {
|
|
133
|
-
closeDb();
|
|
134
|
-
rmSync(home, { recursive: true, force: true });
|
|
135
|
-
rmSync(localCwd, { recursive: true, force: true });
|
|
136
|
-
delete process.env['CRTR_HOME'];
|
|
137
|
-
});
|
|
138
|
-
/** Seed conflicting local state for node id `a` — every local read the
|
|
139
|
-
* attach-chrome remote suppression is supposed to bypass. */
|
|
140
|
-
function seedPoisonedLocalState() {
|
|
141
|
-
createNode(meta('a', { cwd: localCwd }));
|
|
142
|
-
// A local focus — poisons focusedNodeIds()/isAttached's fast path.
|
|
143
|
-
openFocusRow('poison-focus', null, null, 'a');
|
|
144
|
-
// A broker attach.json — poisons isAttached's slow path.
|
|
145
|
-
writeFileSync(join(jobDir('a'), 'attach.json'), JSON.stringify({ viewers: 1 }));
|
|
146
|
-
// An active, manually-retried fault — poisons nodeGlyph's hanging overlay.
|
|
147
|
-
recordFault('a', {
|
|
148
|
-
link: 'viewer↔broker',
|
|
149
|
-
op: 'poison',
|
|
150
|
-
kind: 'other',
|
|
151
|
-
retry: { disposition: 'manual' },
|
|
152
|
-
message: 'POISON FAULT — local read leaked into remote attach chrome',
|
|
153
|
-
});
|
|
154
|
-
// Local telemetry — poisons tokensCell + activityCell.
|
|
155
|
-
writeFileSync(join(jobDir('a'), 'telemetry.json'), JSON.stringify({
|
|
156
|
-
context_tokens: 999_999,
|
|
157
|
-
last_activity: 'POISON ACTIVITY — local read leaked into remote attach chrome',
|
|
158
|
-
}));
|
|
159
|
-
}
|
|
160
|
-
test('buildCanvasPanelLines suppresses every local-read adornment for a RemoteCanvasSource, even with conflicting local state for the same node id', async (t) => {
|
|
161
|
-
seedPoisonedLocalState();
|
|
162
|
-
const rootMeta = meta('root');
|
|
163
|
-
const aMeta = meta('a'); // the REMOTE node's meta — unrelated to the poisoned local NodeMeta above
|
|
164
|
-
const server = await startMockCrtrServer((args) => {
|
|
165
|
-
if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'show') {
|
|
166
|
-
const id = args[4];
|
|
167
|
-
if (id === 'root')
|
|
168
|
-
return { body: show(rootMeta, ['a'], []) };
|
|
169
|
-
if (id === 'a')
|
|
170
|
-
return { body: show(aMeta, [], ['root']) };
|
|
171
|
-
}
|
|
172
|
-
return { status: 500, body: {} };
|
|
173
|
-
});
|
|
174
|
-
// Register the close BEFORE any assertion runs — a listening server left
|
|
175
|
-
// open by a thrown assertion keeps this test file's process alive forever
|
|
176
|
-
// (see the CI-hang postmortem on rebuild-coalescer.test.ts).
|
|
177
|
-
t.after(() => server.close());
|
|
178
|
-
const source = new RemoteCanvasSource(server.url, 'tok');
|
|
179
|
-
// The roster excludes the attached root because it is already identified by
|
|
180
|
-
// the editor, leaving its one live child 'a'. The poisoned local node id is
|
|
181
|
-
// 'a', so the load-bearing assertions target that rendered row.
|
|
182
|
-
const { reports, reportIds } = await buildCanvasPanelLines('root', {}, IDENTITY_PALETTE, source);
|
|
183
|
-
assert.deepEqual(reportIds, ['a'], 'roster omits the node already open in the editor');
|
|
184
|
-
assert.equal(reports.length, 1);
|
|
185
|
-
const line = reports[0];
|
|
186
|
-
assert.ok(!line.includes('1000k'), `local telemetry (999999 tokens) must not leak into a remote row: ${line}`);
|
|
187
|
-
assert.ok(!line.includes('POISON'), `poisoned local text must never appear in a remote row: ${line}`);
|
|
188
|
-
assert.ok(!line.includes('⚠'), `a local active fault must not surface as the hanging glyph on a remote row: ${line}`);
|
|
189
|
-
// A child's parent remains in the below-editor roster with an ↑ prefix, which
|
|
190
|
-
// distinguishes it from the ↓ rows for reports.
|
|
191
|
-
const childPanels = await buildCanvasPanelLines('a', {}, IDENTITY_PALETTE, source);
|
|
192
|
-
assert.deepEqual(childPanels.reportIds, ['root']);
|
|
193
|
-
assert.equal(childPanels.reports.length, 1);
|
|
194
|
-
assert.match(childPanels.reports[0], /↑.*root/);
|
|
195
|
-
assert.match(reports[0], /↓.*a/);
|
|
196
|
-
});
|
|
197
|
-
test('GraphOverlay suppresses every local-read adornment for a RemoteCanvasSource AND makes Enter/m/x no-ops, even with conflicting local state for the same node id', async (t) => {
|
|
198
|
-
seedPoisonedLocalState();
|
|
199
|
-
const rootMeta = meta('root');
|
|
200
|
-
const aMeta = meta('a');
|
|
201
|
-
const server = await startMockCrtrServer((args) => {
|
|
202
|
-
if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'show') {
|
|
203
|
-
const id = args[4];
|
|
204
|
-
if (id === 'root')
|
|
205
|
-
return { body: show(rootMeta, ['a'], []) };
|
|
206
|
-
if (id === 'a')
|
|
207
|
-
return { body: show(aMeta, [], ['root']) };
|
|
208
|
-
}
|
|
209
|
-
return { status: 500, body: {} };
|
|
210
|
-
});
|
|
211
|
-
// Register the close BEFORE any assertion runs — see the note above.
|
|
212
|
-
t.after(() => server.close());
|
|
213
|
-
const source = new RemoteCanvasSource(server.url, 'tok');
|
|
214
|
-
const { tui } = fakeTui();
|
|
215
|
-
const overlay = new GraphOverlay(tui, 'root', () => ({}), IDENTITY_PALETTE, resolveKeybindings(), source);
|
|
216
|
-
overlay.open();
|
|
217
|
-
// buildSnapshot() is async (chased through the mock server); poll for it to land.
|
|
218
|
-
for (let i = 0; i < 100 && overlay.snapshot === undefined; i++) {
|
|
219
|
-
await new Promise((r) => setImmediate(r));
|
|
220
|
-
}
|
|
221
|
-
assert.notEqual(overlay.snapshot, undefined, 'snapshot never built');
|
|
222
|
-
const lines = overlay.render(100).join('\n');
|
|
223
|
-
assert.ok(!lines.includes('1000k'), `local telemetry must not leak into the remote graph overlay: ${lines}`);
|
|
224
|
-
assert.ok(!lines.includes('POISON'), `poisoned local text must never appear in the remote graph overlay: ${lines}`);
|
|
225
|
-
assert.ok(!lines.includes('⚠'), `a local active fault must not surface as the hanging glyph in the remote graph overlay: ${lines}`);
|
|
226
|
-
assert.ok(!lines.includes(BG_ATTACHED), `a local focus/attach must not paint a remote row as attached in the graph overlay: ${lines}`);
|
|
227
|
-
// Footer hint must drop the focus/kill/mgr hints in remote mode.
|
|
228
|
-
assert.ok(!lines.includes('kill'), `remote overlay footer must not advertise kill: ${lines}`);
|
|
229
|
-
assert.ok(!lines.includes('focus') && !lines.includes('mgr'), `remote overlay footer must not advertise focus/mgr: ${lines}`);
|
|
230
|
-
// Enter must NOT close the overlay (a local `close()` is the observable
|
|
231
|
-
// effect of a real `focusTarget` dispatch) — it must no-op instead.
|
|
232
|
-
overlay.handleInput('\r');
|
|
233
|
-
assert.equal(overlay.isOpen(), true, 'Enter must not act (close) on a remote graph row');
|
|
234
|
-
// x must NOT arm the close confirm on a remote row. The confirmation UI never
|
|
235
|
-
// literally contains legacy `y/n`, so assert the real state directly:
|
|
236
|
-
// pendingConfirm stays unset and no `kill …?` accept/cancel prompt renders.
|
|
237
|
-
overlay.handleInput('x');
|
|
238
|
-
assert.equal(overlay.pendingConfirm, undefined, 'x must not arm pendingConfirm on a remote graph row');
|
|
239
|
-
const afterX = overlay.render(100).join('\n');
|
|
240
|
-
assert.ok(!afterX.includes('kill'), `x must not surface a kill confirm prompt on a remote graph row: ${afterX}`);
|
|
241
|
-
assert.ok(!/accept|cancel/.test(afterX), `x must not surface an accept/cancel confirm on a remote graph row: ${afterX}`);
|
|
242
|
-
// m must NOT close the overlay either (it would focusTarget the manager).
|
|
243
|
-
overlay.handleInput('m');
|
|
244
|
-
assert.equal(overlay.isOpen(), true, 'm must not act (close) on a remote graph row');
|
|
245
|
-
});
|
|
246
|
-
// ---------------------------------------------------------------------------
|
|
247
|
-
// Phase 3 review 2 — the ENCLOSING attach viewer (slash commands, pane tag,
|
|
248
|
-
// detach-reap), not just the GraphOverlay/panel rendering
|
|
249
|
-
// the fix above already covers. Same adversarial shape: seed colliding LOCAL
|
|
250
|
-
// state for the remote node id `a`, then assert the remote path never touches
|
|
251
|
-
// it — and, symmetrically, that the LOCAL path is byte-for-byte unchanged
|
|
252
|
-
// (every guard below defaults to acting exactly as before when `remote` is
|
|
253
|
-
// `false`).
|
|
254
|
-
// ---------------------------------------------------------------------------
|
|
255
|
-
function fakeSlashContext(remote, nodeId) {
|
|
256
|
-
const notices = [];
|
|
257
|
-
const sent = [];
|
|
258
|
-
const ctx = {
|
|
259
|
-
send: (frame) => sent.push(frame),
|
|
260
|
-
notify: (m) => notices.push(m),
|
|
261
|
-
cwd: '/tmp/does-not-matter',
|
|
262
|
-
// Explicit empty string (not `undefined`) so promoteNode/openContext's
|
|
263
|
-
// `ctx.nodeId ?? process.env['CRTR_NODE_ID']` fallback can NEVER pick up
|
|
264
|
-
// this test process's own real CRTR_NODE_ID (this test runs INSIDE a live
|
|
265
|
-
// crtr node) — the local-mode assertions below must reach the real
|
|
266
|
-
// no-node-id early return, never an accidental real `crtr node promote`
|
|
267
|
-
// against ourselves.
|
|
268
|
-
nodeId: '',
|
|
269
|
-
remote,
|
|
270
|
-
};
|
|
271
|
-
return { ctx, notices, sent };
|
|
272
|
-
}
|
|
273
|
-
test('slash autocomplete structurally omits local-only native canvas commands in remote mode and keeps them in local mode', () => {
|
|
274
|
-
const remoteNames = slashCommandList(undefined, true).map((c) => c.name);
|
|
275
|
-
assert.ok(!remoteNames.includes('promote'), `remote autocomplete must not offer /promote: ${remoteNames.join(',')}`);
|
|
276
|
-
assert.ok(!remoteNames.includes('resume-node'), `remote autocomplete must not offer /resume-node: ${remoteNames.join(',')}`);
|
|
277
|
-
assert.ok(!remoteNames.includes('context'), `remote autocomplete must not offer /context: ${remoteNames.join(',')}`);
|
|
278
|
-
assert.ok(remoteNames.includes('graph'), 'remote autocomplete must still offer /graph');
|
|
279
|
-
const localNames = slashCommandList().map((c) => c.name);
|
|
280
|
-
for (const name of ['graph', 'promote', 'resume-node', 'context']) {
|
|
281
|
-
assert.ok(localNames.includes(name), `local autocomplete must still offer /${name}: ${localNames.join(',')}`);
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
test('dispatchSlashCommand no-ops /promote, /resume-node, /context in remote mode instead of shelling a local crtr command', () => {
|
|
285
|
-
const { ctx, notices, sent } = fakeSlashContext(true, 'a');
|
|
286
|
-
for (const cmd of ['/promote', '/resume-node', '/context', '/promote orchestrator']) {
|
|
287
|
-
notices.length = 0;
|
|
288
|
-
const handled = dispatchSlashCommand(cmd, ctx);
|
|
289
|
-
assert.equal(handled, true, `${cmd} must be handled (native, never forwarded to the engine as a prompt)`);
|
|
290
|
-
assert.equal(notices.length, 1, `${cmd} must notify exactly once (the remote-unsafe notice), got: ${JSON.stringify(notices)}`);
|
|
291
|
-
assert.match(notices[0], /not available for a remote attach/, `${cmd} must notify the remote-unsafe message, not proceed into its local handler: ${notices[0]}`);
|
|
292
|
-
}
|
|
293
|
-
assert.equal(sent.length, 0, 'no command frame must ever be sent for a gated remote canvas command');
|
|
294
|
-
// /graph is remote-safe via GraphOverlay's own `remote` handling.
|
|
295
|
-
notices.length = 0;
|
|
296
|
-
ctx.onGraph = () => notices.push('graph-toggled');
|
|
297
|
-
dispatchSlashCommand('/graph', ctx);
|
|
298
|
-
assert.deepEqual(notices, ['graph-toggled'], '/graph must still work normally in remote mode');
|
|
299
|
-
});
|
|
300
|
-
test('dispatchSlashCommand leaves the LOCAL (non-remote) path for /promote, /resume-node, /context byte-for-byte unchanged', () => {
|
|
301
|
-
const { ctx, notices } = fakeSlashContext(false, '');
|
|
302
|
-
// No TMUX in this test process (a headless `node --test` run), so
|
|
303
|
-
// /resume-node and /context hit their OWN "needs tmux" notices — proving
|
|
304
|
-
// dispatch reached their real local handlers, not our new remote gate.
|
|
305
|
-
const savedTmux = process.env['TMUX'];
|
|
306
|
-
const savedTmuxPane = process.env['TMUX_PANE'];
|
|
307
|
-
delete process.env['TMUX'];
|
|
308
|
-
delete process.env['TMUX_PANE'];
|
|
309
|
-
try {
|
|
310
|
-
notices.length = 0;
|
|
311
|
-
dispatchSlashCommand('/promote', ctx);
|
|
312
|
-
assert.deepEqual(notices, ['/promote: no node to promote (viewer has no node id)']);
|
|
313
|
-
notices.length = 0;
|
|
314
|
-
dispatchSlashCommand('/resume-node', ctx);
|
|
315
|
-
assert.deepEqual(notices, ['/resume-node needs tmux']);
|
|
316
|
-
notices.length = 0;
|
|
317
|
-
dispatchSlashCommand('/context', ctx);
|
|
318
|
-
assert.deepEqual(notices, ['/context needs tmux']);
|
|
319
|
-
}
|
|
320
|
-
finally {
|
|
321
|
-
if (savedTmux !== undefined)
|
|
322
|
-
process.env['TMUX'] = savedTmux;
|
|
323
|
-
else
|
|
324
|
-
delete process.env['TMUX'];
|
|
325
|
-
if (savedTmuxPane !== undefined)
|
|
326
|
-
process.env['TMUX_PANE'] = savedTmuxPane;
|
|
327
|
-
else
|
|
328
|
-
delete process.env['TMUX_PANE'];
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
test('tagAttachPane/untagAttachPane never tag/untag the pane for a remote attach, and are unchanged for local', () => {
|
|
332
|
-
let calls = [];
|
|
333
|
-
const setOpt = (pane, name, value) => {
|
|
334
|
-
calls.push([pane, name, value]);
|
|
335
|
-
};
|
|
336
|
-
calls = [];
|
|
337
|
-
tagAttachPane(true, '%3', 'a', setOpt);
|
|
338
|
-
assert.deepEqual(calls, [], 'remote must never tag the pane with @crtr_node');
|
|
339
|
-
calls = [];
|
|
340
|
-
tagAttachPane(false, '%3', 'a', setOpt);
|
|
341
|
-
assert.deepEqual(calls, [['%3', '@crtr_node', 'a']], 'local tag must still fire unchanged');
|
|
342
|
-
calls = [];
|
|
343
|
-
untagAttachPane(true, '%3', setOpt);
|
|
344
|
-
assert.deepEqual(calls, [], 'remote must never untag the pane');
|
|
345
|
-
calls = [];
|
|
346
|
-
untagAttachPane(false, '%3', setOpt);
|
|
347
|
-
assert.deepEqual(calls, [['%3', '@crtr_node', '']], 'local untag must still fire unchanged');
|
|
348
|
-
// No pane resolved (outside tmux) — unaffected either way.
|
|
349
|
-
calls = [];
|
|
350
|
-
tagAttachPane(false, undefined, 'a', setOpt);
|
|
351
|
-
assert.deepEqual(calls, [], 'no pane to tag when outside tmux');
|
|
352
|
-
});
|
|
353
|
-
// ---------------------------------------------------------------------------
|
|
354
|
-
// T3 — memory-ref inventory lifecycle/race (design: inline memory references,
|
|
355
|
-
// terminal integration) and the input-layer whitespace-preservation contract.
|
|
356
|
-
// ---------------------------------------------------------------------------
|
|
357
|
-
test('createMemoryRefRefreshCoordinator: a stale reply from a superseded reset cannot overwrite a newer inventory, and malformed/rejected replies degrade to empty without throwing', async () => {
|
|
358
|
-
const snapshots = [];
|
|
359
|
-
const engineNameSnapshots = [];
|
|
360
|
-
const setMemoryRefs = (refs, engineLeadingCommandNames) => {
|
|
361
|
-
snapshots.push(refs);
|
|
362
|
-
engineNameSnapshots.push(engineLeadingCommandNames);
|
|
363
|
-
};
|
|
364
|
-
const pending = [];
|
|
365
|
-
const request = () => new Promise((resolve, reject) => { pending.push({ resolve, reject }); });
|
|
366
|
-
const coordinator = createMemoryRefRefreshCoordinator(setMemoryRefs, request);
|
|
367
|
-
const flush = async () => { await Promise.resolve(); await Promise.resolve(); };
|
|
368
|
-
// First reset (e.g. the initial welcome) — clears synchronously, then waits
|
|
369
|
-
// on its correlated request.
|
|
370
|
-
coordinator.reset();
|
|
371
|
-
assert.deepEqual(snapshots, [[]], 'first reset clears the inventory immediately');
|
|
372
|
-
assert.deepEqual(engineNameSnapshots, [[]], 'the engine-command inventory clears alongside refs, synchronously');
|
|
373
|
-
const firstRequest = pending[0];
|
|
374
|
-
// A second reset — a reconnect's fresh welcome, or an explicit /reload —
|
|
375
|
-
// supersedes it BEFORE the first reply lands: clears again and issues its
|
|
376
|
-
// own request.
|
|
377
|
-
coordinator.reset();
|
|
378
|
-
assert.deepEqual(snapshots, [[], []], 'a superseding reset clears the inventory again immediately');
|
|
379
|
-
const secondRequest = pending[1];
|
|
380
|
-
// The SECOND (latest) request resolves first — its refs AND engine-command
|
|
381
|
-
// names must both be installed (Major 6 — broker's `engineLeadingCommandNames`
|
|
382
|
-
// propagates through the coordinator alongside `refs`, not just `refs` alone).
|
|
383
|
-
const latestRefs = [{ name: 'dev', kind: 'knowledge', scope: 'project', shortForm: 'dev docs' }];
|
|
384
|
-
const latestEngineNames = ['reload'];
|
|
385
|
-
secondRequest.resolve({
|
|
386
|
-
type: 'data',
|
|
387
|
-
id: 'latest',
|
|
388
|
-
kind: 'list_memory_refs',
|
|
389
|
-
refs: latestRefs,
|
|
390
|
-
engineLeadingCommandNames: latestEngineNames,
|
|
391
|
-
});
|
|
392
|
-
await flush();
|
|
393
|
-
assert.deepEqual(snapshots.at(-1), latestRefs, 'the latest reset\'s reply installs its refs');
|
|
394
|
-
assert.deepEqual(engineNameSnapshots.at(-1), latestEngineNames, 'the latest reset\'s reply installs its engine-command names');
|
|
395
|
-
// The FIRST (now-stale) request's reply arrives late — it must be dropped,
|
|
396
|
-
// never overwriting the newer inventory the second reset already installed.
|
|
397
|
-
const staleRefs = [{ name: 'stale', kind: 'knowledge', scope: 'project', shortForm: 'stale' }];
|
|
398
|
-
firstRequest.resolve({ type: 'data', id: 'stale', kind: 'list_memory_refs', refs: staleRefs, engineLeadingCommandNames: ['stale-cmd'] });
|
|
399
|
-
await flush();
|
|
400
|
-
assert.equal(snapshots.length, 3, 'a stale reply from a superseded reset must never install refs');
|
|
401
|
-
assert.deepEqual(snapshots.at(-1), latestRefs, 'the newer inventory must survive a late stale reply');
|
|
402
|
-
assert.deepEqual(engineNameSnapshots.at(-1), latestEngineNames, 'the newer engine-command inventory must survive a late stale reply too');
|
|
403
|
-
// A malformed reply (wrong `kind`) degrades to the already-empty inventory.
|
|
404
|
-
coordinator.reset();
|
|
405
|
-
const thirdRequest = pending[2];
|
|
406
|
-
thirdRequest.resolve({ type: 'data', id: 'malformed', kind: 'dequeue', steering: [], followUp: [] });
|
|
407
|
-
await flush();
|
|
408
|
-
assert.deepEqual(snapshots.at(-1), [], 'a malformed-kind reply must never install refs');
|
|
409
|
-
assert.deepEqual(engineNameSnapshots.at(-1), [], 'a malformed-kind reply must never install engine-command names');
|
|
410
|
-
// A rejected request (timeout) degrades silently too — no retry, no throw.
|
|
411
|
-
coordinator.reset();
|
|
412
|
-
const fourthRequest = pending[3];
|
|
413
|
-
fourthRequest.reject(new Error('request timed out'));
|
|
414
|
-
await flush();
|
|
415
|
-
assert.deepEqual(snapshots.at(-1), [], 'a rejected request must never throw and must stay empty');
|
|
416
|
-
assert.deepEqual(engineNameSnapshots.at(-1), [], 'a rejected request must never throw and engine-command names must stay empty');
|
|
417
|
-
});
|
|
418
|
-
test('InputController.handleSubmit sends the prompt frame with the exact typed leading/trailing whitespace, even though emptiness/slash classification uses a trimmed view', () => {
|
|
419
|
-
const sent = [];
|
|
420
|
-
const fakeEditor = {
|
|
421
|
-
onSubmit: undefined,
|
|
422
|
-
onEscape: undefined,
|
|
423
|
-
onPasteImage: undefined,
|
|
424
|
-
onPasteImagePath: undefined,
|
|
425
|
-
onAction: () => { },
|
|
426
|
-
addToHistory: () => { },
|
|
427
|
-
setText: () => { },
|
|
428
|
-
getText: () => '',
|
|
429
|
-
insertTextAtCursor: () => { },
|
|
430
|
-
};
|
|
431
|
-
new InputController({}, fakeEditor, { matches: () => false }, { onCommand: (frame) => sent.push(frame), onDialogResponse: () => { } });
|
|
432
|
-
fakeEditor.onSubmit(' hello world ');
|
|
433
|
-
assert.deepEqual(sent, [{ type: 'prompt', text: ' hello world ' }], 'the sent prompt frame must keep the human\'s exact leading/trailing whitespace');
|
|
434
|
-
// Emptiness classification reads the TRIMMED view — whitespace-only input
|
|
435
|
-
// must never submit a frame.
|
|
436
|
-
sent.length = 0;
|
|
437
|
-
fakeEditor.onSubmit(' \n ');
|
|
438
|
-
assert.deepEqual(sent, [], 'a whitespace-only submit must not send a frame');
|
|
439
|
-
});
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import { decodeAttachControlInput, encodeAttachControlInput, extractAttachControlInput, resolveKeybindings, } from '../../../core/keybindings/index.js';
|
|
4
|
-
import { detachHint, inboxOpenHint, dispatchAttachAction, dispatchAttachBinding, matchesAttachBinding, refreshAttachBindingSnapshot, } from '../session/bindings.js';
|
|
5
|
-
import { GraphOverlay } from '../overlays/graph.js';
|
|
6
|
-
const PALETTE = {
|
|
7
|
-
accent: (s) => s,
|
|
8
|
-
active: (s) => s,
|
|
9
|
-
info: (s) => s,
|
|
10
|
-
muted: (s) => s,
|
|
11
|
-
faint: (s) => s,
|
|
12
|
-
border: (s) => s,
|
|
13
|
-
bold: (s) => s,
|
|
14
|
-
error: (s) => s,
|
|
15
|
-
warning: (s) => s,
|
|
16
|
-
diffAdded: (s) => s,
|
|
17
|
-
diffRemoved: (s) => s,
|
|
18
|
-
bashMode: (s) => s,
|
|
19
|
-
bashModeAlt: (s) => s,
|
|
20
|
-
surface: (s) => s,
|
|
21
|
-
};
|
|
22
|
-
function fakeTui() {
|
|
23
|
-
return {
|
|
24
|
-
showOverlay: () => ({ hide: () => { } }),
|
|
25
|
-
requestRender: () => { },
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
test('attach direct and private control input dispatch through the same action map', () => {
|
|
29
|
-
const bindings = resolveKeybindings({
|
|
30
|
-
'crtr.attach.detach': ['ctrl+x'],
|
|
31
|
-
'crtr.attach.clear-or-detach': [],
|
|
32
|
-
'crtr.attach.graph.toggle': [],
|
|
33
|
-
'crtr.attach.help.toggle': ['alt+shift+k'],
|
|
34
|
-
'crtr.attach.inbox.toggle': [],
|
|
35
|
-
'crtr.attach.model-ladder.next': ['alt+z'],
|
|
36
|
-
'crtr.attach.model-ladder.previous': ['alt+y'],
|
|
37
|
-
'crtr.attach.command.inspect': ['alt+shift+h'],
|
|
38
|
-
'crtr.attach.file-review': [],
|
|
39
|
-
'crtr.attach.profile-files': [],
|
|
40
|
-
'crtr.attach.whip': [],
|
|
41
|
-
});
|
|
42
|
-
const calls = [];
|
|
43
|
-
const actions = {
|
|
44
|
-
'crtr.attach.detach': () => calls.push('detach'),
|
|
45
|
-
'crtr.attach.clear-or-detach': () => calls.push('clear'),
|
|
46
|
-
'crtr.attach.graph.toggle': () => calls.push('graph'),
|
|
47
|
-
'crtr.attach.help.toggle': () => calls.push('help'),
|
|
48
|
-
'crtr.attach.inbox.toggle': () => calls.push('inbox'),
|
|
49
|
-
'crtr.attach.model-ladder.next': () => calls.push('ladder'),
|
|
50
|
-
'crtr.attach.model-ladder.previous': () => calls.push('ladder-back'),
|
|
51
|
-
'crtr.attach.command.inspect': () => calls.push('inspect'),
|
|
52
|
-
'crtr.attach.file-review': () => calls.push('review'),
|
|
53
|
-
'crtr.attach.profile-files': () => calls.push('profile-files'),
|
|
54
|
-
'crtr.attach.whip': () => calls.push('whip'),
|
|
55
|
-
};
|
|
56
|
-
assert.equal(dispatchAttachBinding(bindings, '\x18', actions), true);
|
|
57
|
-
assert.equal(dispatchAttachBinding(bindings, '\x04', actions), false, 'old detach must not reach the listener action');
|
|
58
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1bg', actions), false, 'disabled graph must not reach the listener action');
|
|
59
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1bx', actions), false, 'removed mode key must stay ordinary input');
|
|
60
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1bP', actions), false, 'removed mode key must stay ordinary input');
|
|
61
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1bz', actions), true);
|
|
62
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1bm', actions), false, 'old ladder key must not reach the listener action');
|
|
63
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1by', actions), true);
|
|
64
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1bM', actions), false, 'old ladder-back key must not reach the listener action');
|
|
65
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1b[72;4u', actions), true);
|
|
66
|
-
assert.equal(dispatchAttachBinding(bindings, '\x1b[75;4u', actions), true);
|
|
67
|
-
assert.equal(dispatchAttachBinding(bindings, '\x06', actions), false, 'disabled direct binding must stay disabled');
|
|
68
|
-
const privateInput = encodeAttachControlInput('crtr.attach.profile-files');
|
|
69
|
-
const privateAction = decodeAttachControlInput(privateInput);
|
|
70
|
-
assert.equal(privateAction, 'crtr.attach.profile-files');
|
|
71
|
-
dispatchAttachAction(privateAction, actions);
|
|
72
|
-
const helpPrivateInput = encodeAttachControlInput('crtr.attach.help.toggle');
|
|
73
|
-
assert.equal(decodeAttachControlInput(helpPrivateInput), 'crtr.attach.help.toggle');
|
|
74
|
-
dispatchAttachAction('crtr.attach.help.toggle', actions);
|
|
75
|
-
assert.deepEqual(calls, ['detach', 'ladder', 'ladder-back', 'inspect', 'help', 'profile-files', 'help']);
|
|
76
|
-
assert.equal(decodeAttachControlInput(`${privateInput}x`), undefined, 'whole-input decoding must be exact');
|
|
77
|
-
assert.equal(decodeAttachControlInput('\x1b_crtr;crtr.attach.not-real\x1b\\'), undefined, 'unknown actions must stay ordinary input');
|
|
78
|
-
assert.deepEqual(extractAttachControlInput(`before${privateInput}after`), {
|
|
79
|
-
actionId: 'crtr.attach.profile-files',
|
|
80
|
-
remaining: 'beforeafter',
|
|
81
|
-
});
|
|
82
|
-
assert.equal(detachHint(bindings), 'Ctrl+X', 'disabled clear-or-detach must fall back to enabled detach');
|
|
83
|
-
const noDetach = resolveKeybindings({ 'crtr.attach.detach': [], 'crtr.attach.clear-or-detach': [] });
|
|
84
|
-
assert.equal(detachHint(noDetach), undefined, 'a disabled pair must not render "Disabled to detach"');
|
|
85
|
-
});
|
|
86
|
-
test('closed-inbox footer hint resolves the configured inbox shortcut(s)', () => {
|
|
87
|
-
// Default: alt+i renders as the configured shortcut plus 'inbox'.
|
|
88
|
-
assert.equal(inboxOpenHint(resolveKeybindings()), 'Alt+I inbox');
|
|
89
|
-
// Custom single key.
|
|
90
|
-
assert.equal(inboxOpenHint(resolveKeybindings({ 'crtr.tmux.inbox.toggle': ['alt+j'] })), 'Alt+J inbox');
|
|
91
|
-
// Multiple gestures join with ' / ' (crouter's formatBinding convention).
|
|
92
|
-
assert.equal(inboxOpenHint(resolveKeybindings({ 'crtr.tmux.inbox.toggle': ['alt+i', 'alt+j'] })), 'Alt+I / Alt+J inbox');
|
|
93
|
-
// Disabled: omit the shortcut clause and fall back to the CLI affordance,
|
|
94
|
-
// never render the word "Disabled".
|
|
95
|
-
const disabled = inboxOpenHint(resolveKeybindings({ 'crtr.tmux.inbox.toggle': [] }));
|
|
96
|
-
assert.equal(disabled, 'crtr human list');
|
|
97
|
-
assert.doesNotMatch(disabled, /Disabled/);
|
|
98
|
-
});
|
|
99
|
-
test('attach startup and reload replace the dispatch/GRAPH snapshots and install each complete tmux snapshot', () => {
|
|
100
|
-
const first = resolveKeybindings({ 'crtr.attach.detach': ['ctrl+x'], 'crtr.graph.focus': ['f'] });
|
|
101
|
-
const second = resolveKeybindings({
|
|
102
|
-
'crtr.attach.detach': ['ctrl+z'],
|
|
103
|
-
'crtr.graph.focus': ['r'],
|
|
104
|
-
'crtr.graph.revive': [],
|
|
105
|
-
});
|
|
106
|
-
const settings = [
|
|
107
|
-
{ bindings: first, tmuxPassthrough: ['crtr.attach.detach'] },
|
|
108
|
-
{ bindings: second, tmuxPassthrough: ['crtr.attach.copy.message'] },
|
|
109
|
-
];
|
|
110
|
-
const graphSnapshots = [];
|
|
111
|
-
const installed = [];
|
|
112
|
-
let active = refreshAttachBindingSnapshot(() => settings.shift(), (bindings) => graphSnapshots.push(bindings), () => true, (bindings, tmuxPassthrough) => installed.push({ bindings, tmuxPassthrough }));
|
|
113
|
-
assert.equal(matchesAttachBinding(active.bindings, 'crtr.attach.detach', '\x18'), true, 'startup snapshot drives attach dispatch');
|
|
114
|
-
assert.equal(active.bindings.gestures('crtr.graph.focus')[0], 'f', 'startup snapshot reaches GRAPH');
|
|
115
|
-
active = refreshAttachBindingSnapshot(() => settings.shift(), (bindings) => graphSnapshots.push(bindings), () => true, (bindings, tmuxPassthrough) => installed.push({ bindings, tmuxPassthrough }));
|
|
116
|
-
assert.equal(matchesAttachBinding(active.bindings, 'crtr.attach.detach', '\x18'), false, 'reload replaces the old attach snapshot');
|
|
117
|
-
assert.equal(matchesAttachBinding(active.bindings, 'crtr.attach.detach', '\x1a'), true, 'reload dispatches through the new attach snapshot');
|
|
118
|
-
assert.equal(active.bindings.gestures('crtr.graph.focus')[0], 'r', 'reload replaces GRAPH bindings too');
|
|
119
|
-
assert.deepEqual(graphSnapshots, [first, second]);
|
|
120
|
-
assert.deepEqual(installed, [
|
|
121
|
-
{ bindings: first, tmuxPassthrough: ['crtr.attach.detach'] },
|
|
122
|
-
{ bindings: second, tmuxPassthrough: ['crtr.attach.copy.message'] },
|
|
123
|
-
], 'the unified tmux installer receives startup and reload settings snapshots');
|
|
124
|
-
});
|
|
125
|
-
test('GRAPH navigation and hints use effective bindings rather than default literals', () => {
|
|
126
|
-
const bindings = resolveKeybindings({
|
|
127
|
-
'crtr.graph.down': ['z'],
|
|
128
|
-
'crtr.graph.up': [],
|
|
129
|
-
'crtr.graph.focus': ['f'],
|
|
130
|
-
'crtr.graph.close-subtree': [],
|
|
131
|
-
'crtr.graph.dismiss': ['q'],
|
|
132
|
-
'crtr.graph.confirm.accept': ['t'],
|
|
133
|
-
'crtr.graph.confirm.cancel': ['c'],
|
|
134
|
-
});
|
|
135
|
-
const overlay = new GraphOverlay(fakeTui(), 'a', () => ({}), PALETTE, bindings, {});
|
|
136
|
-
const internal = overlay;
|
|
137
|
-
internal.cursorId = 'a';
|
|
138
|
-
internal.snapshot = {
|
|
139
|
-
rows: [
|
|
140
|
-
{ id: 'a', hasKids: false, isSelf: true, branch: '', cycle: false, collapsed: false },
|
|
141
|
-
{ id: 'b', hasKids: false, isSelf: false, branch: '', cycle: false, collapsed: false },
|
|
142
|
-
],
|
|
143
|
-
activeBelow: new Map(),
|
|
144
|
-
nodes: new Map([['a', null], ['b', null]]),
|
|
145
|
-
childIds: new Map(),
|
|
146
|
-
sortedChildIds: new Map(),
|
|
147
|
-
managerOf: new Map(),
|
|
148
|
-
focused: new Set(),
|
|
149
|
-
};
|
|
150
|
-
overlay.handleInput('j');
|
|
151
|
-
assert.equal(internal.cursorId, 'a', 'replaced default must stop matching');
|
|
152
|
-
overlay.handleInput('z');
|
|
153
|
-
assert.equal(internal.cursorId, 'b', 'replacement must drive navigation');
|
|
154
|
-
const rendered = overlay.render(58).join('\n');
|
|
155
|
-
// Bare printable keys render exactly as they must be typed (lowercase),
|
|
156
|
-
// never uppercased into a shift chord the matcher would reject.
|
|
157
|
-
assert.match(rendered, /f focus/, 'narrow GRAPH footer must prioritize remapped local focus');
|
|
158
|
-
assert.match(rendered, /q dismiss/, 'narrow GRAPH footer must prioritize remapped dismiss');
|
|
159
|
-
assert.doesNotMatch(rendered, /close/);
|
|
160
|
-
assert.doesNotMatch(rendered, /j down/);
|
|
161
|
-
assert.doesNotMatch(rendered, /Disabled/);
|
|
162
|
-
let closed = 0;
|
|
163
|
-
internal.pendingConfirm = { label: 'close b?', action: () => { closed++; } };
|
|
164
|
-
assert.match(overlay.render(80).join('\n'), /t accept · c cancel/);
|
|
165
|
-
overlay.handleInput('y');
|
|
166
|
-
assert.equal(closed, 0, 'replaced accept default must stop confirming');
|
|
167
|
-
internal.pendingConfirm = { label: 'close b?', action: () => { closed++; } };
|
|
168
|
-
overlay.handleInput('t');
|
|
169
|
-
assert.equal(closed, 1, 'replacement must confirm close');
|
|
170
|
-
});
|