@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,33 +1,46 @@
|
|
|
1
1
|
// Tests for the <crtr-bearings> preamble:
|
|
2
|
-
// 1.
|
|
3
|
-
//
|
|
4
|
-
// Orchestrators add the across-cycles framing; promotion delivers that
|
|
5
|
-
// same orchestrator context-dir framing to a node that spawned base.
|
|
2
|
+
// 1. Situational context rides the bearings as a sibling block, and only
|
|
3
|
+
// once something has been set.
|
|
6
4
|
// 2. canvas-context-intro injects the block as its own session message at
|
|
7
|
-
// session_start (before the first prompt), idempotent across resumes
|
|
5
|
+
// session_start (before the first prompt), idempotent across resumes,
|
|
6
|
+
// inert without a node id — and its renderer never overruns the terminal.
|
|
8
7
|
//
|
|
9
8
|
// Run: node --import tsx/esm --test src/core/__tests__/context-intro.test.ts
|
|
10
|
-
import { test, before, beforeEach, after } from 'node:test';
|
|
9
|
+
import { test, before, beforeEach, after, afterEach } from 'node:test';
|
|
11
10
|
import assert from 'node:assert/strict';
|
|
12
|
-
import { mkdtempSync, mkdirSync, rmSync
|
|
11
|
+
import { existsSync, mkdtempSync, mkdirSync, rmSync } from 'node:fs';
|
|
13
12
|
import { tmpdir } from 'node:os';
|
|
14
13
|
import { join } from 'node:path';
|
|
15
14
|
import { closeDb } from '../canvas/db.js';
|
|
16
|
-
import {
|
|
15
|
+
import { apiSocketPath } from '../canvas/paths.js';
|
|
17
16
|
import { spawnNode } from '../runtime/nodes.js';
|
|
18
|
-
import { promote } from '../runtime/promote.js';
|
|
19
|
-
import { personaDrift } from '../runtime/persona.js';
|
|
20
|
-
import { memoryDir } from '../runtime/memory.js';
|
|
21
17
|
import { appendSituationalContext, situationalContextBlock } from '../runtime/situational-context.js';
|
|
22
|
-
import registerCanvasContextIntro, {
|
|
18
|
+
import registerCanvasContextIntro, { renderContextMessage, CONTEXT_INTRO_CUSTOM_TYPE, } from '../../pi-extensions/canvas-context-intro.js';
|
|
19
|
+
import { buildContextBearings as buildContextIntro } from '../runtime/bearings.js';
|
|
20
|
+
import { createApiServer } from '../../daemon/api/server.js';
|
|
23
21
|
let home;
|
|
22
|
+
let server;
|
|
23
|
+
async function waitForSocket(path) {
|
|
24
|
+
for (let i = 0; i < 200; i++) {
|
|
25
|
+
if (existsSync(path))
|
|
26
|
+
return;
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`api socket never bound at ${path}`);
|
|
30
|
+
}
|
|
24
31
|
before(() => {
|
|
25
32
|
home = mkdtempSync(join(tmpdir(), 'crtr-ctxintro-'));
|
|
26
33
|
process.env['CRTR_HOME'] = home;
|
|
27
34
|
});
|
|
28
|
-
beforeEach(() => {
|
|
35
|
+
beforeEach(async () => {
|
|
29
36
|
closeDb();
|
|
30
37
|
rmSync(home, { recursive: true, force: true });
|
|
38
|
+
mkdirSync(home, { recursive: true });
|
|
39
|
+
server = createApiServer();
|
|
40
|
+
await waitForSocket(apiSocketPath());
|
|
41
|
+
});
|
|
42
|
+
afterEach(async () => {
|
|
43
|
+
await server.close();
|
|
31
44
|
});
|
|
32
45
|
after(() => {
|
|
33
46
|
closeDb();
|
|
@@ -35,42 +48,6 @@ after(() => {
|
|
|
35
48
|
delete process.env['CRTR_HOME'];
|
|
36
49
|
delete process.env['CRTR_NODE_ID'];
|
|
37
50
|
});
|
|
38
|
-
test('worker bearings: base framing + <knowledge> block, NO across-cycles framing', () => {
|
|
39
|
-
// Bug-regression: review finding M1 — buildContextBearings renders the
|
|
40
|
-
// <knowledge> block (renderKnowledgeBlock): a kind-wrapped file tree of
|
|
41
|
-
// knowledge docs. This test locks in that contract.
|
|
42
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
43
|
-
// Seed a node-local substrate doc so the knowledge block is non-empty.
|
|
44
|
-
const dir = memoryDir(meta.node_id);
|
|
45
|
-
mkdirSync(dir, { recursive: true });
|
|
46
|
-
writeFileSync(join(dir, 'test-ref.md'), '---\nkind: knowledge\nwhen-and-why-to-read: When testing, this reference should be read because it is a regression fixture\nsystem-prompt-visibility: preview\n---\nTest body.\n');
|
|
47
|
-
const block = buildContextIntro(meta.node_id);
|
|
48
|
-
assert.match(block, /<crtr-bearings>/, 'opens with the bearings section');
|
|
49
|
-
assert.ok(block.includes(contextDir(meta.node_id)), 'names the context-dir path inline (no dir= attribute)');
|
|
50
|
-
assert.doesNotMatch(block, /<crtr-context/, 'no legacy <crtr-context dir=…> wrapper');
|
|
51
|
-
assert.match(block, /## Your context directory/, 'context dir is its own markdown subsection');
|
|
52
|
-
assert.match(block, /shared document store, not a task tracker/, 'base = shared docs, not tasks');
|
|
53
|
-
// The catalog is a sibling <memory kind="knowledge"> block, never nested
|
|
54
|
-
// under anything dir-scoped.
|
|
55
|
-
assert.match(block, /<memory kind="knowledge">/, 'knowledge catalog present as a memory block');
|
|
56
|
-
// Per-store stanza headers (label · dir) never appear.
|
|
57
|
-
assert.doesNotMatch(block, /user-global · /, 'no user-global label·dir stanza');
|
|
58
|
-
assert.doesNotMatch(block, /node-local · /, 'no node-local label·dir stanza');
|
|
59
|
-
// No (empty) placeholder marker.
|
|
60
|
-
assert.doesNotMatch(block, /\(empty\)/, 'no (empty) placeholder');
|
|
61
|
-
assert.match(block, /\nknowledge\n/, 'tree headed by the `knowledge` root label');
|
|
62
|
-
// The node-local preview-rung doc renders as a tree entry with a `# read when:`
|
|
63
|
-
// routing line (verbatim previewLine output).
|
|
64
|
-
assert.match(block, /test-ref {2}# read when: When testing, this reference should be read because it is a regression fixture\./, 'node-local preview doc renders its routing line');
|
|
65
|
-
assert.match(block, /<project_context>/, 'project_context now rides the bearings even without project files');
|
|
66
|
-
assert.match(block, /<environment cwd="\/tmp\/work">/, 'environment block is always present');
|
|
67
|
-
assert.match(block, /Host: .+ \u00b7 tmux server: (reachable|none)/, 'environment block reports a host/runtime line with tmux server reachability');
|
|
68
|
-
assert.match(block, /Directory listing: unavailable \(cwd missing or unreadable\)\./, 'missing cwd degrades the directory listing');
|
|
69
|
-
assert.match(block, /Git: not a git repository\./, 'missing cwd degrades git info');
|
|
70
|
-
// A terminal worker must NOT carry the orchestrator across-cycles framing.
|
|
71
|
-
assert.doesNotMatch(block, /refresh cycles/, 'no across-cycles framing for a terminal worker');
|
|
72
|
-
assert.match(block, /<\/crtr-bearings>/);
|
|
73
|
-
});
|
|
74
51
|
test('situational context rides the bearings as a sibling <situational-context> block; empty when unset', () => {
|
|
75
52
|
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
76
53
|
assert.equal(situationalContextBlock(meta.node_id), '', 'no block until something is set');
|
|
@@ -81,94 +58,6 @@ test('situational context rides the bearings as a sibling <situational-context>
|
|
|
81
58
|
assert.match(block, /user is looking at the billing applet/, 'block carries the ambient text');
|
|
82
59
|
assert.ok(!/<situational-context>[\s\S]*<\/crtr-bearings>/.test(block), 'the block is a sibling of <crtr-bearings>, not nested inside it');
|
|
83
60
|
});
|
|
84
|
-
test('node-local doc identity honors explicit frontmatter `name`, not the physical filename', () => {
|
|
85
|
-
// node-local docs follow the one substrate identity rule (resolveDocName):
|
|
86
|
-
// an explicit `name:` renders and dedups under that name, not the filename.
|
|
87
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
88
|
-
const dir = memoryDir(meta.node_id);
|
|
89
|
-
mkdirSync(dir, { recursive: true });
|
|
90
|
-
writeFileSync(join(dir, 'physical-filename.md'), '---\nkind: knowledge\nname: explicit-identity\nwhen-and-why-to-read: When testing, this reference should be read because it is a regression fixture\nsystem-prompt-visibility: preview\n---\nTest body.\n');
|
|
91
|
-
const block = buildContextIntro(meta.node_id);
|
|
92
|
-
assert.match(block, /\u2500 explicit-identity {2}# read when:/, 'tree entry renders under the explicit frontmatter name');
|
|
93
|
-
assert.ok(!block.includes('physical-filename'), 'the physical filename never surfaces once an explicit name is set');
|
|
94
|
-
});
|
|
95
|
-
test('a CLAUDE.md in the node\'s cwd does not enter the bearings; only the <environment> snapshot remains', () => {
|
|
96
|
-
// buildProjectContextBlock now emits only the cwd/git environment snapshot.
|
|
97
|
-
// Project guidance lives in the document substrate instead, so a bare on-disk
|
|
98
|
-
// CLAUDE.md stays out of the bearings entirely.
|
|
99
|
-
const proj = mkdtempSync(join(tmpdir(), 'crtr-proj-'));
|
|
100
|
-
writeFileSync(join(proj, 'CLAUDE.md'), 'PROJECT_MARKER: build then commit.\n');
|
|
101
|
-
const meta = spawnNode({ kind: 'general', cwd: proj, parent: null });
|
|
102
|
-
const block = buildContextIntro(meta.node_id);
|
|
103
|
-
assert.doesNotMatch(block, /<project_instructions/, 'no <project_instructions> block is ever emitted');
|
|
104
|
-
assert.doesNotMatch(block, /PROJECT_MARKER: build then commit\./, 'the CLAUDE.md body never rides the bearings');
|
|
105
|
-
assert.match(block, /<project_context>/, 'project_context wrapper still present');
|
|
106
|
-
assert.match(block, /<environment cwd=".*crtr-proj-.*">/, 'environment block still rides inside project_context');
|
|
107
|
-
assert.match(block, /Directory:\n CLAUDE\.md\n/, 'environment block still includes an ls-style listing');
|
|
108
|
-
assert.match(block, /Git: not a git repository\./, 'git snapshot degrades cleanly for a non-repo');
|
|
109
|
-
assert.match(block, /<environment[\s\S]*<\/environment>\n<\/project_context>$/, 'environment block closes project_context');
|
|
110
|
-
assert.ok(block.indexOf('</crtr-bearings>') < block.indexOf('<project_context>'), 'project_context follows the crtr-bearings block');
|
|
111
|
-
rmSync(proj, { recursive: true, force: true });
|
|
112
|
-
});
|
|
113
|
-
test('orchestrator bearings: across-cycles framing + node-local substrate docs ride into <knowledge>; a non-substrate .md file is never inlined', () => {
|
|
114
|
-
// Bug-regression: review finding M1 — buildContextBearings renders <knowledge>.
|
|
115
|
-
// Node-local substrate docs render as tree entries at their rung; a
|
|
116
|
-
// non-substrate .md file (no frontmatter `kind`) never surfaces.
|
|
117
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
118
|
-
promote(meta.node_id); // flip to orchestrator mode — the across-cycles gate
|
|
119
|
-
const dir = memoryDir(meta.node_id);
|
|
120
|
-
mkdirSync(dir, { recursive: true });
|
|
121
|
-
// Write a non-substrate MEMORY.md file to verify it is never surfaced in the block.
|
|
122
|
-
const legacyIndexPath = join(dir, 'MEMORY.md');
|
|
123
|
-
writeFileSync(legacyIndexPath, '# memory index — one pointer line per memory; how-to in "Your long-term memory".\n\n- [Flaky build](flaky-build.md) — first run fails\n');
|
|
124
|
-
// A node-local substrate doc DOES ride into the knowledge block at its rung.
|
|
125
|
-
writeFileSync(join(dir, 'flaky-build.md'), '---\nkind: knowledge\nwhen-and-why-to-read: When the build flakes, this reference should be read because the first run fails\nsystem-prompt-visibility: preview\n---\nFirst run always fails; rerun once.\n');
|
|
126
|
-
const block = buildContextIntro(meta.node_id);
|
|
127
|
-
assert.match(block, /shared document store, not a task tracker/, 'still carries the base framing');
|
|
128
|
-
assert.match(block, /refresh cycles/, 'orchestrator gets the across-cycles framing');
|
|
129
|
-
assert.match(block, /<memory kind="knowledge">/, 'knowledge catalog present as a memory block');
|
|
130
|
-
assert.match(block, /flaky-build {2}# read when: When the build flakes, this reference should be read because the first run fails\./, 'node-local doc renders as a tree entry with its routing line');
|
|
131
|
-
// The non-substrate file never renders: no header line, no pointer line, no path.
|
|
132
|
-
assert.ok(!block.includes('# memory index'), 'the index header comment is NOT inlined');
|
|
133
|
-
assert.ok(!block.includes('- [Flaky build](flaky-build.md)'), 'index pointer lines are NOT inlined');
|
|
134
|
-
assert.ok(!block.includes(legacyIndexPath), 'no absolute index (MEMORY.md) path');
|
|
135
|
-
assert.ok(!block.includes('node-local · '), 'no label·dir stanza header');
|
|
136
|
-
assert.match(block, /<\/crtr-bearings>/);
|
|
137
|
-
});
|
|
138
|
-
test('orchestrator bearings: no per-store stanzas or (empty) markers; a rung-none node-local doc still surfaces as a bare-name tree entry', () => {
|
|
139
|
-
// Bug-regression: review findings M1 + M6 — the <knowledge> block carries no
|
|
140
|
-
// per-store `label · dir` stanzas or (empty) markers, and node-local docs are
|
|
141
|
-
// NOT filtered on rung: a migrated node-local doc defaults
|
|
142
|
-
// system-prompt-visibility: none and must still ride into the knowledge memory block as
|
|
143
|
-
// its bare name (floored to the `name` rung; never its body).
|
|
144
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
145
|
-
promote(meta.node_id); // flip to orchestrator mode
|
|
146
|
-
const dir = memoryDir(meta.node_id);
|
|
147
|
-
mkdirSync(dir, { recursive: true });
|
|
148
|
-
writeFileSync(join(dir, 'rung-none-fact.md'), '---\nkind: knowledge\n---\nbody that must not render at the none rung\n');
|
|
149
|
-
const block = buildContextIntro(meta.node_id);
|
|
150
|
-
// No per-store stanza headers, no (empty) markers, no MEMORY.md paths.
|
|
151
|
-
assert.ok(!block.includes(`node-local · ${memoryDir(meta.node_id)}`), 'no node-local stanza header');
|
|
152
|
-
assert.ok(!block.includes('user-global · '), 'no user-global stanza header');
|
|
153
|
-
assert.ok(!block.includes('project · '), 'no project stanza header');
|
|
154
|
-
assert.doesNotMatch(block, /\(empty\)/, 'no (empty) markers');
|
|
155
|
-
assert.ok(!block.includes('MEMORY.md'), 'no MEMORY.md path in the block');
|
|
156
|
-
// M6: rung-none node-local doc surfaces as a bare-name tree entry only.
|
|
157
|
-
assert.match(block, /─ rung-none-fact\n/, 'rung-none node-local doc surfaces as a bare-name tree entry');
|
|
158
|
-
assert.ok(!block.includes('body that must not render'), 'none rung renders the name only, not the body');
|
|
159
|
-
});
|
|
160
|
-
test('promotion guidance delivers the orchestrator context-dir framing', () => {
|
|
161
|
-
// A node spawns as a base worker (no orchestrator bearings). On promotion the
|
|
162
|
-
// persona injector must build the across-cycles context-dir framing it never
|
|
163
|
-
// got at spawn (delivered at the next turn boundary, not returned by promote).
|
|
164
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
165
|
-
promote(meta.node_id);
|
|
166
|
-
const drift = personaDrift(meta.node_id);
|
|
167
|
-
const guidance = drift?.guidance ?? '';
|
|
168
|
-
assert.ok(drift !== null, 'promotion drifts the persona (base→orchestrator)');
|
|
169
|
-
assert.match(guidance, /refresh cycles/, 'promotion guidance carries the across-cycles framing');
|
|
170
|
-
assert.ok(guidance.includes(contextDir(meta.node_id)), 'and names the context dir path');
|
|
171
|
-
});
|
|
172
61
|
function makeFakePi() {
|
|
173
62
|
return {
|
|
174
63
|
sent: [],
|
|
@@ -182,7 +71,7 @@ function makeFakePi() {
|
|
|
182
71
|
function fakeCtx(entries = []) {
|
|
183
72
|
return { sessionManager: { getEntries: () => entries } };
|
|
184
73
|
}
|
|
185
|
-
test('session_start injects the block as the first message of an empty session', () => {
|
|
74
|
+
test('session_start injects the block as the first message of an empty session', async () => {
|
|
186
75
|
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
187
76
|
process.env['CRTR_NODE_ID'] = meta.node_id;
|
|
188
77
|
const pi = makeFakePi();
|
|
@@ -190,13 +79,13 @@ test('session_start injects the block as the first message of an empty session',
|
|
|
190
79
|
assert.ok(pi.handler, 'session_start handler registered');
|
|
191
80
|
// Empty session → inject the block as its own custom message (no delivery
|
|
192
81
|
// options → it precedes the first prompt).
|
|
193
|
-
pi.handler({ reason: 'startup' }, fakeCtx());
|
|
82
|
+
await pi.handler({ reason: 'startup' }, fakeCtx());
|
|
194
83
|
assert.equal(pi.sent.length, 1, 'one message injected');
|
|
195
84
|
assert.equal(pi.sent[0].customType, CONTEXT_INTRO_CUSTOM_TYPE);
|
|
196
85
|
assert.equal(pi.sent[0].display, true);
|
|
197
86
|
assert.match(pi.sent[0].content, /<crtr-bearings>/);
|
|
198
87
|
});
|
|
199
|
-
test('session_start is idempotent across resume (skips if already in history)', () => {
|
|
88
|
+
test('session_start is idempotent across resume (skips if already in history)', async () => {
|
|
200
89
|
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
201
90
|
process.env['CRTR_NODE_ID'] = meta.node_id;
|
|
202
91
|
// Restored session already carries OUR block (which names this node id) → no
|
|
@@ -209,14 +98,14 @@ test('session_start is idempotent across resume (skips if already in history)',
|
|
|
209
98
|
const entries = [
|
|
210
99
|
{ type: 'custom_message', customType: CONTEXT_INTRO_CUSTOM_TYPE, content: buildContextIntro(meta.node_id) },
|
|
211
100
|
];
|
|
212
|
-
pi.handler({ reason: 'resume' }, fakeCtx(entries));
|
|
101
|
+
await pi.handler({ reason: 'resume' }, fakeCtx(entries));
|
|
213
102
|
assert.equal(pi.sent.length, 0, 'our own block already in history → skip');
|
|
214
103
|
});
|
|
215
|
-
test('session_start is inert when CRTR_NODE_ID is absent', () => {
|
|
104
|
+
test('session_start is inert when CRTR_NODE_ID is absent', async () => {
|
|
216
105
|
delete process.env['CRTR_NODE_ID'];
|
|
217
106
|
const pi = makeFakePi();
|
|
218
107
|
registerCanvasContextIntro(pi);
|
|
219
|
-
pi.handler({ reason: 'startup' }, fakeCtx());
|
|
108
|
+
await pi.handler({ reason: 'startup' }, fakeCtx());
|
|
220
109
|
assert.equal(pi.sent.length, 0);
|
|
221
110
|
});
|
|
222
111
|
test('renderer registered for the customType; collapsed hides body, ctrl+o expand reveals it', () => {
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
// no broker capacity and is never gated.
|
|
10
10
|
import { after, afterEach, before, test } from 'node:test';
|
|
11
11
|
import assert from 'node:assert/strict';
|
|
12
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
12
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
13
13
|
import { tmpdir } from 'node:os';
|
|
14
14
|
import { join } from 'node:path';
|
|
15
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
15
16
|
import { closeDb } from '../canvas/db.js';
|
|
16
|
-
import { armCron, getCron, listCronRuns } from '../canvas/crons.js';
|
|
17
|
-
import { cronLaunchesNode, runDueCrons } from '../../daemon/cron-run.js';
|
|
17
|
+
import { armCron, cancelCron, getCron, listCronRuns } from '../canvas/crons.js';
|
|
18
|
+
import { cronLaunchesNode, executeCron, markSelfCanceledCronRun, runDueCrons } from '../../daemon/cron-run.js';
|
|
18
19
|
let home;
|
|
19
20
|
let realHome;
|
|
20
21
|
function arm(overrides) {
|
|
@@ -87,6 +88,24 @@ test('a plain shell cron runs at zero capacity — only launches are gated', asy
|
|
|
87
88
|
await Promise.all(settlements);
|
|
88
89
|
assert.equal(getCron('plain-shell'), null, 'the one-shot settled and was consumed');
|
|
89
90
|
});
|
|
91
|
+
test('an on-change cron that cancels itself still delivers its final output', async () => {
|
|
92
|
+
const runIdPath = join(home, 'self-cancel-run-id');
|
|
93
|
+
arm({
|
|
94
|
+
cron_id: 'self-cancel-delivery',
|
|
95
|
+
command: `printf '%s' "$CRTR_RUN_ID" > '${runIdPath}'; echo settled; sleep 0.1`,
|
|
96
|
+
recur: JSON.stringify({ every: '1h' }),
|
|
97
|
+
on_output: 'on-change',
|
|
98
|
+
sink: JSON.stringify({ human: true }),
|
|
99
|
+
});
|
|
100
|
+
const run = executeCron(getCron('self-cancel-delivery'), { outOfBand: false });
|
|
101
|
+
for (let i = 0; i < 50 && !existsSync(runIdPath); i++)
|
|
102
|
+
await delay(10);
|
|
103
|
+
assert.ok(existsSync(runIdPath), 'the live run exposed its id to its self-cancel command');
|
|
104
|
+
assert.equal(markSelfCanceledCronRun('self-cancel-delivery', readFileSync(runIdPath, 'utf8')), true);
|
|
105
|
+
assert.equal(cancelCron('self-cancel-delivery', { preserveRunningProcess: true }), true);
|
|
106
|
+
const record = await run;
|
|
107
|
+
assert.equal(record?.delivered, 'delivered: human notify');
|
|
108
|
+
});
|
|
90
109
|
test('cronLaunchesNode classifies by command verb and armed sink', () => {
|
|
91
110
|
const of = (command, sink = '{}') => cronLaunchesNode({ command, sink });
|
|
92
111
|
assert.equal(of("crtr node lifecycle revive 'n' --fresh"), true);
|
|
@@ -8,11 +8,11 @@ import { createServer } from 'node:net';
|
|
|
8
8
|
import { createNode, getNode, subscribe } from '../canvas/canvas.js';
|
|
9
9
|
import { closeDb } from '../canvas/db.js';
|
|
10
10
|
import { readInboxSince } from '../feed/inbox.js';
|
|
11
|
-
import { superviseTick
|
|
11
|
+
import { superviseTick } from '../../daemon/crtrd.js';
|
|
12
|
+
import { readPidfile } from '../../daemon/pidfile.js';
|
|
12
13
|
import { verifyDaemonStartup, waitForDaemonExit } from '../../daemon/manage.js';
|
|
13
14
|
import { waitForBrokerViewSocket } from '../runtime/placement-tmux.js';
|
|
14
15
|
import { viewSocketPath } from '../canvas/paths.js';
|
|
15
|
-
import { signBrandedHostArtifacts, brandedHostWorks, codesignIdentitiesForBrandedHost } from '../runtime/branded-host.js';
|
|
16
16
|
import { markBusy, clearBusy } from '../runtime/busy.js';
|
|
17
17
|
import { bindTestFleet } from './helpers/fleet.js';
|
|
18
18
|
import { resetFleetForTests } from '../runtime/fleet.js';
|
|
@@ -354,21 +354,3 @@ test('waitForBrokerViewSocket returns false as soon as the real broker process e
|
|
|
354
354
|
assert.equal(ready, false, 'an exited broker must fail readiness');
|
|
355
355
|
assert.ok(Date.now() - started < 1000, 'the readiness guard must fail fast instead of waiting for the socket deadline');
|
|
356
356
|
});
|
|
357
|
-
test('signBrandedHostArtifacts signs the copied libnode before the branded binary', () => {
|
|
358
|
-
const signed = [];
|
|
359
|
-
signBrandedHostArtifacts('/tmp/crouter', '/tmp/libnode.dylib', (path) => signed.push(path));
|
|
360
|
-
assert.deepEqual(signed, ['/tmp/libnode.dylib', '/tmp/crouter']);
|
|
361
|
-
});
|
|
362
|
-
test('codesignIdentitiesForBrandedHost prefers configured or discovered identities and otherwise ad-hoc signs', () => {
|
|
363
|
-
assert.deepEqual(codesignIdentitiesForBrandedHost({ configured: 'Developer ID Application: Example', discovered: 'Apple Development: Local' }), ['Developer ID Application: Example']);
|
|
364
|
-
assert.deepEqual(codesignIdentitiesForBrandedHost({ discovered: 'Apple Development: Local' }), ['Apple Development: Local']);
|
|
365
|
-
assert.deepEqual(codesignIdentitiesForBrandedHost(), ['-']);
|
|
366
|
-
});
|
|
367
|
-
test('brandedHostWorks health-checks if a binary is executable', () => {
|
|
368
|
-
// Issue #102: the branded host binary can be corrupted or killed by macOS
|
|
369
|
-
// before exec, causing spawn() to fail silently. The health-check detects this.
|
|
370
|
-
const goodBin = process.execPath; // a real, executable binary
|
|
371
|
-
const badBin = '/nonexistent/crouter-broken';
|
|
372
|
-
assert.equal(brandedHostWorks(goodBin), true, 'health-check passes for a real executable binary');
|
|
373
|
-
assert.equal(brandedHostWorks(badBin), false, 'health-check fails for a nonexistent binary');
|
|
374
|
-
});
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// fires on its own (fails toward 'pending', not 'wedged').
|
|
13
13
|
import { test } from 'node:test';
|
|
14
14
|
import assert from 'node:assert/strict';
|
|
15
|
-
import { wedgeVerdict, WEDGE_QUIET_MS, WEDGE_CPU_MAX_PERCENT, sumTreeCpu, treeHasDescendants } from '../../daemon/
|
|
15
|
+
import { wedgeVerdict, WEDGE_QUIET_MS, WEDGE_CPU_MAX_PERCENT, sumTreeCpu, treeHasDescendants, } from '../../daemon/reconcilers/broker-supervision.js';
|
|
16
16
|
test('wedgeVerdict: a node whose turn already ended is never wedged, regardless of the other signals', () => {
|
|
17
17
|
assert.equal(wedgeVerdict({ busy: false, quietForMs: null, cpuPercent: null }), 'leave');
|
|
18
18
|
assert.equal(wedgeVerdict({ busy: false, quietForMs: 10 * 60 * 60_000, cpuPercent: 0 }), 'leave');
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// unchanged — only its caller moved into the table).
|
|
12
12
|
import { test } from 'node:test';
|
|
13
13
|
import assert from 'node:assert/strict';
|
|
14
|
-
import { classifyDeadNode, retryResumeMode
|
|
14
|
+
import { classifyDeadNode, retryResumeMode } from '../../daemon/fleet.js';
|
|
15
15
|
/** A table-row fixture: an active, booted-or-not node in the named state. */
|
|
16
16
|
function row(over = {}) {
|
|
17
17
|
return {
|
|
@@ -83,20 +83,3 @@ test('retryResumeMode: interrupted turns and pending cycles recover as cycles; i
|
|
|
83
83
|
assert.equal(retryResumeMode({}, false), true, 'cycle_pending undefined idle crash resumes strictly');
|
|
84
84
|
assert.equal(retryResumeMode(null, false), true, 'no meta and no busy marker resumes strictly');
|
|
85
85
|
});
|
|
86
|
-
// ===========================================================================
|
|
87
|
-
// The throttle's backoff schedule (pure): attempt n waits min(5s·2^(n-1), 10min);
|
|
88
|
-
// zero consecutive failures respawn immediately (the sub-second yield respawn
|
|
89
|
-
// D-3 buys). The stateful throttle behavior lives in respawn-throttle.test.ts.
|
|
90
|
-
// ===========================================================================
|
|
91
|
-
test('respawnBackoffMs: immediate at zero failures, doubling from 5s, capped at 10 minutes', () => {
|
|
92
|
-
assert.equal(respawnBackoffMs(0), 0);
|
|
93
|
-
assert.equal(respawnBackoffMs(1), 5_000);
|
|
94
|
-
assert.equal(respawnBackoffMs(2), 10_000);
|
|
95
|
-
assert.equal(respawnBackoffMs(3), 20_000);
|
|
96
|
-
assert.equal(respawnBackoffMs(5), 80_000);
|
|
97
|
-
assert.equal(respawnBackoffMs(20), 600_000, 'the backoff is capped, never unbounded');
|
|
98
|
-
});
|
|
99
|
-
test('throttle constants: healthy uptime is 60s; the loop terminalizes at 6 consecutive short-lived exits', () => {
|
|
100
|
-
assert.equal(HEALTHY_UPTIME_MS, 60_000);
|
|
101
|
-
assert.equal(MAX_RESPAWN_ATTEMPTS, 6);
|
|
102
|
-
});
|
|
@@ -121,7 +121,7 @@ declare class FakeSession {
|
|
|
121
121
|
private disposed;
|
|
122
122
|
private eventSeq;
|
|
123
123
|
private timer;
|
|
124
|
-
/**
|
|
124
|
+
/** Compiled-seam graceful-teardown vehicle: a real active turn that only settles
|
|
125
125
|
* after abort(), so the broker's bounded abort wait is observable. */
|
|
126
126
|
private heldTurn;
|
|
127
127
|
private readonly listeners;
|
|
@@ -269,7 +269,7 @@ class FakeSession {
|
|
|
269
269
|
disposed = false;
|
|
270
270
|
eventSeq = 0;
|
|
271
271
|
timer;
|
|
272
|
-
/**
|
|
272
|
+
/** Compiled-seam graceful-teardown vehicle: a real active turn that only settles
|
|
273
273
|
* after abort(), so the broker's bounded abort wait is observable. */
|
|
274
274
|
heldTurn;
|
|
275
275
|
// The broker's fan-out subscribers (broker.ts `session.subscribe(...)`) and the
|
|
@@ -306,7 +306,7 @@ class FakeSession {
|
|
|
306
306
|
// Mirror the real pi SDK: a model-less construction (`model === undefined`)
|
|
307
307
|
// does NOT leave `session.model` undefined — Agent.createMutableAgentState()
|
|
308
308
|
// falls back to a hardcoded unknown-stub. Representing that here is what
|
|
309
|
-
// makes the
|
|
309
|
+
// makes the compiled seam tests exercise the broker's real sessionHasNoModel()/
|
|
310
310
|
// isUnknownModel() guard path (broker.ts) rather than the `=== undefined`
|
|
311
311
|
// shortcut that never happens against the real engine.
|
|
312
312
|
this.currentModel = model ?? UNKNOWN_MODEL_STUB;
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
// and fires REAL lifecycle events under harness control, so the real hooks
|
|
8
8
|
// drive real canvas state across the process boundary.
|
|
9
9
|
//
|
|
10
|
-
// The runtime
|
|
11
|
-
// seam in piCommand (src/core/runtime/tmux.ts). We therefore receive:
|
|
10
|
+
// The runtime execs us exactly where it would exec `pi`, via the CRTR_PI_BINARY
|
|
11
|
+
// seam in piCommand (src/core/runtime/tmux-driver.ts). We therefore receive:
|
|
12
12
|
// • argv: -e <ext> … -n <label> [--session <path>] [--model …] [--tools …]
|
|
13
13
|
// [--append-system-prompt <file>] [<kickoff prompt>] (buildPiArgv)
|
|
14
14
|
// • env: CRTR_NODE_ID, CRTR_KIND, CRTR_MODE, CRTR_LIFECYCLE, CRTR_HOME,
|
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
// The `focuses` table (canvas.db, migration v6) + its canvas setters + the
|
|
4
4
|
// placement reads that compose over them. The table is the CANONICAL focus store
|
|
5
5
|
// — there is no focus.ptr file and no dual-write bridge. Covers:
|
|
6
|
-
// - migration v6 adds `focuses` to a fresh db
|
|
7
|
-
// idempotent / forward-only on re-run + re-open
|
|
6
|
+
// - migration v6 adds `focuses` to a fresh db
|
|
8
7
|
// - canvas setters/reads round-trip: open / setOccupant / setPane / close;
|
|
9
8
|
// getFocusByNode / getFocusByPane / getFocusById / listFocuses
|
|
10
|
-
// - UNIQUE(node_id): a second focus row (and an occupant UPDATE) for one node
|
|
11
|
-
// is rejected (upholds "a node occupies <=1 focus", Q5)
|
|
12
9
|
// - independent focus rows don't contend
|
|
13
10
|
// - placement focusOf / isFocused / focusByPane / focusedNodes / listFocuses
|
|
14
11
|
// GC dead-pane viewer rows on read (liveOrPrune), and pass null-pane rows
|
|
@@ -18,10 +15,8 @@ import assert from 'node:assert/strict';
|
|
|
18
15
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
19
16
|
import { tmpdir } from 'node:os';
|
|
20
17
|
import { join } from 'node:path';
|
|
21
|
-
import { DatabaseSync } from 'node:sqlite';
|
|
22
18
|
import { openFocusRow, setFocusOccupant, setFocusPane, closeFocusRow, getFocusByNode, getFocusByPane, getFocusById, listFocuses, } from '../canvas/focuses.js';
|
|
23
|
-
import { openDb, closeDb,
|
|
24
|
-
import { canvasDbPath, ensureHome } from '../canvas/paths.js';
|
|
19
|
+
import { openDb, closeDb, MIGRATIONS } from '../canvas/db.js';
|
|
25
20
|
import { focusOf, isFocused, focusByPane, focusedNodes, listFocuses as placementListFocuses, } from '../runtime/placement.js';
|
|
26
21
|
let home;
|
|
27
22
|
function userVersion(db) {
|
|
@@ -51,76 +46,6 @@ test('a fresh db migrates to the latest version and has the focuses table', () =
|
|
|
51
46
|
assert.equal(userVersion(db), MIGRATIONS.length);
|
|
52
47
|
assert.ok(tableNames(db).includes('focuses'), 'focuses table exists on a fresh db');
|
|
53
48
|
});
|
|
54
|
-
test('the focuses table has the v6 shape (UNIQUE node_id, nullable pane/session)', () => {
|
|
55
|
-
const db = openDb();
|
|
56
|
-
const cols = db.prepare('PRAGMA table_info(focuses)').all();
|
|
57
|
-
const byName = new Map(cols.map((c) => [c.name, c]));
|
|
58
|
-
assert.equal(byName.get('focus_id')?.pk, 1, 'focus_id is the primary key');
|
|
59
|
-
assert.equal(byName.get('node_id')?.notnull, 1, 'node_id is NOT NULL');
|
|
60
|
-
assert.equal(byName.get('pane')?.notnull, 0, 'pane is nullable');
|
|
61
|
-
assert.equal(byName.get('session')?.notnull, 0, 'session is nullable');
|
|
62
|
-
// node_id carries a UNIQUE index.
|
|
63
|
-
const idx = db.prepare('PRAGMA index_list(focuses)').all();
|
|
64
|
-
assert.ok(idx.some((i) => i.unique === 1), 'a UNIQUE index exists (the node_id constraint)');
|
|
65
|
-
});
|
|
66
|
-
test('a v5 db migrates forward, adding focuses without disturbing existing data', () => {
|
|
67
|
-
// Hand-build a db at exactly v5: baseline + the four v2 runtime columns + the
|
|
68
|
-
// v5 pane column + edges WITH the v4 FK shape, user_version=5 — the shape just
|
|
69
|
-
// before v6.
|
|
70
|
-
ensureHome();
|
|
71
|
-
const raw = new DatabaseSync(canvasDbPath());
|
|
72
|
-
raw.exec(`
|
|
73
|
-
CREATE TABLE nodes (
|
|
74
|
-
node_id TEXT PRIMARY KEY, name TEXT NOT NULL, kind TEXT NOT NULL,
|
|
75
|
-
mode TEXT NOT NULL DEFAULT 'base', lifecycle TEXT NOT NULL DEFAULT 'terminal',
|
|
76
|
-
status TEXT NOT NULL DEFAULT 'active', cwd TEXT NOT NULL, parent TEXT,
|
|
77
|
-
created TEXT NOT NULL,
|
|
78
|
-
intent TEXT, pi_pid INTEGER, window TEXT, tmux_session TEXT, pane TEXT
|
|
79
|
-
);
|
|
80
|
-
CREATE TABLE edges (
|
|
81
|
-
type TEXT NOT NULL, from_id TEXT NOT NULL, to_id TEXT NOT NULL,
|
|
82
|
-
active INTEGER NOT NULL DEFAULT 1, created TEXT NOT NULL,
|
|
83
|
-
PRIMARY KEY (type, from_id, to_id),
|
|
84
|
-
FOREIGN KEY (from_id) REFERENCES nodes(node_id) ON DELETE CASCADE,
|
|
85
|
-
FOREIGN KEY (to_id) REFERENCES nodes(node_id) ON DELETE CASCADE
|
|
86
|
-
);
|
|
87
|
-
PRAGMA user_version = 5;
|
|
88
|
-
`);
|
|
89
|
-
raw
|
|
90
|
-
.prepare('INSERT INTO nodes (node_id, name, kind, status, cwd, created, window, tmux_session, pane) VALUES (?,?,?,?,?,?,?,?,?)')
|
|
91
|
-
.run('legacy', 'Legacy', 'general', 'idle', '/tmp/work', '2020-01-01T00:00:00Z', '@9', 'crtr', '%3');
|
|
92
|
-
assert.equal(userVersion(raw), 5);
|
|
93
|
-
assert.ok(!tableNames(raw).includes('focuses'), 'precondition: no focuses table at v5');
|
|
94
|
-
raw.close();
|
|
95
|
-
// openDb() runs v6 forward.
|
|
96
|
-
const db = openDb();
|
|
97
|
-
assert.equal(userVersion(db), MIGRATIONS.length);
|
|
98
|
-
assert.ok(tableNames(db).includes('focuses'), 'focuses table added by v6');
|
|
99
|
-
// The pre-existing node row is intact (the v6 migration only adds a table).
|
|
100
|
-
const row = db
|
|
101
|
-
.prepare('SELECT status, window, tmux_session, pane FROM nodes WHERE node_id = ?')
|
|
102
|
-
.get('legacy');
|
|
103
|
-
assert.equal(row['status'], 'idle', 'existing status untouched');
|
|
104
|
-
assert.equal(row['window'], '@9', 'existing window untouched');
|
|
105
|
-
assert.equal(row['tmux_session'], 'crtr', 'existing session untouched');
|
|
106
|
-
assert.equal(row['pane'], '%3', 'existing pane untouched');
|
|
107
|
-
// The fresh focuses table is empty.
|
|
108
|
-
const n = db.prepare('SELECT COUNT(*) AS n FROM focuses').get().n;
|
|
109
|
-
assert.equal(n, 0, 'a fresh focuses table starts empty');
|
|
110
|
-
});
|
|
111
|
-
test('the v6 migration is idempotent / forward-only on re-run and re-open', () => {
|
|
112
|
-
const db = openDb();
|
|
113
|
-
assert.equal(userVersion(db), MIGRATIONS.length);
|
|
114
|
-
// Re-running migrate() is a no-op — the gate skips applied steps. The CREATE
|
|
115
|
-
// TABLE IF NOT EXISTS would be harmless anyway, but the gate must not re-fire.
|
|
116
|
-
assert.doesNotThrow(() => migrate(db));
|
|
117
|
-
assert.equal(userVersion(db), MIGRATIONS.length);
|
|
118
|
-
// Re-opening from disk is likewise a no-op.
|
|
119
|
-
closeDb();
|
|
120
|
-
const db2 = openDb();
|
|
121
|
-
assert.equal(userVersion(db2), MIGRATIONS.length);
|
|
122
|
-
assert.ok(tableNames(db2).includes('focuses'));
|
|
123
|
-
});
|
|
124
49
|
// ---------------------------------------------------------------------------
|
|
125
50
|
// Canvas setters / reads — open / setOccupant / setPane / close round-trip.
|
|
126
51
|
// ---------------------------------------------------------------------------
|
|
@@ -148,25 +73,6 @@ test('open / setOccupant / close round-trip with the reads', () => {
|
|
|
148
73
|
assert.equal(getFocusById('f1'), null);
|
|
149
74
|
assert.deepEqual(listFocuses(), []);
|
|
150
75
|
});
|
|
151
|
-
test('UNIQUE(node_id): a second focus row for the same node is rejected', () => {
|
|
152
|
-
openDb();
|
|
153
|
-
openFocusRow('f1', '%a', 'Sa', 'A');
|
|
154
|
-
// A second viewport occupied by the SAME node violates UNIQUE(node_id) — this
|
|
155
|
-
// is the constraint that upholds "a node occupies <=1 focus" (Q5).
|
|
156
|
-
assert.throws(() => openFocusRow('f2', '%b', 'Sb', 'A'), /UNIQUE|constraint/i);
|
|
157
|
-
// The first row is untouched; no stray second row was created.
|
|
158
|
-
assert.deepEqual(listFocuses().map((f) => f.focus_id), ['f1']);
|
|
159
|
-
});
|
|
160
|
-
test('UNIQUE(node_id): hot-swapping an occupant onto an already-focused node is rejected', () => {
|
|
161
|
-
openDb();
|
|
162
|
-
openFocusRow('f1', '%a', 'Sa', 'A');
|
|
163
|
-
openFocusRow('f2', '%b', 'Sb', 'B');
|
|
164
|
-
// B already occupies f2 — moving it onto f1 via setFocusOccupant must throw
|
|
165
|
-
// (the Q5 vacate-first is placement.focus()'s job, not this setter's).
|
|
166
|
-
assert.throws(() => setFocusOccupant('f1', 'B'), /UNIQUE|constraint/i);
|
|
167
|
-
assert.deepEqual(getFocusByNode('A'), { focus_id: 'f1', pane: '%a', session: 'Sa', node_id: 'A' });
|
|
168
|
-
assert.deepEqual(getFocusByNode('B'), { focus_id: 'f2', pane: '%b', session: 'Sb', node_id: 'B' });
|
|
169
|
-
});
|
|
170
76
|
test('independent focus rows do not contend', () => {
|
|
171
77
|
openDb();
|
|
172
78
|
openFocusRow('f1', '%a', 'Sa', 'A');
|
|
@@ -185,8 +91,8 @@ test('independent focus rows do not contend', () => {
|
|
|
185
91
|
// A row whose viewer pane no longer exists is pruned the next time it is read,
|
|
186
92
|
// so the registry self-heals without a sweeper; a row with a null pane (a
|
|
187
93
|
// registered-but-not-yet-realized viewer) is passed through. A live tmux pane
|
|
188
|
-
// can't be fabricated in the
|
|
189
|
-
// here; the live-pane read is covered in the
|
|
94
|
+
// can't be fabricated in the ordinary suite, so we cover the prune + null-pane paths
|
|
95
|
+
// here; the live-pane read is covered in the compiled-seam broker lifecycle suite.
|
|
190
96
|
// ---------------------------------------------------------------------------
|
|
191
97
|
test('placement reads GC dead-pane viewer rows and keep null-pane rows', () => {
|
|
192
98
|
openDb();
|
|
@@ -6,9 +6,6 @@ export declare const delay: (ms: number) => Promise<void>;
|
|
|
6
6
|
export declare const tok: (s: string) => string;
|
|
7
7
|
export declare const frameHas: (f: BrokerToClient, token: string) => boolean;
|
|
8
8
|
export declare function brokerLogText(h: Harness, id: string): string;
|
|
9
|
-
/** lsof the holders of `path`, or null when lsof is unavailable (skip the fd
|
|
10
|
-
* check). Exit-non-zero with empty stdout means "no holders". */
|
|
11
|
-
export declare function lsofHolders(path: string): number[] | null;
|
|
12
9
|
export interface Attached {
|
|
13
10
|
client: BrokerClient;
|
|
14
11
|
frames: BrokerToClient[];
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
import { existsSync, readFileSync } from 'node:fs';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { createConnection } from 'node:net';
|
|
15
|
-
import { spawnSync } from 'node:child_process';
|
|
16
15
|
import { BrokerClient } from '../../broker-client/index.js';
|
|
17
16
|
import { CLIENT_READ_CAPS, FrameDecoder, encodeFrame, } from '../../runtime/broker-protocol.js';
|
|
18
17
|
export const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -30,19 +29,6 @@ export function brokerLogText(h, id) {
|
|
|
30
29
|
return '';
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
|
-
/** lsof the holders of `path`, or null when lsof is unavailable (skip the fd
|
|
34
|
-
* check). Exit-non-zero with empty stdout means "no holders". */
|
|
35
|
-
export function lsofHolders(path) {
|
|
36
|
-
if (spawnSync('which', ['lsof'], { stdio: 'ignore' }).status !== 0)
|
|
37
|
-
return null;
|
|
38
|
-
const out = (spawnSync('lsof', ['-t', '--', path], { encoding: 'utf8' }).stdout ?? '').trim();
|
|
39
|
-
if (out === '')
|
|
40
|
-
return [];
|
|
41
|
-
return out
|
|
42
|
-
.split('\n')
|
|
43
|
-
.map((l) => Number(l.trim()))
|
|
44
|
-
.filter((n) => Number.isFinite(n));
|
|
45
|
-
}
|
|
46
32
|
/** Build the attach kit against a lazily-resolved harness (the harness is
|
|
47
33
|
* created in the file's before() hook, after the kit is constructed). */
|
|
48
34
|
export function createAttachKit(getH) {
|
|
@@ -77,17 +77,12 @@ export interface Harness {
|
|
|
77
77
|
session: string;
|
|
78
78
|
spawnRoot(task: string, o?: SpawnOpts): string;
|
|
79
79
|
fabricateBrokerNode(o?: FabricateOpts): string;
|
|
80
|
-
spawnChild(parentId: string, task: string, o?: SpawnOpts): Promise<string>;
|
|
81
80
|
cli(nodeId: string | null, args: string[]): CliResult;
|
|
82
81
|
spawnHeadlessChild(parentId: string, task: string, o?: SpawnOpts): Promise<string>;
|
|
83
|
-
spawnHeadlessChildNoBoot(parentId: string, task: string, o?: SpawnOpts): Promise<string>;
|
|
84
|
-
turn(nodeId: string, text?: string): Promise<void>;
|
|
85
82
|
stop(nodeId: string, reason?: 'stop' | 'length' | 'aborted' | 'error', errorMessage?: string): Promise<void>;
|
|
86
|
-
finish(nodeId: string, finalText: string): Promise<void>;
|
|
87
83
|
tick(now?: number): Promise<void>;
|
|
88
84
|
fleet: DaemonFleet;
|
|
89
85
|
deliverExit(nodeId: string, status?: FleetExitStatus): Promise<void>;
|
|
90
|
-
drainFleet(): Promise<void>;
|
|
91
86
|
awaitFleetExit(nodeId: string, timeoutMs?: number): Promise<void>;
|
|
92
87
|
awaitBoot(nodeId: string, o?: {
|
|
93
88
|
minCount?: number;
|
|
@@ -98,12 +93,9 @@ export interface Harness {
|
|
|
98
93
|
timeoutMs?: number;
|
|
99
94
|
match?: RegExp;
|
|
100
95
|
}): Promise<string[]>;
|
|
101
|
-
waitForStatus(nodeId: string, status: NodeStatus, timeoutMs?: number): Promise<void>;
|
|
102
|
-
waitForPaneGone(nodeId: string, timeoutMs?: number): Promise<void>;
|
|
103
96
|
waitFor<T>(probe: () => T | undefined | null | false, o?: WaitOpts): Promise<T>;
|
|
104
97
|
node(nodeId: string): NodeMeta | null;
|
|
105
98
|
status(nodeId: string): NodeStatus | null;
|
|
106
|
-
paneAlive(nodeId: string): boolean;
|
|
107
99
|
inbox(nodeId: string): InboxEntry[];
|
|
108
100
|
injected(nodeId: string): Injected[];
|
|
109
101
|
fakeCmd(nodeId: string, cmd: Record<string, unknown>): void;
|