@north-light/crouter 0.3.172 → 0.3.174
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} +106 -177
- 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 +55 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +60 -0
- 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/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,20 +1,18 @@
|
|
|
1
|
+
// Run with: node --import tsx/esm --test src/pi-extensions/__tests__/canvas-recap.test.ts
|
|
2
|
+
//
|
|
3
|
+
// Failure atomicity: a recap that has been requested but has not produced a
|
|
4
|
+
// briefing yet must leave the pinned recap alone. A regenerating (or failing)
|
|
5
|
+
// recap that cleared the widget first would blank the user's pinned summary.
|
|
1
6
|
import { test } from 'node:test';
|
|
2
7
|
import assert from 'node:assert/strict';
|
|
3
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
8
|
import { registerCanvasRecap } from '../canvas-recap.js';
|
|
7
|
-
|
|
8
|
-
import { closeDb } from '../../core/canvas/db.js';
|
|
9
|
-
test('a streaming manual recap snapshots the partial response and replaces the pinned recap only on success', () => {
|
|
9
|
+
test('a recap replaces the pinned widget only when its generation succeeds', () => {
|
|
10
10
|
const originalNodeId = process.env['CRTR_NODE_ID'];
|
|
11
11
|
process.env['CRTR_NODE_ID'] = 'recap-regression-node';
|
|
12
12
|
const handlers = new Map();
|
|
13
13
|
let commandHandler;
|
|
14
14
|
const widgetWrites = [];
|
|
15
|
-
const notifications = [];
|
|
16
15
|
const generations = [];
|
|
17
|
-
let idleWaits = 0;
|
|
18
16
|
const recapGenerator = (conversation, finish) => {
|
|
19
17
|
generations.push({ conversation, finish });
|
|
20
18
|
};
|
|
@@ -24,133 +22,38 @@ test('a streaming manual recap snapshots the partial response and replaces the p
|
|
|
24
22
|
commandHandler = options.handler;
|
|
25
23
|
},
|
|
26
24
|
};
|
|
27
|
-
const sessionManager = {
|
|
28
|
-
getEntries: () => [{ type: 'message', message: { role: 'user', content: 'Build the recap command.' } }],
|
|
29
|
-
};
|
|
30
25
|
const ctx = {
|
|
31
26
|
ui: {
|
|
32
27
|
setWidget: (_key, content) => { widgetWrites.push(content); },
|
|
33
|
-
notify: (
|
|
28
|
+
notify: () => undefined,
|
|
29
|
+
},
|
|
30
|
+
sessionManager: {
|
|
31
|
+
getEntries: () => [{ type: 'message', message: { role: 'user', content: 'Build the recap command.' } }],
|
|
34
32
|
},
|
|
35
|
-
sessionManager,
|
|
36
33
|
model: { provider: 'test', id: 'light' },
|
|
37
34
|
isIdle: () => false,
|
|
38
|
-
waitForIdle: async () =>
|
|
35
|
+
waitForIdle: async () => undefined,
|
|
39
36
|
};
|
|
40
37
|
try {
|
|
41
38
|
registerCanvasRecap(pi, recapGenerator);
|
|
42
39
|
handlers.get('session_start')?.({}, ctx);
|
|
43
40
|
commandHandler?.('', ctx);
|
|
44
|
-
assert.equal(notifications.at(-1), 'Generating recap…', 'the manually selected command confirms that generation started');
|
|
45
41
|
generations[0]?.finish('Goal: Existing goal\nState: Existing state');
|
|
46
42
|
assert.deepEqual(widgetWrites.at(-1), ['Goal: Existing goal', 'State: Existing state']);
|
|
47
|
-
|
|
43
|
+
// A second recap requested mid-response must not disturb the pinned one
|
|
44
|
+
// until its own briefing arrives.
|
|
48
45
|
handlers.get('message_update')?.({
|
|
49
46
|
message: { role: 'assistant', content: [{ type: 'text', text: 'I am editing the live implementation now.' }] },
|
|
50
47
|
}, ctx);
|
|
51
48
|
const writesBeforeRequest = widgetWrites.length;
|
|
52
|
-
|
|
53
|
-
assert.equal(
|
|
54
|
-
assert.equal(idleWaits, 0);
|
|
55
|
-
assert.equal(generations.length, 2);
|
|
56
|
-
assert.match(generations[1].conversation, /Agent: I am editing the live implementation now\./);
|
|
49
|
+
commandHandler?.('', ctx);
|
|
50
|
+
assert.equal(generations.length, 2, 'the second request started its own generation');
|
|
57
51
|
assert.equal(widgetWrites.length, writesBeforeRequest, 'the pinned recap remains while its replacement generates');
|
|
58
|
-
handlers.get('message_update')?.({
|
|
59
|
-
message: { role: 'assistant', content: [{ type: 'text', text: 'I am now verifying the implementation.' }] },
|
|
60
|
-
}, ctx);
|
|
61
52
|
generations[1].finish('Goal: Updated goal\nState: Updated click-time state');
|
|
62
|
-
assert.deepEqual(widgetWrites.at(-1), ['Goal: Updated goal', 'State: Updated click-time state']);
|
|
63
|
-
}
|
|
64
|
-
finally {
|
|
65
|
-
handlers.get('session_shutdown')?.({}, ctx);
|
|
66
|
-
if (originalNodeId === undefined)
|
|
67
|
-
delete process.env['CRTR_NODE_ID'];
|
|
68
|
-
else
|
|
69
|
-
process.env['CRTR_NODE_ID'] = originalNodeId;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
test('review recap and naming input exclude inherited entries while retaining the post-boundary conversation', () => {
|
|
73
|
-
const originalNodeId = process.env['CRTR_NODE_ID'];
|
|
74
|
-
const originalHome = process.env['CRTR_HOME'];
|
|
75
|
-
const home = mkdtempSync(join(tmpdir(), 'crtr-recap-boundary-'));
|
|
76
|
-
const nodeId = 'review-recap-node';
|
|
77
|
-
const handlers = new Map();
|
|
78
|
-
let commandHandler;
|
|
79
|
-
const widgetWrites = [];
|
|
80
|
-
const recapInputs = [];
|
|
81
|
-
const namingInputs = [];
|
|
82
|
-
let entries = [
|
|
83
|
-
{ type: 'message', message: { role: 'user', content: 'PREBOUNDARY_CANARY inherited request' } },
|
|
84
|
-
{ type: 'message', message: { role: 'assistant', content: 'inherited answer' } },
|
|
85
|
-
{
|
|
86
|
-
type: 'custom_message',
|
|
87
|
-
customType: 'crtr-review-boundary',
|
|
88
|
-
details: { reviewId: 'review-1' },
|
|
89
|
-
},
|
|
90
|
-
{ type: 'message', message: { role: 'user', content: 'review-only finding' } },
|
|
91
|
-
{ type: 'message', message: { role: 'assistant', content: 'review-only resolution' } },
|
|
92
|
-
];
|
|
93
|
-
const pi = {
|
|
94
|
-
on: (event, handler) => { handlers.set(event, handler); },
|
|
95
|
-
registerCommand: (_name, options) => {
|
|
96
|
-
commandHandler = options.handler;
|
|
97
|
-
},
|
|
98
|
-
getSessionName: () => 'developer',
|
|
99
|
-
setSessionName: () => undefined,
|
|
100
|
-
};
|
|
101
|
-
const sessionManager = { getEntries: () => entries };
|
|
102
|
-
const ctx = {
|
|
103
|
-
ui: { setWidget: (_key, content) => { widgetWrites.push(content); } },
|
|
104
|
-
sessionManager,
|
|
105
|
-
};
|
|
106
|
-
const recapGenerator = (conversation) => { recapInputs.push(conversation); };
|
|
107
|
-
try {
|
|
108
|
-
closeDb();
|
|
109
|
-
process.env['CRTR_HOME'] = home;
|
|
110
|
-
process.env['CRTR_NODE_ID'] = nodeId;
|
|
111
|
-
createNode({
|
|
112
|
-
node_id: nodeId,
|
|
113
|
-
name: 'developer',
|
|
114
|
-
created: new Date().toISOString(),
|
|
115
|
-
cwd: '/tmp/work',
|
|
116
|
-
kind: 'developer',
|
|
117
|
-
mode: 'base',
|
|
118
|
-
lifecycle: 'terminal',
|
|
119
|
-
status: 'active',
|
|
120
|
-
review_binding: {
|
|
121
|
-
review_id: 'review-1',
|
|
122
|
-
origin_node_id: 'origin',
|
|
123
|
-
branch_file: '/tmp/review.jsonl',
|
|
124
|
-
target_file: '/tmp/target.ts',
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
registerCanvasRecap(pi, recapGenerator, (_id, conversation) => { namingInputs.push(conversation); });
|
|
128
|
-
handlers.get('session_start')?.({}, ctx);
|
|
129
|
-
commandHandler?.('', ctx);
|
|
130
|
-
assert.equal(recapInputs.length, 1);
|
|
131
|
-
assert.equal(namingInputs.length, 1);
|
|
132
|
-
for (const input of [...recapInputs, ...namingInputs]) {
|
|
133
|
-
assert.doesNotMatch(input, /PREBOUNDARY_CANARY/);
|
|
134
|
-
assert.match(input, /review-only finding/);
|
|
135
|
-
assert.match(input, /review-only resolution/);
|
|
136
|
-
}
|
|
137
|
-
entries = [{ type: 'message', message: { role: 'user', content: 'PREBOUNDARY_CANARY without a boundary' } }];
|
|
138
|
-
handlers.get('message_update')?.({
|
|
139
|
-
message: { role: 'assistant', content: 'PREBOUNDARY_CANARY streaming response without a boundary' },
|
|
140
|
-
}, ctx);
|
|
141
|
-
commandHandler?.('', ctx);
|
|
142
|
-
assert.equal(recapInputs.length, 1, 'a markerless review produces no recap input, including a streaming partial');
|
|
143
|
-
assert.equal(namingInputs.length, 1, 'a markerless review produces no naming input, including a streaming partial');
|
|
144
|
-
assert.equal(widgetWrites.at(-1), undefined, 'a markerless review clears the recap widget');
|
|
53
|
+
assert.deepEqual(widgetWrites.at(-1), ['Goal: Updated goal', 'State: Updated click-time state'], 'success replaces the pinned recap');
|
|
145
54
|
}
|
|
146
55
|
finally {
|
|
147
56
|
handlers.get('session_shutdown')?.({}, ctx);
|
|
148
|
-
closeDb();
|
|
149
|
-
rmSync(home, { recursive: true, force: true });
|
|
150
|
-
if (originalHome === undefined)
|
|
151
|
-
delete process.env['CRTR_HOME'];
|
|
152
|
-
else
|
|
153
|
-
process.env['CRTR_HOME'] = originalHome;
|
|
154
57
|
if (originalNodeId === undefined)
|
|
155
58
|
delete process.env['CRTR_NODE_ID'];
|
|
156
59
|
else
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// Every assertion is on DB / disk effects (report files, inbox pointers) plus
|
|
10
10
|
// the captured sendUserMessage — tmux is unavailable here, so the focus/respawn
|
|
11
11
|
// helpers no-op (TMUX_PANE is cleared) and we drive a clean shutdown path.
|
|
12
|
-
import { test, before, after, beforeEach } from 'node:test';
|
|
12
|
+
import { test, before, after, beforeEach, afterEach } from 'node:test';
|
|
13
13
|
import assert from 'node:assert/strict';
|
|
14
14
|
import { mkdtempSync, rmSync, existsSync, readdirSync } from 'node:fs';
|
|
15
15
|
import { tmpdir } from 'node:os';
|
|
@@ -18,6 +18,9 @@ import registerCanvasStophook from '../canvas-stophook.js';
|
|
|
18
18
|
import { createNode, subscribe, getNode, setStatus } from '../../core/canvas/canvas.js';
|
|
19
19
|
import { openFocusRow, getFocusByNode, getFocusById, listFocuses } from '../../core/canvas/focuses.js';
|
|
20
20
|
import { closeDb } from '../../core/canvas/db.js';
|
|
21
|
+
import { apiSocketPath } from '../../core/canvas/paths.js';
|
|
22
|
+
import { createApiServer } from '../../daemon/api/server.js';
|
|
23
|
+
import { CrtrClient } from '../../api/client.js';
|
|
21
24
|
import { reportsDir } from '../../core/canvas/paths.js';
|
|
22
25
|
import { readInboxSince, appendInbox } from '../../core/feed/inbox.js';
|
|
23
26
|
import { STALL_REPROMPT } from '../../core/runtime/stop-guard.js';
|
|
@@ -25,6 +28,7 @@ import { markStopSignal } from '../../core/runtime/stop-signals.js';
|
|
|
25
28
|
import { isBusy } from '../../core/runtime/busy.js';
|
|
26
29
|
import { recordFault, readFault } from '../../core/runtime/fault.js';
|
|
27
30
|
let home;
|
|
31
|
+
let server;
|
|
28
32
|
let origNode;
|
|
29
33
|
let origPane;
|
|
30
34
|
function node(id, over = {}) {
|
|
@@ -46,12 +50,12 @@ function makeFakePi() {
|
|
|
46
50
|
injected: [],
|
|
47
51
|
on(e, h) { handlers[e] = h; },
|
|
48
52
|
sendUserMessage(content, options) { this.injected.push({ content, deliverAs: options?.deliverAs }); },
|
|
49
|
-
fire(e, ev, ctx) { handlers[e]?.(ev, ctx); },
|
|
53
|
+
async fire(e, ev, ctx) { await handlers[e]?.(ev, ctx); },
|
|
50
54
|
};
|
|
51
55
|
}
|
|
52
|
-
function settle(pi, event, ctx) {
|
|
53
|
-
pi.fire('agent_end', event, ctx);
|
|
54
|
-
pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
56
|
+
async function settle(pi, event, ctx) {
|
|
57
|
+
await pi.fire('agent_end', event, ctx);
|
|
58
|
+
await pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
55
59
|
}
|
|
56
60
|
/** A natural-stop agent_end event carrying one assistant text block. */
|
|
57
61
|
function stopEvent(text) {
|
|
@@ -66,16 +70,39 @@ before(() => {
|
|
|
66
70
|
origNode = process.env['CRTR_NODE_ID'];
|
|
67
71
|
origPane = process.env['TMUX_PANE'];
|
|
68
72
|
});
|
|
69
|
-
|
|
73
|
+
async function waitForSocket() {
|
|
74
|
+
const probe = CrtrClient.forLocalSocket({ autostart: false });
|
|
75
|
+
for (let i = 0; i < 200; i++) {
|
|
76
|
+
if (existsSync(apiSocketPath())) {
|
|
77
|
+
try {
|
|
78
|
+
await probe.healthz();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// The socket path appears before the in-process server accepts requests.
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`api socket never answered at ${apiSocketPath()}`);
|
|
88
|
+
}
|
|
89
|
+
beforeEach(async () => {
|
|
70
90
|
closeDb();
|
|
71
91
|
if (home)
|
|
72
92
|
rmSync(home, { recursive: true, force: true });
|
|
73
93
|
home = mkdtempSync(join(tmpdir(), 'crtr-stophook-end-'));
|
|
74
94
|
process.env['CRTR_HOME'] = home;
|
|
95
|
+
server = createApiServer();
|
|
96
|
+
await waitForSocket();
|
|
75
97
|
// Force the clean-shutdown path (no in-place respawn) so the refresh test is
|
|
76
98
|
// deterministic even when the suite runs inside a tmux pane.
|
|
77
99
|
delete process.env['TMUX_PANE'];
|
|
78
100
|
});
|
|
101
|
+
afterEach(async () => {
|
|
102
|
+
await server?.close();
|
|
103
|
+
server = undefined;
|
|
104
|
+
closeDb();
|
|
105
|
+
});
|
|
79
106
|
after(() => {
|
|
80
107
|
closeDb();
|
|
81
108
|
if (home)
|
|
@@ -90,7 +117,7 @@ after(() => {
|
|
|
90
117
|
else
|
|
91
118
|
process.env['TMUX_PANE'] = origPane;
|
|
92
119
|
});
|
|
93
|
-
test('natural stop commits idle-release only at agent_settled', { timeout: 1_000 }, () => {
|
|
120
|
+
test('natural stop commits idle-release only at agent_settled', { timeout: 1_000 }, async () => {
|
|
94
121
|
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
95
122
|
createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
|
|
96
123
|
createNode(node('worker', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
|
|
@@ -101,12 +128,12 @@ test('natural stop commits idle-release only at agent_settled', { timeout: 1_000
|
|
|
101
128
|
registerCanvasStophook(pi);
|
|
102
129
|
let shutdown = false;
|
|
103
130
|
const ctx = { shutdown: () => { shutdown = true; } };
|
|
104
|
-
pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
105
|
-
pi.fire('agent_end', stopEvent('still waiting on the worker'), ctx);
|
|
131
|
+
await pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
132
|
+
await pi.fire('agent_end', stopEvent('still waiting on the worker'), ctx);
|
|
106
133
|
assert.equal(getNode('mgr')?.status, 'active', 'agent_end is staging-only');
|
|
107
134
|
assert.equal(isBusy('mgr'), true, 'agent_end cannot clear whole-run busy state');
|
|
108
135
|
assert.equal(shutdown, false, 'agent_end cannot route a natural stop');
|
|
109
|
-
pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
136
|
+
await pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
110
137
|
const m = getNode('mgr');
|
|
111
138
|
assert.equal(isBusy('mgr'), false, 'agent_settled clears whole-run busy state');
|
|
112
139
|
assert.equal(m?.intent, 'idle-release', 'mgr idle-released');
|
|
@@ -120,7 +147,7 @@ test('natural stop commits idle-release only at agent_settled', { timeout: 1_000
|
|
|
120
147
|
// the done-branch handoff/openFocus on an idle-release would leave a row here.
|
|
121
148
|
assert.equal(listFocuses().length, 0, 'awaiting+unfocused leaves the focuses table empty');
|
|
122
149
|
});
|
|
123
|
-
test('gh-451: idle-release does NOT release while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, () => {
|
|
150
|
+
test('gh-451: idle-release does NOT release while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, async () => {
|
|
124
151
|
// Reproduces the #451 race: a subscriber's push landed in mgr's inbox but the
|
|
125
152
|
// in-process watcher has not yet flushed/committed the durable cursor past it
|
|
126
153
|
// (its DEBOUNCE_MS hold). If this settle released anyway, the daemon would
|
|
@@ -138,12 +165,12 @@ test('gh-451: idle-release does NOT release while a non-deferred inbox entry sit
|
|
|
138
165
|
registerCanvasStophook(pi);
|
|
139
166
|
let shutdown = false;
|
|
140
167
|
const ctx = { shutdown: () => { shutdown = true; } };
|
|
141
|
-
settle(pi, stopEvent('still waiting on the worker'), ctx);
|
|
168
|
+
await settle(pi, stopEvent('still waiting on the worker'), ctx);
|
|
142
169
|
assert.equal(getNode('mgr')?.status, 'active', 'mgr stays active — NOT idle-released while behind the cursor');
|
|
143
170
|
assert.equal(getNode('mgr')?.intent ?? null, null, 'no idle-release intent while a non-deferred entry is unseen');
|
|
144
171
|
assert.equal(shutdown, false, 'pi stays alive so the in-process watcher can still deliver/commit');
|
|
145
172
|
});
|
|
146
|
-
test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, () => {
|
|
173
|
+
test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, async () => {
|
|
147
174
|
// A canonical final can settle while the in-process watcher has delivered a
|
|
148
175
|
// child report into the inbox but has not yet committed the durable cursor.
|
|
149
176
|
// The finished branch must keep this broker alive for that delivery.
|
|
@@ -154,12 +181,12 @@ test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits
|
|
|
154
181
|
registerCanvasStophook(pi);
|
|
155
182
|
let shutdown = false;
|
|
156
183
|
const ctx = { shutdown: () => { shutdown = true; } };
|
|
157
|
-
settle(pi, stopEvent('already finalized'), ctx);
|
|
184
|
+
await settle(pi, stopEvent('already finalized'), ctx);
|
|
158
185
|
assert.equal(getNode('mgr')?.status, 'active', 'mgr stays active while the watcher catches up');
|
|
159
186
|
assert.equal(getNode('mgr')?.intent ?? null, null, 'no idle-release intent while a non-deferred entry is unseen');
|
|
160
187
|
assert.equal(shutdown, false, 'pi stays alive so the in-process watcher can still deliver/commit');
|
|
161
188
|
});
|
|
162
|
-
test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches the daemon\'s own wake gate)', { timeout: 1_000 }, () => {
|
|
189
|
+
test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches the daemon\'s own wake gate)', { timeout: 1_000 }, async () => {
|
|
163
190
|
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
164
191
|
createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
|
|
165
192
|
createNode(node('worker', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
|
|
@@ -171,26 +198,26 @@ test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches
|
|
|
171
198
|
registerCanvasStophook(pi);
|
|
172
199
|
let shutdown = false;
|
|
173
200
|
const ctx = { shutdown: () => { shutdown = true; } };
|
|
174
|
-
settle(pi, stopEvent('still waiting on the worker'), ctx);
|
|
201
|
+
await settle(pi, stopEvent('still waiting on the worker'), ctx);
|
|
175
202
|
assert.equal(getNode('mgr')?.intent, 'idle-release', 'a deferred-only unseen entry does not block release (#341 parity)');
|
|
176
203
|
assert.equal(getNode('mgr')?.status, 'idle');
|
|
177
204
|
assert.equal(shutdown, true, 'pi shuts down — deferred entries ride the next natural cycle, not this settle');
|
|
178
205
|
});
|
|
179
|
-
test('queued continuation finishes before natural-stop routing commits', { timeout: 1_000 }, () => {
|
|
206
|
+
test('queued continuation finishes before natural-stop routing commits', { timeout: 1_000 }, async () => {
|
|
180
207
|
createNode(node('leaf', { parent: null, lifecycle: 'terminal' }));
|
|
181
208
|
process.env['CRTR_NODE_ID'] = 'leaf';
|
|
182
209
|
const pi = makeFakePi();
|
|
183
210
|
registerCanvasStophook(pi);
|
|
184
211
|
let shutdown = false;
|
|
185
212
|
const ctx = { shutdown: () => { shutdown = true; } };
|
|
186
|
-
pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
187
|
-
pi.fire('agent_end', stopEvent('first attempt ended while a continuation was queued'), ctx);
|
|
213
|
+
await pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
214
|
+
await pi.fire('agent_end', stopEvent('first attempt ended while a continuation was queued'), ctx);
|
|
188
215
|
assert.equal(shutdown, false, 'the intermediate agent_end cannot route a natural stop');
|
|
189
216
|
assert.equal(getNode('leaf')?.status, 'active');
|
|
190
217
|
setStatus('leaf', 'done');
|
|
191
|
-
pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
192
|
-
pi.fire('agent_end', stopEvent('queued continuation completed the assignment'), ctx);
|
|
193
|
-
pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
218
|
+
await pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
219
|
+
await pi.fire('agent_end', stopEvent('queued continuation completed the assignment'), ctx);
|
|
220
|
+
await pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
194
221
|
assert.equal(shutdown, true, 'settlement routes from the completed continuation');
|
|
195
222
|
assert.equal(getNode('leaf')?.intent ?? null, null, 'the intermediate natural stop never idle-released the node');
|
|
196
223
|
});
|
|
@@ -201,42 +228,12 @@ test('queued continuation finishes before natural-stop routing commits', { timeo
|
|
|
201
228
|
// used by the handler now GC-prunes a viewer row whose pane is not a LIVE tmux
|
|
202
229
|
// pane (liveOrPrune → paneExists), so a fabricated '%pane' id is pruned on the
|
|
203
230
|
// first read. To drive the handler's focus path deterministically in the
|
|
204
|
-
// tmux-free
|
|
231
|
+
// tmux-free ordinary suite we register viewer rows with a NULL pane (a registered-
|
|
205
232
|
// but-not-yet-realized viewer, which liveOrPrune passes through). status='done'
|
|
206
233
|
// is reached by setting the runtime row directly (the branch reads
|
|
207
234
|
// getNode(nodeId).status).
|
|
208
235
|
// ---------------------------------------------------------------------------
|
|
209
|
-
test('§5.1.
|
|
210
|
-
// Regression guard for the broker-host cut: the engine is now a detached
|
|
211
|
-
// broker, not a pane, so there is no engine to hand to a manager. The old
|
|
212
|
-
// "dormant idle-release manager takes over the finished node's focus row"
|
|
213
|
-
// path (handFocusToManager) is DELETED — a truly-done focused node just
|
|
214
|
-
// tearDownNode's its own viewer and shuts down, EVEN when a dormant
|
|
215
|
-
// idle-release manager exists (the exact case that used to trigger takeover).
|
|
216
|
-
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
217
|
-
createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator', status: 'idle', intent: 'idle-release' }));
|
|
218
|
-
// M starts WITH a recorded LOCATION so the done-path presence-null is observable.
|
|
219
|
-
createNode(node('M', { parent: 'mgr', lifecycle: 'terminal', pane: '%m', tmux_session: 'Suser', window: '@wm' }));
|
|
220
|
-
subscribe('mgr', 'M', true);
|
|
221
|
-
openFocusRow('fM', null, 'Suser', 'M'); // null pane → focusOf returns it → drives tearDownNode
|
|
222
|
-
process.env['CRTR_NODE_ID'] = 'M';
|
|
223
|
-
setStatus('M', 'done'); // pushed final this turn
|
|
224
|
-
const pi = makeFakePi();
|
|
225
|
-
registerCanvasStophook(pi);
|
|
226
|
-
let shutdown = false;
|
|
227
|
-
settle(pi, stopEvent('done — pushed final'), { shutdown: () => { shutdown = true; } });
|
|
228
|
-
// The done branch: focusOf('M') != null → tearDownNode('M') CLOSES fM. The
|
|
229
|
-
// manager is NOT handed anything (takeover deleted). Non-vacuous: a takeover
|
|
230
|
-
// impl would leave getFocusByNode('mgr').focus_id === 'fM'.
|
|
231
|
-
assert.equal(getFocusByNode('mgr'), null, 'the manager is NOT handed the finished node\'s focus (takeover deleted)');
|
|
232
|
-
assert.equal(getFocusById('fM'), null, 'the finished node\'s viewer focus row is closed');
|
|
233
|
-
assert.equal(getFocusByNode('M'), null, 'the finished node no longer occupies any focus');
|
|
234
|
-
assert.equal(shutdown, true, 'pi shut down after teardown');
|
|
235
|
-
// The done node's own presence is nulled (setPresence(null) on the done path).
|
|
236
|
-
assert.equal(getNode('M')?.pane ?? null, null, 'the finished node\'s own LOCATION pane is nulled');
|
|
237
|
-
assert.equal(getNode('M')?.window ?? null, null, 'the finished node\'s window presence is nulled too');
|
|
238
|
-
});
|
|
239
|
-
test('§5.1.2 truly-done + focused + NO manager (root) → focus row CLOSED (Q1)', () => {
|
|
236
|
+
test('§5.1.2 truly-done + focused → focus row CLOSED, own presence nulled (Q1)', async () => {
|
|
240
237
|
// R carries a LOCATION so the close-path presence-null is observable.
|
|
241
238
|
createNode(node('R', { parent: null, lifecycle: 'terminal', pane: '%r', tmux_session: 'Suser', window: '@wr' }));
|
|
242
239
|
openFocusRow('fR', '%r', 'Suser', 'R');
|
|
@@ -244,40 +241,16 @@ test('§5.1.2 truly-done + focused + NO manager (root) → focus row CLOSED (Q1)
|
|
|
244
241
|
setStatus('R', 'done');
|
|
245
242
|
const pi = makeFakePi();
|
|
246
243
|
registerCanvasStophook(pi);
|
|
247
|
-
settle(pi, stopEvent('root done'), { shutdown: () => { } });
|
|
248
|
-
//
|
|
249
|
-
// handFocusToManager returns false → the close path: closeFocusRow(fR) +
|
|
244
|
+
await settle(pi, stopEvent('root done'), { shutdown: () => { } });
|
|
245
|
+
// The done branch closes the viewer row: closeFocusRow(fR) +
|
|
250
246
|
// setRemainOnExit(%r's window, false) (return-to-shell) + null R's presence.
|
|
251
|
-
// Non-vacuous:
|
|
252
|
-
//
|
|
253
|
-
assert.equal(getFocusById('fR'), null, 'a
|
|
247
|
+
// Non-vacuous: an impl that leaves the row open keeps it present; one that
|
|
248
|
+
// skips the presence-null leaves getNode('R').pane === '%r'.
|
|
249
|
+
assert.equal(getFocusById('fR'), null, 'a finished node\'s focus row is closed');
|
|
254
250
|
assert.equal(listFocuses().length, 0, 'no focus rows survive');
|
|
255
251
|
assert.equal(getNode('R')?.pane ?? null, null, 'the finished root\'s own LOCATION pane is nulled (close path reaps)');
|
|
256
252
|
});
|
|
257
|
-
test('§5.1.
|
|
258
|
-
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
259
|
-
createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
|
|
260
|
-
createNode(node('M', { parent: 'mgr', lifecycle: 'terminal', pane: '%m', tmux_session: 'Sa', window: '@wm' }));
|
|
261
|
-
subscribe('mgr', 'M', true);
|
|
262
|
-
openFocusRow('fOther', '%o', 'Sb', 'mgr'); // mgr already on its OWN viewport
|
|
263
|
-
openFocusRow('fM', '%m', 'Sa', 'M');
|
|
264
|
-
process.env['CRTR_NODE_ID'] = 'M';
|
|
265
|
-
setStatus('M', 'done');
|
|
266
|
-
const pi = makeFakePi();
|
|
267
|
-
registerCanvasStophook(pi);
|
|
268
|
-
settle(pi, stopEvent('M done'), { shutdown: () => { } });
|
|
269
|
-
// handFocusToManager sees getFocusByNode('mgr') != null → returns false →
|
|
270
|
-
// closeFocusRow(fM). Non-vacuous: moving mgr would either repoint its focus_id
|
|
271
|
-
// to fM (and a wrong impl that didn't close fM would leave it present) or throw
|
|
272
|
-
// UNIQUE(node_id); this pins mgr's OTHER focus untouched and M's focus gone.
|
|
273
|
-
assert.equal(getFocusById('fM'), null, "M's focus is closed");
|
|
274
|
-
assert.equal(getFocusByNode('mgr')?.focus_id, 'fOther', "the manager's other viewport is NOT stolen");
|
|
275
|
-
// MINOR: M (done) is reaped on the close path — its own presence nulled.
|
|
276
|
-
// Non-vacuous: an impl that skips the done-path setPresence-null leaves
|
|
277
|
-
// getNode('M').pane === '%m'.
|
|
278
|
-
assert.equal(getNode('M')?.pane ?? null, null, "the finished node's own LOCATION pane is nulled");
|
|
279
|
-
});
|
|
280
|
-
test('§5.1.4 truly-done + UNFOCUSED → no focus row created/touched, shuts down (Invariant P)', () => {
|
|
253
|
+
test('§5.1.4 truly-done + UNFOCUSED → no focus row created/touched, shuts down (Invariant P)', async () => {
|
|
281
254
|
createNode(node('mgr', { parent: null, lifecycle: 'terminal', mode: 'orchestrator' }));
|
|
282
255
|
createNode(node('M', { parent: 'mgr', lifecycle: 'terminal' }));
|
|
283
256
|
subscribe('mgr', 'M', true);
|
|
@@ -286,28 +259,28 @@ test('§5.1.4 truly-done + UNFOCUSED → no focus row created/touched, shuts dow
|
|
|
286
259
|
const pi = makeFakePi();
|
|
287
260
|
registerCanvasStophook(pi);
|
|
288
261
|
let shutdown = false;
|
|
289
|
-
settle(pi, stopEvent('done, never had a viewport'), { shutdown: () => { shutdown = true; } });
|
|
262
|
+
await settle(pi, stopEvent('done, never had a viewport'), { shutdown: () => { shutdown = true; } });
|
|
290
263
|
// focusOf(M) is null → the focus block is skipped entirely → just shutdown.
|
|
291
264
|
// Non-vacuous: an impl that created or handed off a focus row would leave
|
|
292
265
|
// listFocuses non-empty.
|
|
293
266
|
assert.equal(shutdown, true, 'an unfocused done node shuts down');
|
|
294
267
|
assert.equal(listFocuses().length, 0, 'no focus row was created or touched');
|
|
295
268
|
});
|
|
296
|
-
test('§5.1.5 awaiting + FOCUSED → STAY ALIVE: pi keeps running (no release), focus row untouched (F3)', () => {
|
|
269
|
+
test('§5.1.5 awaiting + FOCUSED → STAY ALIVE: pi keeps running (no release), focus row untouched (F3)', async () => {
|
|
297
270
|
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
298
271
|
createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
|
|
299
272
|
createNode(node('worker', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
|
|
300
273
|
subscribe('root', 'mgr', true);
|
|
301
274
|
subscribe('mgr', 'worker', true); // mgr awaits a live worker → would idle-release if UNfocused
|
|
302
275
|
// null pane (broker cut): focusOf passes a null-pane viewer row through, so the
|
|
303
|
-
// handler reads mgr as FOCUSED in the tmux-free
|
|
276
|
+
// handler reads mgr as FOCUSED in the tmux-free ordinary suite (a fabricated %pane
|
|
304
277
|
// would be GC-pruned by liveOrPrune and the node would wrongly release).
|
|
305
278
|
openFocusRow('fMgr', null, 'Suser', 'mgr');
|
|
306
279
|
process.env['CRTR_NODE_ID'] = 'mgr';
|
|
307
280
|
const pi = makeFakePi();
|
|
308
281
|
registerCanvasStophook(pi);
|
|
309
282
|
let shutdown = false;
|
|
310
|
-
settle(pi, stopEvent('still waiting on the worker'), { shutdown: () => { shutdown = true; } });
|
|
283
|
+
await settle(pi, stopEvent('still waiting on the worker'), { shutdown: () => { shutdown = true; } });
|
|
311
284
|
// A FOCUSED awaiting node holds the user's viewport, so the awaiting branch
|
|
312
285
|
// keeps pi LIVE and dormant (the in-process inbox-watcher wakes it) instead of
|
|
313
286
|
// releasing + shutting down. It must NOT release, NOT shut down, and NOT touch
|
|
@@ -318,14 +291,14 @@ test('§5.1.5 awaiting + FOCUSED → STAY ALIVE: pi keeps running (no release),
|
|
|
318
291
|
assert.equal(shutdown, false, 'a focused awaiting node is NOT shut down — pi stays live');
|
|
319
292
|
assert.equal(getFocusByNode('mgr')?.focus_id, 'fMgr', 'the focus row is UNCHANGED — not closed, not handed off');
|
|
320
293
|
});
|
|
321
|
-
test('§5.1.7 resident attended (no live subs) → nothing happens; focus + status survive', () => {
|
|
294
|
+
test('§5.1.7 resident attended (no live subs) → nothing happens; focus + status survive', async () => {
|
|
322
295
|
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
323
296
|
openFocusRow('fR', '%r', 'Suser', 'root');
|
|
324
297
|
process.env['CRTR_NODE_ID'] = 'root';
|
|
325
298
|
const pi = makeFakePi();
|
|
326
299
|
registerCanvasStophook(pi);
|
|
327
300
|
let shutdown = false;
|
|
328
|
-
settle(pi, stopEvent('I have wrapped up'), { shutdown: () => { shutdown = true; } });
|
|
301
|
+
await settle(pi, stopEvent('I have wrapped up'), { shutdown: () => { shutdown = true; } });
|
|
329
302
|
// evaluateStop on a resident → reason 'dormant' (NOT 'awaiting'), so the
|
|
330
303
|
// awaiting branch is skipped and the handler does nothing: no release, no
|
|
331
304
|
// shutdown, no focus touch. Non-vacuous: an impl that idle-released a resident
|
|
@@ -336,7 +309,7 @@ test('§5.1.7 resident attended (no live subs) → nothing happens; focus + stat
|
|
|
336
309
|
assert.equal(getFocusByNode('root')?.focus_id, 'fR', 'focus row survives untouched');
|
|
337
310
|
assert.equal(shutdown, false, 'a resident attended node is not shut down');
|
|
338
311
|
});
|
|
339
|
-
test('refresh-yield (intent=refresh) writes NO push — silent to subscribers', () => {
|
|
312
|
+
test('refresh-yield (intent=refresh) writes NO push — silent to subscribers', async () => {
|
|
340
313
|
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
341
314
|
createNode(node('orch', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator', intent: 'refresh' }));
|
|
342
315
|
subscribe('root', 'orch', true);
|
|
@@ -344,7 +317,7 @@ test('refresh-yield (intent=refresh) writes NO push — silent to subscribers',
|
|
|
344
317
|
const pi = makeFakePi();
|
|
345
318
|
registerCanvasStophook(pi);
|
|
346
319
|
let shutdown = false;
|
|
347
|
-
settle(pi, stopEvent('checkpoint before refreshing'), { shutdown: () => { shutdown = true; } });
|
|
320
|
+
await settle(pi, stopEvent('checkpoint before refreshing'), { shutdown: () => { shutdown = true; } });
|
|
348
321
|
assert.equal(shutdown, true, 'pi shut down (no tmux pane → clean shutdown)');
|
|
349
322
|
assert.equal(reportCount('orch'), 0, 'a yield is silent: NO report file');
|
|
350
323
|
assert.equal(readInboxSince('root').length, 0, 'a yield is silent: NO inbox pointer');
|
|
@@ -390,19 +363,19 @@ test('turn_end still clears a daemon→node wedge fault (existing behavior, unch
|
|
|
390
363
|
pi.fire('turn_end', turnEndEvent('turn completed'), {});
|
|
391
364
|
assert.equal(readFault('leaf'), null, 'the daemon→node wedge fault is still cleared at turn_end');
|
|
392
365
|
});
|
|
393
|
-
test('a successful final or human ask suppresses the stop reprompt without a canvas read', () => {
|
|
366
|
+
test('a successful final or human ask suppresses the stop reprompt without a canvas read', async () => {
|
|
394
367
|
for (const [signal, shutsDown] of [['pushedFinal', true], ['askedHuman', false]]) {
|
|
395
368
|
process.env['CRTR_NODE_ID'] = 'signal-only';
|
|
396
369
|
markStopSignal('signal-only', signal);
|
|
397
370
|
const pi = makeFakePi();
|
|
398
371
|
registerCanvasStophook(pi);
|
|
399
372
|
let shutdown = false;
|
|
400
|
-
settle(pi, stopEvent(`completed ${signal}`), { shutdown: () => { shutdown = true; } });
|
|
373
|
+
await settle(pi, stopEvent(`completed ${signal}`), { shutdown: () => { shutdown = true; } });
|
|
401
374
|
assert.equal(pi.injected.length, 0, `${signal} does not re-prompt when the broker cannot read its node`);
|
|
402
375
|
assert.equal(shutdown, shutsDown, `${signal} takes its expected settled action`);
|
|
403
376
|
}
|
|
404
377
|
});
|
|
405
|
-
test('an in-run retry (agent_start with no new input) does not erase this run\'s stop signal', () => {
|
|
378
|
+
test('an in-run retry (agent_start with no new input) does not erase this run\'s stop signal', async () => {
|
|
406
379
|
// Regression: pi re-fires agent_start for automatic retries and post-compaction
|
|
407
380
|
// continuations WITHIN one run. Clearing the marker there erased the ask/final
|
|
408
381
|
// recorded earlier in the same run, so settlement fell back to a canvas read
|
|
@@ -418,15 +391,15 @@ test('an in-run retry (agent_start with no new input) does not erase this run\'s
|
|
|
418
391
|
pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
419
392
|
markStopSignal('leaf', 'askedHuman'); // the node ran `crtr human ask` mid-run
|
|
420
393
|
pi.fire('agent_start', { type: 'agent_start' }, ctx); // pi auto-retried after a provider error
|
|
421
|
-
settle(pi, stopEvent('waiting on the human now'), ctx);
|
|
394
|
+
await settle(pi, stopEvent('waiting on the human now'), ctx);
|
|
422
395
|
assert.equal(pi.injected.length, 0, 'the ask survives the in-run retry — no stall reprompt');
|
|
423
396
|
// ...and the NEXT user-directed run does start clean.
|
|
424
397
|
markStopSignal('leaf', 'askedHuman');
|
|
425
398
|
pi.fire('input', { type: 'input' }, ctx);
|
|
426
|
-
settle(pi, stopEvent('I think I am basically done here'), ctx);
|
|
399
|
+
await settle(pi, stopEvent('I think I am basically done here'), ctx);
|
|
427
400
|
assert.equal(pi.injected.length, 1, 'a new input discards a leftover marker from a prior run');
|
|
428
401
|
});
|
|
429
|
-
test('stalled leaf (nothing live to await, no final) is still reprompted', () => {
|
|
402
|
+
test('stalled leaf (nothing live to await, no final) is still reprompted', async () => {
|
|
430
403
|
createNode(node('mgr', { parent: null, lifecycle: 'terminal', mode: 'orchestrator' }));
|
|
431
404
|
createNode(node('leaf', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
|
|
432
405
|
subscribe('mgr', 'leaf', true); // mgr subscribes to leaf; leaf itself awaits nothing
|
|
@@ -434,7 +407,7 @@ test('stalled leaf (nothing live to await, no final) is still reprompted', () =>
|
|
|
434
407
|
const pi = makeFakePi();
|
|
435
408
|
registerCanvasStophook(pi);
|
|
436
409
|
let shutdown = false;
|
|
437
|
-
settle(pi, stopEvent('I think I am basically done here'), { shutdown: () => { shutdown = true; } });
|
|
410
|
+
await settle(pi, stopEvent('I think I am basically done here'), { shutdown: () => { shutdown = true; } });
|
|
438
411
|
assert.equal(pi.injected.length, 1, 'the stall reprompt fired');
|
|
439
412
|
assert.equal(pi.injected[0].content, STALL_REPROMPT, 'reprompt carries the stall nudge to push final / ask');
|
|
440
413
|
assert.equal(pi.injected[0].deliverAs, 'followUp', 'reprompt delivered as a followUp');
|