@north-light/crouter 0.3.173 → 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} +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/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,115 +0,0 @@
|
|
|
1
|
-
// spawnChild({ prompt: '' }) — the no-kickoff path `node new --root --no-kickoff`
|
|
2
|
-
// rides. An empty prompt reaches buildPiArgv as `undefined`-equivalent, so the
|
|
3
|
-
// broker comes up idle and goal-less. Fork identity is carried by the canonical
|
|
4
|
-
// session-start bearings message rather than by either kickoff shape.
|
|
5
|
-
import { test, before, after, beforeEach } from 'node:test';
|
|
6
|
-
import assert from 'node:assert/strict';
|
|
7
|
-
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
8
|
-
import { tmpdir } from 'node:os';
|
|
9
|
-
import { join } from 'node:path';
|
|
10
|
-
import { createServer } from 'node:net';
|
|
11
|
-
import { getNode } from '../canvas/canvas.js';
|
|
12
|
-
import { closeDb } from '../canvas/db.js';
|
|
13
|
-
import { nodeDir } from '../canvas/paths.js';
|
|
14
|
-
import { readGoal } from '../runtime/kickoff.js';
|
|
15
|
-
import { spawnChild } from '../runtime/spawn.js';
|
|
16
|
-
import { headlessBrokerHost } from '../runtime/host.js';
|
|
17
|
-
let home;
|
|
18
|
-
before(() => {
|
|
19
|
-
// Unix-domain socket paths are capped at ~104 bytes on macOS; keep the canvas
|
|
20
|
-
// home short (mirrors spawn-root.test.ts) since readiness now opens a real
|
|
21
|
-
// view.sock under it.
|
|
22
|
-
home = mkdtempSync('/tmp/crtr-no-kickoff-');
|
|
23
|
-
process.env['CRTR_HOME'] = home;
|
|
24
|
-
});
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
closeDb();
|
|
27
|
-
rmSync(home, { recursive: true, force: true });
|
|
28
|
-
});
|
|
29
|
-
after(() => {
|
|
30
|
-
closeDb();
|
|
31
|
-
rmSync(home, { recursive: true, force: true });
|
|
32
|
-
});
|
|
33
|
-
/** Mock the broker host to capture the argv/env it would have launched pi with,
|
|
34
|
-
* and hand back a real listening view.sock so `readiness: 'await'` resolves. */
|
|
35
|
-
function captureLaunch() {
|
|
36
|
-
const original = headlessBrokerHost.launch;
|
|
37
|
-
const invocations = [];
|
|
38
|
-
const servers = [];
|
|
39
|
-
headlessBrokerHost.launch = (nodeId, inv, _opts) => {
|
|
40
|
-
invocations.push(inv);
|
|
41
|
-
const server = createServer();
|
|
42
|
-
servers.push(server);
|
|
43
|
-
server.listen(join(nodeDir(nodeId), 'view.sock'));
|
|
44
|
-
return { pid: process.pid, exited: new Promise(() => { }) };
|
|
45
|
-
};
|
|
46
|
-
return {
|
|
47
|
-
invocations,
|
|
48
|
-
servers,
|
|
49
|
-
restore: () => {
|
|
50
|
-
headlessBrokerHost.launch = original;
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
test('no-kickoff root: no positional prompt reaches pi argv, and no goal is persisted', async () => {
|
|
55
|
-
// buildPiArgv's shape (extensions, -n label, --model, --tools,
|
|
56
|
-
// --append-system-prompt <per-node path>, ...) is identical between a
|
|
57
|
-
// no-kickoff and a real-kickoff spawn of the same kind/mode — the ONLY
|
|
58
|
-
// structural difference a real prompt adds is exactly one trailing argv
|
|
59
|
-
// token (the positional prompt itself). Comparing argv LENGTH between two
|
|
60
|
-
// otherwise-identical spawns proves that, without hardcoding flag order/
|
|
61
|
-
// count assumptions that would drift if buildPiArgv's flag set changes.
|
|
62
|
-
const cwdNoKickoff = mkdtempSync(join(tmpdir(), 'crtr-no-kickoff-cwd-'));
|
|
63
|
-
const cwdWithKickoff = mkdtempSync(join(tmpdir(), 'crtr-with-kickoff-cwd-'));
|
|
64
|
-
const cap = captureLaunch();
|
|
65
|
-
try {
|
|
66
|
-
const result = await spawnChild({ kind: 'general', cwd: cwdNoKickoff, root: true, readiness: 'await', prompt: '' });
|
|
67
|
-
await spawnChild({ kind: 'general', cwd: cwdWithKickoff, root: true, readiness: 'await', prompt: 'hello there' });
|
|
68
|
-
assert.equal(cap.invocations.length, 2, 'both broker launches happened');
|
|
69
|
-
const argvNoKickoff = cap.invocations[0].argv;
|
|
70
|
-
const argvWithKickoff = cap.invocations[1].argv;
|
|
71
|
-
assert.equal(argvNoKickoff.length + 1, argvWithKickoff.length, 'a real kickoff adds EXACTLY one extra argv token (the prompt) vs. no-kickoff');
|
|
72
|
-
assert.equal(argvWithKickoff[argvWithKickoff.length - 1], 'hello there', 'the real kickoff prompt rides as the trailing positional');
|
|
73
|
-
assert.notEqual(argvNoKickoff[argvNoKickoff.length - 1], 'hello there', 'the no-kickoff argv carries no trailing prompt token');
|
|
74
|
-
assert.equal(readGoal(result.node.node_id), null, 'no goal file was written for an empty (no-kickoff) prompt');
|
|
75
|
-
assert.equal(getNode(result.node.node_id)?.status, 'active', 'the node still comes up active/idle, ready for a real first prompt');
|
|
76
|
-
}
|
|
77
|
-
finally {
|
|
78
|
-
cap.restore();
|
|
79
|
-
await Promise.all(cap.servers.filter((s) => s.listening).map((s) => new Promise((resolve) => s.close(() => resolve()))));
|
|
80
|
-
rmSync(cwdNoKickoff, { recursive: true, force: true });
|
|
81
|
-
rmSync(cwdWithKickoff, { recursive: true, force: true });
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
test('fork-from keeps identity out of the task prompt with or without kickoff', async () => {
|
|
85
|
-
const cwdNoKickoff = mkdtempSync(join(tmpdir(), 'crtr-no-kickoff-fork-cwd-'));
|
|
86
|
-
const cwdWithKickoff = mkdtempSync(join(tmpdir(), 'crtr-kickoff-fork-cwd-'));
|
|
87
|
-
const seedPathNoKickoff = join(cwdNoKickoff, 'seed.jsonl');
|
|
88
|
-
const seedPathWithKickoff = join(cwdWithKickoff, 'seed.jsonl');
|
|
89
|
-
writeFileSync(seedPathNoKickoff, '{"type":"session"}\n');
|
|
90
|
-
writeFileSync(seedPathWithKickoff, '{"type":"session"}\n');
|
|
91
|
-
const cap = captureLaunch();
|
|
92
|
-
try {
|
|
93
|
-
await spawnChild({ kind: 'general', cwd: cwdNoKickoff, root: true, readiness: 'await', prompt: '', forkFrom: seedPathNoKickoff });
|
|
94
|
-
await spawnChild({ kind: 'general', cwd: cwdWithKickoff, root: true, readiness: 'await', prompt: 'continue please', forkFrom: seedPathWithKickoff });
|
|
95
|
-
assert.equal(cap.invocations.length, 2, 'both broker launches happened');
|
|
96
|
-
const argvNoKickoff = cap.invocations[0].argv;
|
|
97
|
-
const argvWithKickoff = cap.invocations[1].argv;
|
|
98
|
-
// Both still fork the seeded history through to pi verbatim.
|
|
99
|
-
assert.ok(argvNoKickoff.includes('--fork'), 'the no-kickoff fork source still rides through to pi');
|
|
100
|
-
assert.ok(argvNoKickoff.includes(seedPathNoKickoff), 'the resolved seed path is the no-kickoff fork source');
|
|
101
|
-
assert.ok(argvWithKickoff.includes('--fork'), 'the real-kickoff fork source still rides through to pi');
|
|
102
|
-
assert.ok(argvWithKickoff.includes(seedPathWithKickoff), 'the resolved seed path is the real-kickoff fork source');
|
|
103
|
-
// A real kickoff carries exactly the user's task. The session-start
|
|
104
|
-
// bearings message owns fork identity for both prompt shapes.
|
|
105
|
-
const trailingWithKickoff = argvWithKickoff[argvWithKickoff.length - 1];
|
|
106
|
-
assert.equal(trailingWithKickoff, 'continue please', 'the real fork kickoff is the unmodified user task');
|
|
107
|
-
assert.notEqual(argvNoKickoff[argvNoKickoff.length - 1], trailingWithKickoff, 'the no-kickoff fork carries no task prompt');
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
cap.restore();
|
|
111
|
-
await Promise.all(cap.servers.filter((s) => s.listening).map((s) => new Promise((resolve) => s.close(() => resolve()))));
|
|
112
|
-
rmSync(cwdNoKickoff, { recursive: true, force: true });
|
|
113
|
-
rmSync(cwdWithKickoff, { recursive: true, force: true });
|
|
114
|
-
}
|
|
115
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// Run: node --import tsx/esm --test src/core/__tests__/steer-note.test.ts
|
|
2
|
-
//
|
|
3
|
-
// Context-size steering text (canvas-stophook `steerNote`) is keyed on MODE
|
|
4
|
-
// first, then LIFECYCLE — NOT on lifecycle alone. The key regression this
|
|
5
|
-
// guards: a TERMINAL/ORCHESTRATOR must get roadmap-checkpoint-and-yield
|
|
6
|
-
// guidance (it has a roadmap), never the worker "push final" text.
|
|
7
|
-
import { test } from 'node:test';
|
|
8
|
-
import assert from 'node:assert/strict';
|
|
9
|
-
import { steerNote } from '../../pi-extensions/canvas-stophook.js';
|
|
10
|
-
test('an orchestrator (terminal) is steered to checkpoint roadmap + yield, never push final', () => {
|
|
11
|
-
const msg = steerNote(150_000, 'terminal', 'orchestrator');
|
|
12
|
-
assert.match(msg, /roadmap\.md/, 'points at the roadmap to checkpoint');
|
|
13
|
-
assert.match(msg, /node yield/, 'steers it to yield');
|
|
14
|
-
assert.doesNotMatch(msg, /push final/, 'an orchestrator never finishes with push final');
|
|
15
|
-
});
|
|
16
|
-
test('an orchestrator (resident) gets the same roadmap/yield steering as a terminal orchestrator', () => {
|
|
17
|
-
const t = steerNote(150_000, 'terminal', 'orchestrator');
|
|
18
|
-
const r = steerNote(150_000, 'resident', 'orchestrator');
|
|
19
|
-
assert.equal(r, t, 'mode drives the message, not lifecycle');
|
|
20
|
-
});
|
|
21
|
-
test('a terminal BASE worker is steered to yield-or-finish, never at a bare promote', () => {
|
|
22
|
-
const msg = steerNote(170_000, 'terminal', 'base');
|
|
23
|
-
assert.match(msg, /node yield/, 'a base worker is told to yield to continue (mode-preserving — no auto-promote)');
|
|
24
|
-
assert.match(msg, /push final/, 'and to finish with push final when close');
|
|
25
|
-
assert.doesNotMatch(msg, /node promote/, 'never the heavy "become an orchestrator" framing that bred yield-avoidance');
|
|
26
|
-
assert.doesNotMatch(msg, /roadmap\.md/, 'a base worker has no roadmap.md to checkpoint');
|
|
27
|
-
});
|
|
28
|
-
test('a resident BASE root is steered to yield-or-wrap-up, never at a bare promote or roadmap', () => {
|
|
29
|
-
const msg = steerNote(150_000, 'resident', 'base');
|
|
30
|
-
assert.match(msg, /node yield/, 'a root growing into a job is told to yield (mode-preserving — no auto-promote)');
|
|
31
|
-
assert.doesNotMatch(msg, /node promote/, 'never the heavy "become an orchestrator" framing');
|
|
32
|
-
assert.doesNotMatch(msg, /roadmap\.md/, 'a root has no roadmap.md to point at');
|
|
33
|
-
assert.doesNotMatch(msg, /push final/, 'a resident node never finishes with push final');
|
|
34
|
-
});
|
|
35
|
-
test('below the first band there is no nudge boundary issue — pushy escalation kicks in at 185k', () => {
|
|
36
|
-
// Sanity: the orchestrator branch escalates (pushy) at/after 185k.
|
|
37
|
-
const firm = steerNote(150_000, 'terminal', 'orchestrator');
|
|
38
|
-
const pushy = steerNote(185_000, 'terminal', 'orchestrator');
|
|
39
|
-
assert.notEqual(firm, pushy, 'the 185k band reads differently from the 150k band');
|
|
40
|
-
assert.match(pushy, /overflow/i, 'the pushy band warns about overflow');
|
|
41
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// Tests for the subcommand visibility tier (hidden | normal | common | important)
|
|
2
|
-
// and the parent-level listing affordance.
|
|
3
|
-
// Run with: node --import tsx/esm --test src/core/__tests__/subcommand-tier.test.ts
|
|
4
|
-
//
|
|
5
|
-
// Contract:
|
|
6
|
-
// - Each child def (defineLeaf/defineBranch) owns its own description /
|
|
7
|
-
// whenToUse / tier; defineBranch assembles `help.listing` from those defs —
|
|
8
|
-
// the parent never copies a child's self-description (principle 16).
|
|
9
|
-
// - renderRoot promotes a subtree's `important` children (name + shortform
|
|
10
|
-
// desc) and `common` children (bare qualified path) into that command's
|
|
11
|
-
// block, then names how many other non-hidden subcommands stay behind
|
|
12
|
-
// `crtr <name> -h`.
|
|
13
|
-
// - `hidden` children never appear (not even in the subtree's own -h) and are
|
|
14
|
-
// not counted in any "[+N]" remainder.
|
|
15
|
-
// - renderBranch renders one self-closing <subcommand> per non-hidden child
|
|
16
|
-
// and adds a `subcommands="N"` attribute when a branch child owns children.
|
|
17
|
-
import { test, describe } from 'node:test';
|
|
18
|
-
import assert from 'node:assert/strict';
|
|
19
|
-
import { defineRoot, defineBranch, defineLeaf } from '../command.js';
|
|
20
|
-
import { renderRoot, renderBranch } from '../help.js';
|
|
21
|
-
const leaf = (name, opts = {}) => defineLeaf({
|
|
22
|
-
name,
|
|
23
|
-
description: opts.description,
|
|
24
|
-
whenToUse: opts.whenToUse,
|
|
25
|
-
tier: opts.tier,
|
|
26
|
-
help: { name, summary: name, output: [], outputKind: 'object', effects: ['None. Read-only.'] },
|
|
27
|
-
run: async () => ({}),
|
|
28
|
-
});
|
|
29
|
-
// A nested branch so we can assert the `subcommands="N"` depth flag. Its own
|
|
30
|
-
// parent-level self-description (description/whenToUse) lives on the def, as a
|
|
31
|
-
// sibling of `name`.
|
|
32
|
-
const inspect = defineBranch({
|
|
33
|
-
name: 'inspect',
|
|
34
|
-
description: 'inspect things',
|
|
35
|
-
whenToUse: 'x',
|
|
36
|
-
help: { name: 'thing inspect', summary: 'inspect' },
|
|
37
|
-
children: [
|
|
38
|
-
leaf('list', { description: 'list', whenToUse: 'x' }),
|
|
39
|
-
leaf('show', { description: 'show', whenToUse: 'x' }),
|
|
40
|
-
],
|
|
41
|
-
});
|
|
42
|
-
const thing = defineBranch({
|
|
43
|
-
name: 'thing',
|
|
44
|
-
rootEntry: { concept: 'a thing', desc: 'things', useWhen: 'doing things' },
|
|
45
|
-
help: { name: 'thing', summary: 'do things' },
|
|
46
|
-
children: [
|
|
47
|
-
leaf('make', { description: 'make a thing', whenToUse: 'x', tier: 'important' }),
|
|
48
|
-
leaf('promote', { description: 'promote a thing', whenToUse: 'x', tier: 'common' }),
|
|
49
|
-
inspect,
|
|
50
|
-
leaf('secret', { description: 'secret op', whenToUse: 'x', tier: 'hidden' }),
|
|
51
|
-
leaf('plain', { description: 'plain op', whenToUse: 'x' }),
|
|
52
|
-
],
|
|
53
|
-
});
|
|
54
|
-
const root = defineRoot({ tagline: 'test runtime', globals: [], subtrees: [thing] });
|
|
55
|
-
describe('renderRoot: subcommand promotion', () => {
|
|
56
|
-
const out = renderRoot(root.help);
|
|
57
|
-
test('important child surfaces with its shortform desc', () => {
|
|
58
|
-
assert.match(out, /\n {2}thing make {2,}make a thing\n/);
|
|
59
|
-
});
|
|
60
|
-
test('common child surfaces as a bare qualified path (no desc)', () => {
|
|
61
|
-
assert.match(out, /\n {2}thing promote\n/);
|
|
62
|
-
assert.doesNotMatch(out, /thing promote {2,}promote a thing/);
|
|
63
|
-
});
|
|
64
|
-
test('hidden child is never promoted and not counted', () => {
|
|
65
|
-
assert.doesNotMatch(out, /secret/);
|
|
66
|
-
// 5 children, 1 hidden => 4 listable, 2 promoted => 2 remaining.
|
|
67
|
-
assert.match(out, /\[\+2 other subcommands — `crtr thing -h`\]/);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
describe('renderRoot: commands with no promotions', () => {
|
|
71
|
-
test('still advertise their subcommand count', () => {
|
|
72
|
-
const bare = defineBranch({
|
|
73
|
-
name: 'bare',
|
|
74
|
-
rootEntry: { concept: 'bare', desc: 'bare', useWhen: 'x' },
|
|
75
|
-
help: { name: 'bare', summary: 'bare' },
|
|
76
|
-
children: [leaf('one', { description: 'one', whenToUse: 'x' })],
|
|
77
|
-
});
|
|
78
|
-
const r = defineRoot({ tagline: 't', globals: [], subtrees: [bare] });
|
|
79
|
-
const out = renderRoot(r.help);
|
|
80
|
-
assert.match(out, /\[\+1 subcommand — `crtr bare -h`\]/); // singular, no "other"
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
describe('renderBranch: hidden filter + depth flag (XML)', () => {
|
|
84
|
-
const out = renderBranch(thing.help);
|
|
85
|
-
test('hidden child is dropped from the branch listing', () => {
|
|
86
|
-
assert.doesNotMatch(out, /secret/);
|
|
87
|
-
});
|
|
88
|
-
test('all non-hidden children are listed as <subcommand> rows', () => {
|
|
89
|
-
for (const n of ['make', 'promote', 'inspect', 'plain']) {
|
|
90
|
-
assert.match(out, new RegExp(`name="${n}"`));
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
test('a branch child flags how many subcommands it owns', () => {
|
|
94
|
-
assert.match(out, /name="inspect"[^>]*subcommands="2"/);
|
|
95
|
-
});
|
|
96
|
-
test('leaf children carry no subcommand flag', () => {
|
|
97
|
-
assert.doesNotMatch(out, /name="make"[^>]*subcommands=/);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
// Run with: node --import tsx/esm --test src/core/__tests__/subscription-delivery.test.ts
|
|
2
|
-
//
|
|
3
|
-
// MULTI-LEVEL SUBSCRIPTION DELIVERY — the DELIVERY-vs-WAKE distinction across a
|
|
4
|
-
// graph >=2 levels deep. The whole split is pure canvas/feed/daemon model logic,
|
|
5
|
-
// so this is driven by FABRICATING the topology + dormant states directly
|
|
6
|
-
// (foundation-spec §E.2) and exercising the real model layer (feed.push,
|
|
7
|
-
// evaluateStop, superviseTick) — NO real tmux session, NO pane chrome, and NO
|
|
8
|
-
// real broker boot (which would cost ~5s each). Every assertion reads the canvas
|
|
9
|
-
// data layer and is checked against the state-model ORACLE (§3b, §5, §6).
|
|
10
|
-
//
|
|
11
|
-
// HEADLESS / FABRICATED RETARGET (foundation-spec §C.15 + §E). All nodes are
|
|
12
|
-
// broker-hosted (paneless). Dormancy, which a tmux node shows as a closed pane,
|
|
13
|
-
// a broker shows as an EXITED process (status=idle, intent=idle-release, pi_pid
|
|
14
|
-
// dead) — fabricated directly. A daemon revive is observed via getNode().cycles
|
|
15
|
-
// (reviveNode bumps cycles + transition('revive') BEFORE it spawns — revive.ts:
|
|
16
|
-
// 114,145 — so the model effect is instant, no awaitBoot), never a real boot.
|
|
17
|
-
//
|
|
18
|
-
// (1) BUG LOCKED — the DELIVERY-vs-WAKE split (Invariant D + stop-guard): an
|
|
19
|
-
// ACTIVE subscriber's pointer lands in inbox.jsonl and the daemon's 2nd pass
|
|
20
|
-
// REVIVES it on that unseen entry; a PASSIVE subscriber's pointer lands in
|
|
21
|
-
// passive.jsonl and NEVER wakes; a PASSIVE-only tie does NOT legitimize an
|
|
22
|
-
// idle-release (hasActiveLiveSubscription filters active=1).
|
|
23
|
-
// (2) WHY MODEL-LEVEL, NOT TMUX CHROME — routing (feed.ts), the active/passive
|
|
24
|
-
// edge filter (canvas.ts), the 2nd-pass inbox gate (crtrd.ts), and one-hop
|
|
25
|
-
// fan-out are all pure data-layer; the only thing a pane ever provided was a
|
|
26
|
-
// visible "dormant" signal, which a broker expresses as a dead pid — and
|
|
27
|
-
// which fabrication sets directly.
|
|
28
|
-
// (3) HOW THE FABRICATED DRIVE STILL FAILS IF THE BUG REGRESSES — after T's
|
|
29
|
-
// pushFinal, one h.tick() must revive the ACTIVE subscriber B (cycles bumps,
|
|
30
|
-
// status→active) while the PASSIVE subscriber P stays idle with cycles==0. If
|
|
31
|
-
// inbox-vs-passive routing breaks, either B's entry never reaches its inbox
|
|
32
|
-
// (the 2nd-pass gate finds nothing → B not revived → cycles stays 0) or P
|
|
33
|
-
// gets an inbox entry and IS woken (its cycles/status asserts go RED).
|
|
34
|
-
// Verified by routing passive deliveries into the inbox (see bug-injection
|
|
35
|
-
// report).
|
|
36
|
-
//
|
|
37
|
-
// THE ORACLE CONTRACT under test:
|
|
38
|
-
// • feed.push fans to subscribersOf(target): active → inbox.jsonl (wakes),
|
|
39
|
-
// passive → passive.jsonl (accumulates, NEVER wakes). (state-model §5; feed.ts)
|
|
40
|
-
// • The daemon's 2nd pass revives an idle-released node ONLY on an unseen INBOX
|
|
41
|
-
// entry (crtrd.ts) — so a passive subscriber's idle-released node never wakes.
|
|
42
|
-
// • hasActiveLiveSubscription excludes passive edges (canvas.ts active=1) — a
|
|
43
|
-
// passive tie does NOT legitimize idle-release (stop-guard §3b).
|
|
44
|
-
// • Wake is ONE HOP per push: a push fans to DIRECT subscribers only; an indirect
|
|
45
|
-
// ancestor hears nothing until a middle node explicitly re-pushes. (state-model §5)
|
|
46
|
-
//
|
|
47
|
-
// Graph (>=2 levels; T is two hops under A):
|
|
48
|
-
// A (resident root — the user's virtual front door)
|
|
49
|
-
// └── B (terminal) A→B active seed ── ACTIVE subscriber of T
|
|
50
|
-
// ├── T (terminal) B→T active seed ── THE TARGET (level 2)
|
|
51
|
-
// ├── K (terminal) B→K active seed ── keepalive (stays active)
|
|
52
|
-
// └── P (terminal) B→P active seed ── PASSIVE subscriber of T
|
|
53
|
-
// P→T passive (wired via subscribe(P,T,false))
|
|
54
|
-
// P→K active (the ONLY tie that legitimizes P's release;
|
|
55
|
-
// P→T passive is excluded from the stop-guard)
|
|
56
|
-
import { test } from 'node:test';
|
|
57
|
-
import assert from 'node:assert/strict';
|
|
58
|
-
import { spawnSync } from 'node:child_process';
|
|
59
|
-
import { createHarness } from './helpers/harness.js';
|
|
60
|
-
import { closeDb } from '../canvas/db.js';
|
|
61
|
-
import { subscribe } from '../canvas/canvas.js';
|
|
62
|
-
import { pushFinal, pushUpdate } from '../feed/feed.js';
|
|
63
|
-
import { readPassive } from '../feed/passive.js';
|
|
64
|
-
import { evaluateStop, STALL_REPROMPT } from '../runtime/stop-guard.js';
|
|
65
|
-
// A pid reaped (dead) by the time spawnSync returns — a released broker's exited
|
|
66
|
-
// process (the headless analog of a closed pane).
|
|
67
|
-
function deadPid() {
|
|
68
|
-
const r = spawnSync('true', [], { stdio: 'ignore' });
|
|
69
|
-
return r.pid ?? 0x7ffffffe;
|
|
70
|
-
}
|
|
71
|
-
// LOCAL helper: read a node's PASSIVE accumulator (passive.jsonl) straight off
|
|
72
|
-
// the data layer, mirroring the harness's own `inbox()` reader. The harness
|
|
73
|
-
// exposes inbox() but NOT passive() — this fills that gap.
|
|
74
|
-
function passive(nodeId) {
|
|
75
|
-
closeDb();
|
|
76
|
-
return readPassive(nodeId);
|
|
77
|
-
}
|
|
78
|
-
// `{node_id, active}` arrays → a stable comparable set of `id:active|passive`.
|
|
79
|
-
function edgeSet(arr) {
|
|
80
|
-
return new Set(arr.map((e) => `${e.node_id}:${e.active ? 'active' : 'passive'}`));
|
|
81
|
-
}
|
|
82
|
-
test('multi-level subscription delivery: active subscriber WOKEN vs passive subscriber DELIVERED-not-woken, on the same dormant target', { timeout: 30_000 }, async () => {
|
|
83
|
-
const h = await createHarness({ headless: true, sessionPrefix: 'crtr-subdeliv' });
|
|
84
|
-
try {
|
|
85
|
-
// ===================================================================
|
|
86
|
-
// S1 — Build the graph by FABRICATION (no boots). A is a resident root
|
|
87
|
-
// (inline, daemon-untouched); B/T/K/P/X are broker nodes whose
|
|
88
|
-
// liveness fields are set directly. Each parent→child spine edge is
|
|
89
|
-
// wired ACTIVE.
|
|
90
|
-
// ===================================================================
|
|
91
|
-
const A = h.spawnRoot('front door'); // resident root, active, no placement
|
|
92
|
-
// T (the target) and K (keepalive) are LIVE-active workers; B and P start
|
|
93
|
-
// already DORMANT (idle-released, broker exited = dead pid) — exactly the
|
|
94
|
-
// post-stop state the delivery split is judged against.
|
|
95
|
-
const T = h.fabricateBrokerNode({ status: 'active', pi_pid: deadPid(), pi_session_id: 'sess-T' });
|
|
96
|
-
const K = h.fabricateBrokerNode({ status: 'active', pi_pid: deadPid(), pi_session_id: 'sess-K' });
|
|
97
|
-
const B = h.fabricateBrokerNode({ status: 'idle', intent: 'idle-release', pi_pid: deadPid(), pi_session_id: 'sess-B' });
|
|
98
|
-
const P = h.fabricateBrokerNode({ status: 'idle', intent: 'idle-release', pi_pid: deadPid(), pi_session_id: 'sess-P' });
|
|
99
|
-
// Spine seeds: A→B, B→T, B→K, B→P all ACTIVE (subscriber, publisher).
|
|
100
|
-
subscribe(A, B, true);
|
|
101
|
-
subscribe(B, T, true);
|
|
102
|
-
subscribe(B, K, true);
|
|
103
|
-
subscribe(B, P, true);
|
|
104
|
-
// PASSIVE axis under test: P passively subscribes to T; P actively to K
|
|
105
|
-
// (the only tie that legitimizes P's own idle-release).
|
|
106
|
-
subscribe(P, T, false);
|
|
107
|
-
subscribe(P, K, true);
|
|
108
|
-
assert.deepEqual(edgeSet(h.subscribers(T)), new Set([`${B}:active`, `${P}:passive`]), 'T has B(active) + P(passive) as subscribers — the same-target split');
|
|
109
|
-
assert.deepEqual(edgeSet(h.subscribers(B)), new Set([`${A}:active`]), 'A→B active seed');
|
|
110
|
-
assert.deepEqual(edgeSet(h.subscriptions(P)), new Set([`${T}:passive`, `${K}:active`]), 'P subscribes_to T(passive) + K(active)');
|
|
111
|
-
// ===================================================================
|
|
112
|
-
// S2 — PASSIVE-EXCLUSION via the PURE stop-guard (the active/passive split
|
|
113
|
-
// half). evaluateStop is pure given the canvas; X holds a PASSIVE-only
|
|
114
|
-
// tie to the same live K that P holds ACTIVELY. hasActiveLiveSubscription
|
|
115
|
-
// filters active=1 (canvas.ts), so X's passive K-tie is invisible →
|
|
116
|
-
// 'stalled' (STALL_REPROMPT); P's active K-tie → 'awaiting'. Same
|
|
117
|
-
// publisher K, opposite outcome purely by edge mode (oracle §3b, §5).
|
|
118
|
-
// ===================================================================
|
|
119
|
-
const X = h.fabricateBrokerNode({ status: 'active' });
|
|
120
|
-
subscribe(X, K, false); // X→K PASSIVE-only — its ONLY subscription
|
|
121
|
-
assert.deepEqual(edgeSet(h.subscriptions(X)), new Set([`${K}:passive`]), 'X holds exactly one tie: K(passive) — no active live subscription');
|
|
122
|
-
{
|
|
123
|
-
const xStop = evaluateStop(X, { pushedFinal: false, askedHuman: false });
|
|
124
|
-
assert.equal(xStop.action, 'reprompt', 'X (passive-only) → reprompt, NOT awaiting');
|
|
125
|
-
assert.equal(xStop.reason, 'stalled', 'X classified stalled — passive tie does not hold it');
|
|
126
|
-
assert.equal(xStop.message, STALL_REPROMPT, 'X gets the stall re-prompt');
|
|
127
|
-
const pStop = evaluateStop(P, { pushedFinal: false, askedHuman: false });
|
|
128
|
-
assert.equal(pStop.action, 'allow', 'P (active K-tie) → allow');
|
|
129
|
-
assert.equal(pStop.reason, 'awaiting', 'P classified awaiting on its ACTIVE K-sub — the discriminating positive');
|
|
130
|
-
}
|
|
131
|
-
// Pre-push baseline: keepalive up, grandparent untouched, nothing delivered.
|
|
132
|
-
assert.equal(h.status(K), 'active', 'K active (keepalive holds P legitimately dormant)');
|
|
133
|
-
assert.equal(h.status(A), 'active', 'A (resident root) untouched');
|
|
134
|
-
assert.equal(h.inbox(A).length, 0, 'A inbox empty before the push');
|
|
135
|
-
assert.equal(h.inbox(B).length, 0, 'B inbox empty before the push');
|
|
136
|
-
assert.equal(passive(P).length, 0, 'P passive accumulator empty before the push');
|
|
137
|
-
assert.equal(h.node(B).cycles ?? 0, 0, 'B not yet revived');
|
|
138
|
-
assert.equal(h.node(P).cycles ?? 0, 0, 'P not yet revived');
|
|
139
|
-
// ===================================================================
|
|
140
|
-
// S3 — T FINISHES via the model layer (pushFinal). feed.push fans the
|
|
141
|
-
// pointer to subscribersOf(T) = {B(active), P(passive)} ONLY, by the
|
|
142
|
-
// delivery split: B's lands in inbox.jsonl, P's in passive.jsonl. A
|
|
143
|
-
// (the grandparent, NOT a subscriber of T) gets NOTHING — one-hop.
|
|
144
|
-
// ===================================================================
|
|
145
|
-
const TARGET_FINAL = 'TARGET-FINAL-BODY: the worker completed';
|
|
146
|
-
await pushFinal(T, TARGET_FINAL);
|
|
147
|
-
closeDb();
|
|
148
|
-
{
|
|
149
|
-
assert.equal(h.status(T), 'done', 'T done after pushFinal (transition finalize)');
|
|
150
|
-
assert.equal(h.node(T).intent, 'done', 'T intent=done');
|
|
151
|
-
// ACTIVE delivery → B's INBOX (the wake channel).
|
|
152
|
-
const bFinal = h.inbox(B).find((e) => e.from === T && e.kind === 'final');
|
|
153
|
-
assert.ok(bFinal, 'ACTIVE subscriber B: T-final pointer DELIVERED to inbox.jsonl');
|
|
154
|
-
// PASSIVE delivery → P's ACCUMULATOR, NOT its inbox (no wake channel).
|
|
155
|
-
const pPassive = passive(P);
|
|
156
|
-
assert.equal(pPassive.length, 1, 'PASSIVE subscriber P: exactly one passive entry');
|
|
157
|
-
assert.equal(pPassive[0].from, T, "P's passive entry is from T");
|
|
158
|
-
assert.equal(pPassive[0].kind, 'final', "P's passive entry is the final");
|
|
159
|
-
assert.equal(h.inbox(P).length, 0, 'PASSIVE subscriber P: inbox.jsonl stays EMPTY (no wake channel)');
|
|
160
|
-
// ONE-HOP: the indirect ancestor and the non-subscriber sibling hear nothing.
|
|
161
|
-
assert.equal(h.inbox(A).length, 0, 'A (grandparent, not a subscriber of T) NOT delivered — one-hop');
|
|
162
|
-
assert.equal(h.inbox(K).length, 0, 'K (sibling, not a subscriber of T) NOT delivered');
|
|
163
|
-
}
|
|
164
|
-
// ===================================================================
|
|
165
|
-
// S4 — The DAEMON decision pass. Its 2nd pass revives an idle-released node
|
|
166
|
-
// ONLY on an unseen INBOX entry. B has one (active) → REVIVED. P has
|
|
167
|
-
// none (its entry went to passive.jsonl) → stays idle. The WAKE half
|
|
168
|
-
// of delivery-vs-wake, decided in ONE tick — observed via cycles.
|
|
169
|
-
// ===================================================================
|
|
170
|
-
await h.tick();
|
|
171
|
-
// ACTIVE subscriber: WOKEN — reviveNode bumped cycles + transition(revive).
|
|
172
|
-
{
|
|
173
|
-
const b = h.node(B);
|
|
174
|
-
assert.equal(b.cycles ?? 0, 1, 'ACTIVE subscriber B: daemon pass-2 REVIVED (cycles bumped to 1)');
|
|
175
|
-
assert.equal(b.status, 'active', 'B revive → active');
|
|
176
|
-
assert.equal(b.intent ?? null, null, 'B intent cleared by revive');
|
|
177
|
-
}
|
|
178
|
-
// PASSIVE subscriber: NOT WOKEN — the same tick did NOT revive P.
|
|
179
|
-
{
|
|
180
|
-
const p = h.node(P);
|
|
181
|
-
assert.equal(p.cycles ?? 0, 0, 'PASSIVE subscriber P: NOT revived (cycles still 0)');
|
|
182
|
-
assert.equal(p.status, 'idle', 'P STILL idle — daemon did NOT wake it');
|
|
183
|
-
assert.equal(p.intent, 'idle-release', 'P still intent=idle-release (untouched)');
|
|
184
|
-
}
|
|
185
|
-
assert.equal(passive(P).length, 1, "P's passive entry is still pending (drained only on its next message)");
|
|
186
|
-
assert.equal(h.inbox(P).length, 0, "P's inbox still empty");
|
|
187
|
-
// The grandparent is STILL untouched even though B woke — one-hop confirmed.
|
|
188
|
-
assert.equal(h.inbox(A).length, 0, 'A inbox STILL empty after B woke — wake did not propagate up');
|
|
189
|
-
assert.equal(h.status(A), 'active', 'A unchanged');
|
|
190
|
-
// ===================================================================
|
|
191
|
-
// S5 — SECOND SITE: one-hop fan-out on a re-push. The indirect ancestor A
|
|
192
|
-
// hears B ONLY when B explicitly re-pushes up its own spine. B (now
|
|
193
|
-
// active) pushes an UPDATE → it fans to subscribersOf(B) = {A} only.
|
|
194
|
-
// ===================================================================
|
|
195
|
-
await pushUpdate(B, 'B re-pushing the rolled-up result');
|
|
196
|
-
closeDb();
|
|
197
|
-
{
|
|
198
|
-
const aInbox = h.inbox(A);
|
|
199
|
-
assert.equal(aInbox.length, 1, "A inbox now has exactly B's update (one hop, on B's explicit re-push)");
|
|
200
|
-
assert.equal(aInbox[0].from, B, "A's entry is from B");
|
|
201
|
-
assert.equal(aInbox[0].kind, 'update', "A's entry is the update");
|
|
202
|
-
}
|
|
203
|
-
// The re-push reached its DIRECT subscriber A only — siblings/observer untouched.
|
|
204
|
-
assert.equal(h.inbox(P).length, 0, "P inbox untouched by B's re-push (P does not subscribe to B)");
|
|
205
|
-
assert.equal(h.inbox(K).length, 0, "K inbox untouched by B's re-push");
|
|
206
|
-
assert.equal(passive(P).length, 1, "P's passive backlog unchanged by B's re-push");
|
|
207
|
-
}
|
|
208
|
-
finally {
|
|
209
|
-
await h.dispose();
|
|
210
|
-
}
|
|
211
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { readFile, rm } from 'node:fs/promises';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import test from 'node:test';
|
|
6
|
-
// Regression coverage for the PR #386 cheap-lane correction: the default (no
|
|
7
|
-
// file argument) `cheap` selection can no longer fit its aggregate ordinary
|
|
8
|
-
// duration inside one 90s Actions wall (see notes/pr386 diagnosis), so it
|
|
9
|
-
// splits into ORDINARY_SHARDS deterministic, path-hash-stable shards. These
|
|
10
|
-
// tests prove the split is duration-blind, disjoint, and complete; that each
|
|
11
|
-
// shard's timeout is capped correctly; that default cheap sharding activates
|
|
12
|
-
// only for the true default selection; that the forbidden cross-invocation
|
|
13
|
-
// flags are rejected while it is active; and that a targeted single-file
|
|
14
|
-
// cheap selection still runs as one unsharded invocation.
|
|
15
|
-
import { cheapShardTimeoutMs, findTestFiles, hasForbiddenCrossInvocationFlag, isDefaultCheapSelection, laneOf, ORDINARY_SHARDS, pathShard, runTier, } from '../../../scripts/test-runner.mjs';
|
|
16
|
-
test('the default ordinary partition is duration-blind, disjoint, and complete', async () => {
|
|
17
|
-
const ordinaryFiles = (await findTestFiles()).filter((file) => laneOf(file) === 'ordinary');
|
|
18
|
-
assert.ok(ordinaryFiles.length > 0, 'expected at least one ordinary-lane file to partition');
|
|
19
|
-
const shards = Array.from({ length: ORDINARY_SHARDS }, (_, shardIndex) => ordinaryFiles.filter((file) => pathShard(file, ORDINARY_SHARDS) === shardIndex));
|
|
20
|
-
// Complete: every ordinary file lands in exactly one shard.
|
|
21
|
-
const union = new Set(shards.flat());
|
|
22
|
-
assert.equal(union.size, ordinaryFiles.length, 'every ordinary file must appear in the union of shards');
|
|
23
|
-
// Disjoint: no file appears in more than one shard.
|
|
24
|
-
for (const file of ordinaryFiles) {
|
|
25
|
-
const memberships = shards.filter((shard) => shard.includes(file)).length;
|
|
26
|
-
assert.equal(memberships, 1, `${file} must belong to exactly one shard, got ${memberships}`);
|
|
27
|
-
}
|
|
28
|
-
// Stable: membership depends only on the path string, never on measured
|
|
29
|
-
// duration or file order. Pin fixed path→shard vectors rather than
|
|
30
|
-
// comparing a call against an immediately repeated call to itself, which
|
|
31
|
-
// cannot catch an unstable algorithm or membership drift.
|
|
32
|
-
assert.equal(pathShard('src/core/__tests__/test-runner-cheap-sharding.test.ts', ORDINARY_SHARDS), 1);
|
|
33
|
-
assert.equal(pathShard('src/core/keybindings/__tests__/bespoke-consumers.test.ts', ORDINARY_SHARDS), 0);
|
|
34
|
-
assert.equal(pathShard('src/core/__tests__/fixtures/spawn-proof-target.test.ts', ORDINARY_SHARDS), 0);
|
|
35
|
-
});
|
|
36
|
-
test('cheapShardTimeoutMs caps a shard at the 90s tier wall and never past the remaining full-suite budget', () => {
|
|
37
|
-
const now = Date.now();
|
|
38
|
-
// No full-suite deadline (a bare `test:cheap`): every shard gets the full 90s.
|
|
39
|
-
assert.equal(cheapShardTimeoutMs(Infinity, now), 90_000);
|
|
40
|
-
// Full-suite budget has plenty of room left: still capped at 90s.
|
|
41
|
-
assert.equal(cheapShardTimeoutMs(now + 600_000, now), 90_000);
|
|
42
|
-
// Full-suite budget is tighter than 90s: the shard is capped to what remains.
|
|
43
|
-
assert.equal(cheapShardTimeoutMs(now + 50_000, now), 50_000);
|
|
44
|
-
// Full-suite budget is already exhausted: the shard gets a non-positive
|
|
45
|
-
// timeout so the caller can fail fast instead of starting a doomed shard.
|
|
46
|
-
assert.ok(cheapShardTimeoutMs(now - 1, now) <= 0);
|
|
47
|
-
});
|
|
48
|
-
test('default cheap sharding activates only for the true default (no file argument) cheap selection', () => {
|
|
49
|
-
assert.equal(isDefaultCheapSelection('cheap', false), true);
|
|
50
|
-
assert.equal(isDefaultCheapSelection('cheap', true), false);
|
|
51
|
-
assert.equal(isDefaultCheapSelection('fast', false), false);
|
|
52
|
-
assert.equal(isDefaultCheapSelection('process', false), false);
|
|
53
|
-
assert.equal(isDefaultCheapSelection('live', false), false);
|
|
54
|
-
assert.equal(isDefaultCheapSelection('heavy', false), false);
|
|
55
|
-
});
|
|
56
|
-
test('hasForbiddenCrossInvocationFlag recognizes --test-shard and --test-global-setup in both bare and = forms', () => {
|
|
57
|
-
assert.equal(hasForbiddenCrossInvocationFlag(['--test-shard', '1/2']), true);
|
|
58
|
-
assert.equal(hasForbiddenCrossInvocationFlag(['--test-shard=1/2']), true);
|
|
59
|
-
assert.equal(hasForbiddenCrossInvocationFlag(['--test-global-setup=./setup.mjs']), true);
|
|
60
|
-
assert.equal(hasForbiddenCrossInvocationFlag(['--test-global-setup', './setup.mjs']), true);
|
|
61
|
-
assert.equal(hasForbiddenCrossInvocationFlag(['--test-name-pattern=foo']), false);
|
|
62
|
-
assert.equal(hasForbiddenCrossInvocationFlag([]), false);
|
|
63
|
-
});
|
|
64
|
-
test('runTier rejects --test-shard and --test-global-setup while default cheap partitioning is active', async () => {
|
|
65
|
-
await assert.rejects(() => runTier('cheap', ['--test-shard=1/2']), /default cheap selection.*path-hash-stable shards/);
|
|
66
|
-
await assert.rejects(() => runTier('cheap', ['--test-global-setup=./setup.mjs']), /default cheap selection.*path-hash-stable shards/);
|
|
67
|
-
await assert.rejects(() => runTier('cheap', ['--test-global-setup', './setup.mjs']), /default cheap selection.*path-hash-stable shards/);
|
|
68
|
-
});
|
|
69
|
-
test('a targeted single-file cheap selection stays a single unsharded invocation and its target really executes', async () => {
|
|
70
|
-
// This is a real explicit-file cheap invocation (the same path a caller
|
|
71
|
-
// takes with `npm run test:full:cheap -- <file>`), proving the targeted
|
|
72
|
-
// path still runs the file directly rather than through the shard loop.
|
|
73
|
-
// The target is a dedicated fixture (fixtures/spawn-proof-target.test.ts)
|
|
74
|
-
// that writes an observable marker file when asked, so this regression can
|
|
75
|
-
// tell "the spawned file's own test body actually ran" apart from "the
|
|
76
|
-
// child process merely exited 0" — the two were indistinguishable under
|
|
77
|
-
// the bug this guards: `run()`'s spawn inherited NODE_TEST_CONTEXT /
|
|
78
|
-
// NODE_TEST_WORKER_ID from this already-running node:test process, which
|
|
79
|
-
// made the spawned child's own recursion guard silently skip the target
|
|
80
|
-
// file while the process still exited 0. Asserting only `code === 0` (as
|
|
81
|
-
// this test previously did) would also pass with that fix reverted.
|
|
82
|
-
const proofFile = join(tmpdir(), `crtr-test-runner-spawn-proof-${process.pid}-${Date.now()}.txt`);
|
|
83
|
-
const priorProofEnv = process.env.CRTR_SPAWN_PROOF_FILE;
|
|
84
|
-
process.env.CRTR_SPAWN_PROOF_FILE = proofFile;
|
|
85
|
-
try {
|
|
86
|
-
const code = await runTier('cheap', ['src/core/__tests__/fixtures/spawn-proof-target.test.ts']);
|
|
87
|
-
assert.equal(code, 0);
|
|
88
|
-
assert.equal(await readFile(proofFile, 'utf8'), 'ran', 'spawned target must actually execute and write its proof marker');
|
|
89
|
-
}
|
|
90
|
-
finally {
|
|
91
|
-
if (priorProofEnv === undefined)
|
|
92
|
-
delete process.env.CRTR_SPAWN_PROOF_FILE;
|
|
93
|
-
else
|
|
94
|
-
process.env.CRTR_SPAWN_PROOF_FILE = priorProofEnv;
|
|
95
|
-
await rm(proofFile, { force: true });
|
|
96
|
-
}
|
|
97
|
-
});
|