@north-light/crouter 0.3.173 → 0.3.175
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/runtime-selector.mjs +8 -1
- package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
- package/dist/api/client.d.ts +12 -21
- package/dist/api/client.js +22 -31
- package/dist/api/dto/broker-ops.d.ts +158 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/crons.d.ts +6 -0
- package/dist/api/dto/human.d.ts +7 -1
- package/dist/api/dto/inbox.d.ts +1 -71
- package/dist/api/dto/inbox.js +1 -9
- package/dist/api/dto/nodes.d.ts +6 -7
- package/dist/api/dto/reviews.d.ts +1 -11
- package/dist/api/routes.d.ts +7 -4
- package/dist/api/routes.js +8 -5
- package/dist/build-root.js +3 -3
- package/dist/builtin-memory/04-base-worker.md +1 -4
- package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
- package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
- package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
- package/dist/builtin-memory/advisor/council.md +1 -6
- package/dist/builtin-memory/design.md +2 -7
- package/dist/builtin-memory/development.md +9 -14
- package/dist/builtin-memory/internal/marketplaces.md +2 -6
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +2 -8
- package/dist/builtin-memory/internal/storage-tiers.md +1 -2
- package/dist/builtin-memory/testing.md +41 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +27 -179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +7 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +9 -1
- package/dist/cli.js +2 -2
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
- package/dist/clients/attach/__tests__/context-message.test.js +16 -174
- package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
- package/dist/clients/attach/__tests__/diagram.test.js +2 -2
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
- package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
- package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
- package/dist/clients/attach/command.d.ts +2 -1
- package/dist/clients/attach/command.js +81 -76
- package/dist/clients/attach/input/capabilities.d.ts +27 -0
- package/dist/clients/attach/input/capabilities.js +96 -0
- package/dist/clients/attach/input/controller.d.ts +20 -182
- package/dist/clients/attach/input/controller.js +128 -537
- package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
- package/dist/clients/attach/input/overlay-owner.js +199 -0
- package/dist/clients/attach/overlays/file-review.d.ts +0 -4
- package/dist/clients/attach/overlays/file-review.js +13 -5
- package/dist/clients/attach/overlays/graph.js +2 -10
- package/dist/clients/attach/render/chat-view.d.ts +4 -3
- package/dist/clients/attach/render/chat-view.js +39 -33
- package/dist/clients/attach/render/group-activity.d.ts +1 -0
- package/dist/clients/attach/render/group-activity.js +20 -13
- package/dist/clients/attach/render/group-recap.js +12 -3
- package/dist/clients/attach/session/connection.js +9 -15
- package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
- package/dist/clients/attach/session/editor-inventory.js +7 -8
- package/dist/clients/attach/session/file-links.d.ts +13 -0
- package/dist/clients/attach/session/file-links.js +107 -0
- package/dist/clients/attach/session/frame.d.ts +3 -0
- package/dist/clients/attach/session/frame.js +10 -1
- package/dist/clients/attach/session/frames.js +2 -3
- package/dist/clients/attach/session/input-wiring.d.ts +4 -1
- package/dist/clients/attach/session/input-wiring.js +15 -14
- package/dist/clients/attach/session/mouse.d.ts +6 -1
- package/dist/clients/attach/session/mouse.js +8 -5
- package/dist/clients/attach/session/profile-files.js +18 -12
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/session/state-sync.js +1 -2
- package/dist/clients/attach/session/surface-host.d.ts +3 -2
- package/dist/clients/attach/session/surface-host.js +4 -4
- package/dist/clients/attach/slash/dispatch.d.ts +8 -31
- package/dist/clients/attach/slash/dispatch.js +34 -81
- package/dist/clients/attach/viewer.js +820 -860
- package/dist/clients/conversation/projection.d.ts +79 -0
- package/dist/clients/conversation/projection.js +341 -0
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
- package/dist/clients/inbox/controller.d.ts +0 -4
- package/dist/clients/inbox/controller.js +0 -2
- package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
- package/dist/clients/inbox/review/comments-client.d.ts +3 -2
- package/dist/clients/inbox/review/comments-client.js +12 -12
- package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
- package/dist/clients/inbox/review/companion-pane.js +86 -0
- package/dist/clients/inbox/review/document-surface.d.ts +182 -0
- package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
- package/dist/clients/inbox/review/frame.js +5 -4
- package/dist/clients/inbox/review/launch.d.ts +8 -8
- package/dist/clients/inbox/review/launch.js +52 -92
- package/dist/clients/inbox/review/nvim.d.ts +2 -0
- package/dist/clients/inbox/review/nvim.js +14 -12
- package/dist/clients/inbox/review/review-client.d.ts +12 -8
- package/dist/clients/inbox/review/review-client.js +46 -35
- package/dist/clients/inbox/review-adapter.d.ts +3 -10
- package/dist/clients/inbox/review-adapter.js +27 -19
- package/dist/clients/inbox/surface.d.ts +0 -4
- package/dist/clients/inbox/surface.js +0 -2
- package/dist/clients/surfaces/host.d.ts +11 -3
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
- package/dist/commands/__tests__/human.test.js +11 -322
- package/dist/commands/api-client.d.ts +5 -5
- package/dist/commands/api-client.js +6 -85
- package/dist/commands/canvas-browse.js +3 -29
- package/dist/commands/canvas-config.js +1 -1
- package/dist/commands/canvas-use.js +3 -3
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/cron.js +5 -1
- package/dist/commands/human/queue.d.ts +0 -4
- package/dist/commands/human/queue.js +7 -40
- package/dist/commands/memory/list.d.ts +14 -0
- package/dist/commands/memory/list.js +35 -31
- package/dist/commands/memory/read.d.ts +7 -0
- package/dist/commands/memory/read.js +14 -8
- package/dist/commands/memory/write.js +13 -12
- package/dist/commands/node/bash.d.ts +1 -0
- package/dist/commands/node/bash.js +198 -0
- package/dist/commands/node/create.d.ts +23 -0
- package/dist/commands/node/create.js +207 -0
- package/dist/commands/node/inspect.d.ts +2 -0
- package/dist/commands/node/inspect.js +302 -0
- package/dist/commands/node/lifecycle.d.ts +4 -0
- package/dist/commands/node/lifecycle.js +415 -0
- package/dist/commands/node/message.d.ts +1 -0
- package/dist/commands/node/message.js +164 -0
- package/dist/commands/node/pyramid.d.ts +2 -0
- package/dist/commands/node/pyramid.js +79 -0
- package/dist/commands/node/subscription.d.ts +1 -0
- package/dist/commands/node/subscription.js +82 -0
- package/dist/commands/node/wait.d.ts +1 -0
- package/dist/commands/node/wait.js +159 -0
- package/dist/commands/node-lifecycle-revive.js +10 -57
- package/dist/commands/node.d.ts +0 -42
- package/dist/commands/node.js +11 -2065
- package/dist/commands/search.js +1 -1
- package/dist/commands/surface/node/cycle.d.ts +1 -0
- package/dist/commands/surface/node/cycle.js +83 -0
- package/dist/commands/surface/node/focus.d.ts +1 -0
- package/dist/commands/surface/node/focus.js +67 -0
- package/dist/commands/surface/node/id.d.ts +1 -0
- package/dist/commands/surface/node/id.js +38 -0
- package/dist/commands/surface/node/pin.d.ts +1 -0
- package/dist/commands/surface/node/pin.js +42 -0
- package/dist/commands/surface/node/placement.d.ts +46 -0
- package/dist/commands/surface/node/placement.js +124 -0
- package/dist/commands/surface-node.js +4 -1
- package/dist/commands/surface-reload.js +1 -2
- package/dist/commands/surface-tmux-spread.js +1 -1
- package/dist/commands/surface.js +5 -20
- package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
- package/dist/commands/sys/config.js +6 -6
- package/dist/commands/sys/logs.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
- package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
- package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
- package/dist/commands/sys/panels/dependencies-panel.js +80 -0
- package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
- package/dist/commands/sys/panels/keybindings-panel.js +703 -0
- package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
- package/dist/commands/sys/panels/keys-panel.js +60 -0
- package/dist/commands/sys/panels/models-panel.d.ts +77 -0
- package/dist/commands/sys/panels/models-panel.js +647 -0
- package/dist/commands/sys/panels/panel.d.ts +45 -0
- package/dist/commands/sys/panels/panel.js +137 -0
- package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
- package/dist/commands/sys/panels/plugins-panel.js +80 -0
- package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
- package/dist/commands/sys/panels/prefs-panel.js +85 -0
- package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
- package/dist/commands/sys/panels/provider-panel.js +538 -0
- package/dist/commands/sys/settings-shell.d.ts +55 -0
- package/dist/commands/sys/settings-shell.js +400 -0
- package/dist/commands/sys/settings.d.ts +2 -0
- package/dist/commands/sys/settings.js +31 -0
- package/dist/commands/sys/setup-core.d.ts +3 -33
- package/dist/commands/sys/setup-core.js +27 -78
- package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
- package/dist/commands/sys/setup-settings-runner.js +63 -0
- package/dist/commands/sys/setup-wizard.d.ts +26 -125
- package/dist/commands/sys/setup-wizard.js +209 -2473
- package/dist/commands/sys/setup.js +5 -7
- package/dist/commands/sys.js +3 -2
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
- package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
- package/dist/core/__tests__/broker-preflight.test.js +1 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
- package/dist/core/__tests__/canvas.test.js +2 -36
- package/dist/core/__tests__/close.test.js +14 -3
- package/dist/core/__tests__/context-intro.test.js +32 -143
- package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
- package/dist/core/__tests__/daemon-boot.test.js +2 -20
- package/dist/core/__tests__/daemon-wedge.test.js +1 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +4 -98
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
- package/dist/core/__tests__/helpers/broker-clients.js +0 -14
- package/dist/core/__tests__/helpers/harness.d.ts +0 -8
- package/dist/core/__tests__/helpers/harness.js +7 -87
- package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
- package/dist/core/__tests__/kickoff.test.js +1 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
- package/dist/core/__tests__/migration.test.js +35 -48
- package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
- package/dist/core/__tests__/passive-subscription.test.js +26 -49
- package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
- package/dist/core/__tests__/prune.test.js +94 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -32
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
- package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
- package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
- package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
- package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
- package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
- package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
- package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
- package/dist/core/__tests__/secrets.test.js +1 -7
- package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
- package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
- package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
- package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
- package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
- package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
- package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
- package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
- package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
- package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
- package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
- package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
- package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
- package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
- package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
- package/dist/core/__tests__/session-model.test.js +0 -18
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
- package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
- package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
- package/dist/core/broker-client/client.d.ts +2 -2
- package/dist/core/broker-client/client.js +4 -7
- package/dist/core/broker-client/transport-relay.d.ts +13 -19
- package/dist/core/broker-client/transport-relay.js +19 -34
- package/dist/core/broker-client/transport-socket.d.ts +2 -2
- package/dist/core/broker-client/transport-socket.js +9 -2
- package/dist/core/broker-client/transport.d.ts +7 -3
- package/dist/core/broker-client/transport.js +4 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -18
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
- package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
- package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
- package/dist/core/canvas/browse/app.d.ts +2 -17
- package/dist/core/canvas/browse/app.js +16 -88
- package/dist/core/canvas/browse/model.d.ts +0 -4
- package/dist/core/canvas/browse/model.js +1 -12
- package/dist/core/canvas/browse/render.js +6 -3
- package/dist/core/canvas/crons.d.ts +8 -5
- package/dist/core/canvas/crons.js +7 -6
- package/dist/core/canvas/extensions.d.ts +7 -3
- package/dist/core/canvas/extensions.js +16 -4
- package/dist/core/canvas/nav-model.d.ts +0 -4
- package/dist/core/canvas/nav-model.js +2 -14
- package/dist/core/canvas/node-order.d.ts +3 -0
- package/dist/core/canvas/node-order.js +12 -0
- package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
- package/dist/core/canvas/remote-canvas-source.js +8 -15
- package/dist/core/command.js +11 -4
- package/dist/core/config.js +3 -1
- package/dist/core/events/envelope.js +1 -1
- package/dist/core/events/read.js +7 -21
- package/dist/core/events/source.d.ts +0 -2
- package/dist/core/events/source.js +0 -16
- package/dist/core/events/types.d.ts +1 -1
- package/dist/core/fault-classifier.d.ts +1 -1
- package/dist/core/feed/passive.d.ts +0 -11
- package/dist/core/feed/passive.js +1 -62
- package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
- package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
- package/dist/core/keybindings/background-bash.js +3 -4
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/memory/inline-ref-grammar.js +3 -3
- package/dist/core/memory-resolver.d.ts +11 -25
- package/dist/core/memory-resolver.js +51 -33
- package/dist/core/model-routes.d.ts +15 -0
- package/dist/core/model-routes.js +12 -0
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/preview-registry.js +8 -9
- package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
- package/dist/core/review/realize.d.ts +0 -13
- package/dist/core/review/realize.js +0 -40
- package/dist/core/review/types.d.ts +1 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
- package/dist/core/runtime/bearings.js +1 -11
- package/dist/core/runtime/broker/client-registry.d.ts +33 -0
- package/dist/core/runtime/broker/client-registry.js +164 -0
- package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
- package/dist/core/runtime/broker/daemon-ops.js +49 -0
- package/dist/core/runtime/broker/event-projection.d.ts +42 -0
- package/dist/core/runtime/broker/event-projection.js +178 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
- package/dist/core/runtime/broker/fault-retry.js +277 -0
- package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
- package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
- package/dist/core/runtime/broker/inbox.d.ts +22 -0
- package/dist/core/runtime/broker/inbox.js +167 -0
- package/dist/core/runtime/broker/passive.d.ts +16 -0
- package/dist/core/runtime/broker/passive.js +44 -0
- package/dist/core/runtime/broker/read-ops.d.ts +23 -0
- package/dist/core/runtime/broker/read-ops.js +150 -0
- package/dist/core/runtime/broker/rebind.d.ts +74 -0
- package/dist/core/runtime/broker/rebind.js +211 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
- package/dist/core/runtime/broker/tool-groups.js +244 -0
- package/dist/core/runtime/broker-extension-render.d.ts +11 -0
- package/dist/core/runtime/broker-extension-render.js +181 -0
- package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
- package/dist/core/runtime/broker-persona-guidance.js +58 -0
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/broker-protocol.js +1 -1
- package/dist/core/runtime/broker.d.ts +5 -196
- package/dist/core/runtime/broker.js +276 -3059
- package/dist/core/runtime/canvas-extensions.js +11 -2
- package/dist/core/runtime/fault.js +1 -1
- package/dist/core/runtime/model-selection.d.ts +9 -0
- package/dist/core/runtime/model-selection.js +12 -0
- package/dist/core/runtime/model-swap.d.ts +3 -3
- package/dist/core/runtime/model-swap.js +33 -25
- package/dist/core/runtime/placement-tmux.d.ts +3 -14
- package/dist/core/runtime/placement-tmux.js +11 -80
- package/dist/core/runtime/placement.d.ts +4 -2
- package/dist/core/runtime/placement.js +7 -12
- package/dist/core/runtime/promote.d.ts +14 -1
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/reset.d.ts +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/runtime/spawn.d.ts +8 -0
- package/dist/core/runtime/spawn.js +36 -6
- package/dist/core/runtime/stop-guard.d.ts +4 -3
- package/dist/core/runtime/stop-guard.js +36 -18
- package/dist/core/runtime/stop-signals.d.ts +4 -1
- package/dist/core/runtime/stream-watchdog.js +4 -5
- package/dist/core/runtime/structured-output.d.ts +15 -2
- package/dist/core/runtime/structured-output.js +35 -12
- package/dist/core/runtime/tmux-bindings.d.ts +25 -0
- package/dist/core/runtime/tmux-bindings.js +682 -0
- package/dist/core/runtime/tmux-chrome.d.ts +2 -1
- package/dist/core/runtime/tmux-chrome.js +3 -2
- package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
- package/dist/core/runtime/tmux-driver.js +598 -0
- package/dist/core/runtime/view-socket.d.ts +14 -0
- package/dist/core/runtime/view-socket.js +83 -0
- package/dist/core/session-model/session-state.d.ts +1 -2
- package/dist/core/session-model/session-state.js +5 -8
- package/dist/core/spawn.d.ts +1 -1
- package/dist/core/spawn.js +2 -2
- package/dist/core/substrate/gate.d.ts +1 -1
- package/dist/core/substrate/on-read-pure.d.ts +7 -0
- package/dist/core/substrate/on-read-pure.js +272 -0
- package/dist/core/termrender/termrender.js +32 -2
- package/dist/core/user-settings.d.ts +23 -1
- package/dist/core/user-settings.js +18 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
- package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
- package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
- package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
- package/dist/daemon/api/bridge.js +40 -81
- package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
- package/dist/daemon/api/handlers/broker-ops.js +383 -0
- package/dist/daemon/api/handlers/crons.js +9 -4
- package/dist/daemon/api/handlers/files.js +6 -7
- package/dist/daemon/api/handlers/inbox.js +2 -340
- package/dist/daemon/api/handlers/nodes.d.ts +10 -1
- package/dist/daemon/api/handlers/nodes.js +74 -39
- package/dist/daemon/api/handlers/review-comments.js +5 -1
- package/dist/daemon/api/handlers/reviews.js +0 -19
- package/dist/daemon/api/map.js +25 -4
- package/dist/daemon/api/router.js +2 -3
- package/dist/daemon/api/server.js +5 -7
- package/dist/daemon/cron-run.d.ts +4 -0
- package/dist/daemon/cron-run.js +30 -13
- package/dist/daemon/crtrd.d.ts +3 -58
- package/dist/daemon/crtrd.js +28 -1244
- package/dist/daemon/manage.js +0 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
- package/dist/daemon/reconcilers/broker-supervision.js +549 -0
- package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
- package/dist/daemon/reconcilers/cron-lane.js +32 -0
- package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
- package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
- package/dist/daemon/review/finish.js +2 -5
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
- package/dist/pi-extensions/broker-local.d.ts +20 -0
- package/dist/pi-extensions/broker-local.js +89 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
- package/dist/pi-extensions/canvas-context-intro.js +22 -11
- package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
- package/dist/pi-extensions/canvas-goal-capture.js +7 -12
- package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
- package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
- package/dist/pi-extensions/canvas-passive-context.js +22 -18
- package/dist/pi-extensions/canvas-recap.d.ts +2 -2
- package/dist/pi-extensions/canvas-recap.js +48 -21
- package/dist/pi-extensions/canvas-review-boundary.js +10 -4
- package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
- package/dist/pi-extensions/canvas-stophook.js +149 -431
- package/dist/pi-extensions/canvas-structured-output.js +52 -30
- package/dist/pi-extensions/envelope-merge.d.ts +13 -0
- package/dist/pi-extensions/envelope-merge.js +29 -0
- package/dist/shared/working-activity.d.ts +3 -2
- package/dist/shared/working-activity.js +3 -2
- package/dist/types.d.ts +6 -5
- package/dist/types.js +2 -2
- package/docs/compat/hearth-crtr-v1.md +4 -12
- package/docs/compat/hearth-crtr-v2.md +3 -11
- package/docs/compat/hearth-crtr-v3.md +4 -12
- package/docs/compat/hearth-crtr-v4.md +3 -11
- package/docs/compat/hearth-crtr-v5.md +3 -11
- package/docs/public-api.md +3 -7
- package/package.json +7 -49
- package/runtime.lock.json +2766 -14533
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
- package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
- package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
- package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
- package/dist/clients/conversation/conversation.d.ts +0 -65
- package/dist/clients/conversation/conversation.js +0 -318
- package/dist/clients/conversation/frames.d.ts +0 -30
- package/dist/clients/conversation/frames.js +0 -52
- package/dist/clients/conversation/region.d.ts +0 -51
- package/dist/clients/conversation/region.js +0 -265
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
- package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
- package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
- package/dist/clients/inbox/review/columns.d.ts +0 -22
- package/dist/clients/inbox/review/columns.js +0 -40
- package/dist/clients/inbox/review/composition.d.ts +0 -60
- package/dist/clients/inbox/review/composition.js +0 -278
- package/dist/clients/inbox/review/document-region.d.ts +0 -120
- package/dist/clients/surfaces/region.d.ts +0 -16
- package/dist/clients/web/__tests__/push-engine.test.js +0 -158
- package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
- package/dist/clients/web/__tests__/push-registry.test.js +0 -177
- package/dist/clients/web/dev-server.d.ts +0 -7
- package/dist/clients/web/dev-server.js +0 -46
- package/dist/clients/web/events.d.ts +0 -19
- package/dist/clients/web/events.js +0 -163
- package/dist/clients/web/push-engine.d.ts +0 -44
- package/dist/clients/web/push-engine.js +0 -125
- package/dist/clients/web/push-registry.d.ts +0 -85
- package/dist/clients/web/push-registry.js +0 -373
- package/dist/clients/web/server.d.ts +0 -19
- package/dist/clients/web/server.js +0 -661
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
- package/dist/clients/web/web-client/shared/protocol.js +0 -8
- package/dist/clients/web/web-cmd.d.ts +0 -2
- package/dist/clients/web/web-cmd.js +0 -141
- package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
- package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
- package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
- package/dist/commands/__tests__/canvas-config.test.js +0 -107
- package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
- package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
- package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
- package/dist/commands/__tests__/search-contents.test.js +0 -52
- package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/lint.test.js +0 -15
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
- package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
- package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
- package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
- package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
- package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
- package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
- package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
- package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
- package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
- package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
- package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
- package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
- package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
- package/dist/core/__tests__/finalization-migration.test.js +0 -38
- package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
- package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
- package/dist/core/__tests__/fork.test.d.ts +0 -1
- package/dist/core/__tests__/fork.test.js +0 -108
- package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
- package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
- package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
- package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
- package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
- package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
- package/dist/core/__tests__/full/cascade-close.test.js +0 -240
- package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/detach-focus.test.js +0 -126
- package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
- package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
- package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
- package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.js +0 -60
- package/dist/core/__tests__/model-routes.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes.test.js +0 -41
- package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-identity.test.js +0 -61
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
- package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
- package/dist/core/__tests__/prune-to-limit.test.js +0 -126
- package/dist/core/__tests__/reset.test.d.ts +0 -1
- package/dist/core/__tests__/reset.test.js +0 -69
- package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
- package/dist/core/__tests__/steer-note.test.d.ts +0 -1
- package/dist/core/__tests__/steer-note.test.js +0 -41
- package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
- package/dist/core/__tests__/subcommand-tier.test.js +0 -99
- package/dist/core/__tests__/subscription-delivery.test.js +0 -211
- package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
- package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
- package/dist/core/__tests__/tmux-surface.test.js +0 -484
- package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
- package/dist/core/__tests__/wake-bearings.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
- package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
- package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
- package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
- package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
- package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
- package/dist/core/canvas/remote-event-stream.d.ts +0 -24
- package/dist/core/canvas/remote-event-stream.js +0 -94
- package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
- package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
- package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
- package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
- package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
- package/dist/core/human/__tests__/visible-paths.test.js +0 -28
- package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
- package/dist/core/review/__tests__/project.test.d.ts +0 -1
- package/dist/core/review/__tests__/project.test.js +0 -71
- package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
- package/dist/core/runtime/tmux.js +0 -1314
- package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
- package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/inbox.test.js +0 -489
- package/dist/web-client/apple-touch-icon.png +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
- package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
- package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
- package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
- package/dist/web-client/icon-192.png +0 -0
- package/dist/web-client/icon-512.png +0 -0
- package/dist/web-client/icon-maskable-512.png +0 -0
- package/dist/web-client/index.html +0 -17
- package/dist/web-client/manifest.webmanifest +0 -1
- package/dist/web-client/sw.js +0 -1
- /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
- /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
- /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
- /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
- /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
- /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
- /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
- /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
- /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
- /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
- /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
- /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
- /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
- /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
- /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
- /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
- /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js}
RENAMED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
// Run with: node --import tsx/esm --test src/core/__tests__/
|
|
1
|
+
// Run with: node --import tsx/esm --test src/core/__tests__/seam/dormancy-release.test.ts
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
3
|
+
// The two real dormancy journeys of a live broker, sharing one harness and one
|
|
4
|
+
// acting root:
|
|
5
|
+
//
|
|
6
|
+
// (1) Issue #222/#353 — a real idle-release cycle must settle the inbox watcher
|
|
7
|
+
// before the broker exits, and the daemon may only revive for a row strictly
|
|
8
|
+
// after the committed cursor.
|
|
9
|
+
// (2) The observed 57-broker / ~5.4GB leak — a boot-revived settled node that
|
|
10
|
+
// receives no new work must still traverse bounded release: DAEMON
|
|
11
|
+
// SUPERVISION, not an agent event, owns the unattended park clock, and the
|
|
12
|
+
// exit policy frees the fleet slot without reviving.
|
|
13
|
+
//
|
|
14
|
+
// Both drive a real broker process through the real watcher/supervision paths, so
|
|
15
|
+
// they belong to the compiled seam tier; neither needs tmux.
|
|
5
16
|
import { after, before, test } from 'node:test';
|
|
6
17
|
import assert from 'node:assert/strict';
|
|
7
18
|
import { appendInbox, readCursor, readInboxSince } from '../../feed/inbox.js';
|
|
@@ -12,8 +23,8 @@ import { createHarness } from '../helpers/harness.js';
|
|
|
12
23
|
let h;
|
|
13
24
|
let root;
|
|
14
25
|
before(async () => {
|
|
15
|
-
h = await createHarness({ headless: true, sessionPrefix: 'crtr-
|
|
16
|
-
root = h.spawnRoot('
|
|
26
|
+
h = await createHarness({ headless: true, sessionPrefix: 'crtr-dormancy' });
|
|
27
|
+
root = h.spawnRoot('dormancy-release suite root');
|
|
17
28
|
});
|
|
18
29
|
after(async () => {
|
|
19
30
|
if (h !== undefined)
|
|
@@ -38,18 +49,11 @@ test('idle-release settles its real watcher before exit; daemon revives exactly
|
|
|
38
49
|
// launch.env, and calling reviveNode rather than through `spawnHeadlessChild`.
|
|
39
50
|
//
|
|
40
51
|
// The same launch.env carries the REAL canvas-inbox-watcher's injectable
|
|
41
|
-
// cadence seam (CRTR_WATCHER_TICK_MS / CRTR_WATCHER_DEBOUNCE_MS
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
// wall-clock polling on top of two real broker boots — negligible in
|
|
47
|
-
// isolation, but on a loaded CI runner deep in the serial `heavy` lane (the
|
|
48
|
-
// only heavy-tier test that calls h.awaitWake()'s real, non-overridable 15s
|
|
49
|
-
// cap) that starved interval tick has repeatedly lost the race and timed
|
|
50
|
-
// out (issue: CI runs 29549096301/29549658681/29550017548, always at the
|
|
51
|
-
// first h.awaitWake). Driving the cadence fast here removes the wall-clock
|
|
52
|
-
// dependency entirely without weakening what's under test: the settlement
|
|
52
|
+
// cadence seam (CRTR_WATCHER_TICK_MS / CRTR_WATCHER_DEBOUNCE_MS). The
|
|
53
|
+
// ordinary source watcher suites drive it through ambient env because they
|
|
54
|
+
// run in-process. Keeping this compiled seam at production cadence would add
|
|
55
|
+
// multiple seconds of polling around two real broker boots, so it uses the
|
|
56
|
+
// same fast cadence without weakening what it proves: the settlement
|
|
53
57
|
// lifecycle, cursor semantics, and hasPendingMessages veto are all
|
|
54
58
|
// independent of how fast the watcher polls.
|
|
55
59
|
const manager = h.fabricateBrokerNode({ id: 'settle-veto-manager', status: 'idle', parent: root });
|
|
@@ -106,3 +110,51 @@ test('idle-release settles its real watcher before exit; daemon revives exactly
|
|
|
106
110
|
await h.tick();
|
|
107
111
|
assert.equal(h.node(manager).cycles ?? 0, cyclesAfterRelease + 1, 'the settled later row does not cause a duplicate revival');
|
|
108
112
|
});
|
|
113
|
+
test('a revived settled node with no work releases on the daemon park clock and leaves no broker', { timeout: 30_000 }, async () => {
|
|
114
|
+
// The park clock is read per supervision pass (unattendedParkMsForDaemon), so
|
|
115
|
+
// it is armed for THIS test only — a file-global 1500ms park clock would also
|
|
116
|
+
// apply to the idle-release manager above and race its own release path.
|
|
117
|
+
const priorParkMs = process.env['CRTR_TEST_UNATTENDED_PARK_MS'];
|
|
118
|
+
process.env['CRTR_TEST_UNATTENDED_PARK_MS'] = '1500';
|
|
119
|
+
try {
|
|
120
|
+
const nodeId = h.fabricateBrokerNode({
|
|
121
|
+
id: 'settled-no-work',
|
|
122
|
+
parent: root,
|
|
123
|
+
status: 'idle',
|
|
124
|
+
intent: 'idle-release',
|
|
125
|
+
});
|
|
126
|
+
updateNode(nodeId, {
|
|
127
|
+
launch: {
|
|
128
|
+
extensions: [],
|
|
129
|
+
tools: [],
|
|
130
|
+
systemPrompt: '',
|
|
131
|
+
env: {},
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
reviveNode(nodeId, { resume: true });
|
|
135
|
+
const boot = await h.awaitBoot(nodeId);
|
|
136
|
+
assert.equal(h.fleet.has(nodeId), true, 'the revived broker is fleet-owned');
|
|
137
|
+
const seenAt = 10_000;
|
|
138
|
+
await h.tick(seenAt);
|
|
139
|
+
await h.tick(seenAt + 1499);
|
|
140
|
+
assert.equal(h.fleet.has(nodeId), true, 'the daemon keeps the broker through the full grace');
|
|
141
|
+
await h.tick(seenAt + 1500);
|
|
142
|
+
await h.waitFor(() => {
|
|
143
|
+
const node = h.node(nodeId);
|
|
144
|
+
return node?.status === 'idle' && node.intent === 'idle-release' && !isPidAlive(boot.pid);
|
|
145
|
+
}, { timeoutMs: 10_000, intervalMs: 20, label: 'park-clock release and broker exit' });
|
|
146
|
+
// The pid vanishing is not the fleet learning about it: wait for the child
|
|
147
|
+
// 'exit' delivery + its policy job, which is what actually frees the slot.
|
|
148
|
+
await h.awaitFleetExit(nodeId);
|
|
149
|
+
assert.equal(h.fleet.has(nodeId), false, 'exit policy forgets the idle-release broker');
|
|
150
|
+
assert.equal(h.node(nodeId)?.intent, 'idle-release', 'the row remains durably dormant');
|
|
151
|
+
await h.tick();
|
|
152
|
+
assert.equal(h.fleet.has(nodeId), false, 'a supervision tick does not revive without inbox work');
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
if (priorParkMs === undefined)
|
|
156
|
+
delete process.env['CRTR_TEST_UNATTENDED_PARK_MS'];
|
|
157
|
+
else
|
|
158
|
+
process.env['CRTR_TEST_UNATTENDED_PARK_MS'] = priorParkMs;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
// Run with: node --import tsx/esm --test src/core/__tests__/
|
|
1
|
+
// Run with: node --import tsx/esm --test src/core/__tests__/seam/yield-refresh-transaction.test.ts
|
|
2
2
|
//
|
|
3
3
|
// Regression: one-shot <yield-message/> handoff must survive pre-session_start cycle
|
|
4
|
-
// death and only clear once session_start confirms a successful boot
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// death and only clear once session_start confirms a successful boot, and a
|
|
5
|
+
// competing strict-resume revive (issue #146: a real `surface node focus` while
|
|
6
|
+
// the refresh is still pending) must not reopen the old session. This test runs
|
|
7
|
+
// against the real broker process (headless harness) and a deterministic one-shot
|
|
8
|
+
// pre-start fault injection so a single retry is exercised in-band.
|
|
7
9
|
import { test, before, after } from 'node:test';
|
|
8
10
|
import assert from 'node:assert/strict';
|
|
9
11
|
import { existsSync } from 'node:fs';
|
|
10
12
|
import { createHarness } from '../helpers/harness.js';
|
|
11
13
|
import { isPidAlive } from '../../canvas/pid.js';
|
|
14
|
+
import { reviveNode } from '../../runtime/revive.js';
|
|
12
15
|
import { readYieldMessage, yieldMessagePath } from '../../runtime/kickoff.js';
|
|
13
16
|
import { FAIL_BEFORE_SESSION_START_ONCE } from '../fixtures/fake-engine.js';
|
|
14
17
|
let h;
|
|
@@ -21,7 +24,7 @@ after(async () => {
|
|
|
21
24
|
if (h !== undefined)
|
|
22
25
|
await h.dispose();
|
|
23
26
|
});
|
|
24
|
-
// 30s (approved
|
|
27
|
+
// 30s (approved compiled-seam cap): three real broker boots plus the exit-policy
|
|
25
28
|
// respawn throttle's first ~5s backoff before the successful retry.
|
|
26
29
|
test('yield-message survives one pre-session_start retry and clears on session_start', { timeout: 30_000 }, async () => {
|
|
27
30
|
const note = `Issue #146 pre-session_start replay ${FAIL_BEFORE_SESSION_START_ONCE} keeps the wake note`;
|
|
@@ -44,15 +47,34 @@ test('yield-message survives one pre-session_start retry and clears on session_s
|
|
|
44
47
|
return pid != null && pid !== oldPid ? pid : null;
|
|
45
48
|
}, { label: 'exit-event refresh attempt recorded its broker pid', timeoutMs: 30_000 });
|
|
46
49
|
await h.waitFor(() => !isPidAlive(failedCyclePid), { label: 'one-shot cycling broker died before session_start' });
|
|
50
|
+
// PID death precedes Node's ChildProcess `exit` delivery. Wait through the
|
|
51
|
+
// authoritative fleet barrier and its queued exit-policy job so the contender
|
|
52
|
+
// below reaches refresh arbitration instead of returning on stale liveness.
|
|
53
|
+
// The policy has only armed its backoff timer at this point; no recovery broker
|
|
54
|
+
// owns the slot yet.
|
|
55
|
+
await h.awaitFleetExit(id);
|
|
47
56
|
const afterFirstExit = h.node(id);
|
|
57
|
+
assert.equal(h.fleet.has(id), false, 'the failed broker has left the authoritative fleet before focus competes');
|
|
48
58
|
assert.equal(afterFirstExit?.cycles, baseCycles + 1, 'the first refresh attempt advances cycles');
|
|
59
|
+
assert.equal(afterFirstExit?.intent, 'refresh', 'the durable refresh intent still confronts the strict-resume contender');
|
|
49
60
|
assert.equal(afterFirstExit?.cycle_pending, true, 'cycle_pending remains true until session_start confirms');
|
|
50
61
|
assert.equal(readYieldMessage(id), note, 'yield note stays present after pre-session_start failure');
|
|
51
62
|
assert.equal(existsSync(yieldMessagePath(id)), true, 'yield file survives the failed cycle');
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
63
|
+
// A real `surface node focus` on the node right now asks the revive arbiter for
|
|
64
|
+
// a STRICT RESUME (issue #146). It must lose to the durable pending refresh:
|
|
65
|
+
// the retry still roots a fresh cycle carrying the note, never reopening the
|
|
66
|
+
// old session. Driving reviveNode directly is exactly what focus's revive path
|
|
67
|
+
// calls, minus a tmux pane this contract does not involve.
|
|
68
|
+
const focusRevive = reviveNode(id, { resume: true });
|
|
69
|
+
const focusPid = focusRevive.launch?.pid;
|
|
70
|
+
assert.ok(focusPid != null, 'the competing focus invocation launches the replacement broker');
|
|
71
|
+
assert.equal(focusRevive.resumed, false, 'refresh intent overrides this invocation\'s strict-resume request');
|
|
72
|
+
assert.equal(h.fleet.get(id)?.pid, focusPid, 'the focus invocation synchronously owns the authoritative fleet slot');
|
|
73
|
+
// Registering the manual launch cancels the exit policy's deferred recovery.
|
|
74
|
+
// Its pid must therefore be the successful observed boot, proving these
|
|
75
|
+
// assertions belong to the contender above rather than an already-queued boot.
|
|
55
76
|
const boot = await h.awaitBoot(id, { minCount: baseBoot + 1, timeoutMs: 120_000 });
|
|
77
|
+
assert.equal(boot.pid, focusPid, 'the competing focus invocation owns the confirmed boot');
|
|
56
78
|
const afterRetry = h.node(id);
|
|
57
79
|
assert.equal(afterRetry?.cycles, baseCycles + 2, 'the retry advances once from the latest locked cycle');
|
|
58
80
|
assert.equal(afterRetry?.cycle_pending, false, 'session_start cleared cycle_pending');
|
|
@@ -62,7 +84,7 @@ test('yield-message survives one pre-session_start retry and clears on session_s
|
|
|
62
84
|
assert.equal(boot.prompt.includes(note), true, 'the successful retry kickoff still contains the yield note');
|
|
63
85
|
assert.match(boot.prompt, /<goal file="[^"]+">/, 'a no-roadmap base refresh includes its original goal');
|
|
64
86
|
assert.equal(boot.prompt.includes('headless worker — yield message transactional retry'), true, 'the kickoff carries the original base-node mandate');
|
|
65
|
-
assert.equal(boot.resuming, false, '
|
|
87
|
+
assert.equal(boot.resuming, false, 'a competing focus resume=true cannot reopen the old session while the refresh is pending');
|
|
66
88
|
const updated = h.node(id);
|
|
67
89
|
assert.equal(updated?.mode, 'base', 'a plain yield refresh remains base');
|
|
68
90
|
assert.ok(updated?.pi_session_id != null, 'successful retry recorded a session id');
|
|
@@ -7,7 +7,7 @@ import assert from 'node:assert/strict';
|
|
|
7
7
|
import { mkdtempSync, rmSync, statSync, existsSync, chmodSync } from 'node:fs';
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
-
import { readSecrets, writeSecrets, getRelayToken, setRelayToken, deleteRelayToken
|
|
10
|
+
import { readSecrets, writeSecrets, getRelayToken, setRelayToken, deleteRelayToken } from '../secrets.js';
|
|
11
11
|
let home;
|
|
12
12
|
let realHome;
|
|
13
13
|
before(() => {
|
|
@@ -47,9 +47,3 @@ test('writeSecrets writes secrets.json 0600, even over a pre-existing looser-mod
|
|
|
47
47
|
writeSecrets('user', { relayTokens: { a: 'x', b: 'y' } });
|
|
48
48
|
assert.equal(statSync(p).mode & 0o777, 0o600);
|
|
49
49
|
});
|
|
50
|
-
test('fingerprint is the sha256(token) hex prefix — pinned, so a reversible encoding fails', () => {
|
|
51
|
-
assert.equal(fingerprint('sekret-token-value'), '662bda51b31e');
|
|
52
|
-
assert.notEqual(fingerprint('a-different-token'), fingerprint('sekret-token-value'));
|
|
53
|
-
assert.match(fingerprint('sekret-token-value'), /^[0-9a-f]{12}$/);
|
|
54
|
-
assert.ok(!fingerprint('sekret-token-value').includes('sekret-token-value'));
|
|
55
|
-
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Run with:
|
|
1
|
+
// Run with: npm run test:serial
|
|
2
2
|
//
|
|
3
3
|
// BUG-REGRESSION (broker-universal-host cut, design §B.broker; U1 report
|
|
4
4
|
// mq8ftenr-5d55313d). Before the cut, the headless broker had NO fork path — its
|
|
@@ -24,17 +24,20 @@
|
|
|
24
24
|
// uses, whose fixture omits forkFrom and so could never exercise this branch. It
|
|
25
25
|
// runs offline (fork + session/services assembly are all local: no network/auth).
|
|
26
26
|
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
27
|
+
// The tail of this file covers the pre-launch resolve layer that feeds the
|
|
28
|
+
// broker branch: `resolveForkSource` refusing a reference that resolves to no
|
|
29
|
+
// forkable session file.
|
|
30
30
|
import { test, before, after } from 'node:test';
|
|
31
31
|
import assert from 'node:assert/strict';
|
|
32
32
|
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
33
33
|
import { tmpdir } from 'node:os';
|
|
34
34
|
import { dirname, join } from 'node:path';
|
|
35
35
|
import { fileURLToPath } from 'node:url';
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
36
|
+
import { createNode } from '../../canvas/canvas.js';
|
|
37
|
+
import { closeDb } from '../../canvas/db.js';
|
|
38
|
+
import { resolveForkSource } from '../../runtime/spawn.js';
|
|
39
|
+
import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../../runtime/broker-sdk.js';
|
|
40
|
+
import { buildBrokerSession } from '../../runtime/broker.js';
|
|
38
41
|
// M-9 (broker.ts fault-and-die model gate): buildBrokerSession with no cfg.model
|
|
39
42
|
// now calls the REAL SDK's modelRegistry.getAvailable() and faults if it's empty
|
|
40
43
|
// — which it always is on a host/CI runner with no authenticated provider. This
|
|
@@ -42,7 +45,7 @@ import { buildBrokerSession } from '../runtime/broker.js';
|
|
|
42
45
|
// fake-but-authenticated model the C3 wiring tests use, rather than depending on
|
|
43
46
|
// ambient host credentials (which don't exist in CI — see broker-sdk-wiring's
|
|
44
47
|
// c3-custom-provider-ext.ts fixture).
|
|
45
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
const HERE = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
46
49
|
const C3_EXT = join(HERE, 'fixtures', 'c3-custom-provider-ext.ts');
|
|
47
50
|
// The REAL engine — bypasses the CRTR_BROKER_ENGINE fake entirely (the whole
|
|
48
51
|
// point: the fake omits forkFrom, so only the real SDK can prove the branch).
|
|
@@ -115,3 +118,51 @@ test('D2 broker fork branch: buildBrokerSession(cfg.forkFrom) yields a NEW id +
|
|
|
115
118
|
session.dispose();
|
|
116
119
|
}
|
|
117
120
|
});
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// resolveForkSource — a reference that resolves to no forkable session file
|
|
123
|
+
// must fail loudly BEFORE launch, rather than hand the broker a source it
|
|
124
|
+
// cannot fork.
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
function nodeRow(id, over = {}) {
|
|
127
|
+
return {
|
|
128
|
+
node_id: id,
|
|
129
|
+
name: id,
|
|
130
|
+
created: new Date().toISOString(),
|
|
131
|
+
cwd: '/tmp/work',
|
|
132
|
+
kind: 'developer',
|
|
133
|
+
mode: 'base',
|
|
134
|
+
lifecycle: 'terminal',
|
|
135
|
+
status: 'active',
|
|
136
|
+
...over,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
test('resolveForkSource refuses every reference that resolves to no forkable session file', () => {
|
|
140
|
+
const home = mkdtempSync(join(tmpdir(), 'crtr-fork-resolve-'));
|
|
141
|
+
const sessions = mkdtempSync(join(tmpdir(), 'crtr-pi-agent-'));
|
|
142
|
+
const previousHome = process.env['CRTR_HOME'];
|
|
143
|
+
process.env['CRTR_HOME'] = home;
|
|
144
|
+
process.env['PI_CODING_AGENT_DIR'] = sessions;
|
|
145
|
+
try {
|
|
146
|
+
// Broker-cut contract (U6/§B.broker): the broker forks an absolute .jsonl
|
|
147
|
+
// PATH, never a bare session id, so a node row carrying only pi_session_id
|
|
148
|
+
// is unforkable.
|
|
149
|
+
createNode(nodeRow('id-only', { pi_session_id: 'uuid-1' }));
|
|
150
|
+
assert.throws(() => resolveForkSource('id-only'), /no pi session yet|session FILE/);
|
|
151
|
+
createNode(nodeRow('fresh'));
|
|
152
|
+
assert.throws(() => resolveForkSource('fresh'), /no pi session yet/);
|
|
153
|
+
// An unknown bare/partial uuid is scanned against pi's sessions store and
|
|
154
|
+
// fails when it matches nothing — never passed through verbatim.
|
|
155
|
+
assert.throws(() => resolveForkSource('019e8ce3-322e'), /no pi session/);
|
|
156
|
+
assert.throws(() => resolveForkSource(' '), /requires a node id/);
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
closeDb();
|
|
160
|
+
delete process.env['PI_CODING_AGENT_DIR'];
|
|
161
|
+
if (previousHome === undefined)
|
|
162
|
+
delete process.env['CRTR_HOME'];
|
|
163
|
+
else
|
|
164
|
+
process.env['CRTR_HOME'] = previousHome;
|
|
165
|
+
rmSync(home, { recursive: true, force: true });
|
|
166
|
+
rmSync(sessions, { recursive: true, force: true });
|
|
167
|
+
}
|
|
168
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Run with:
|
|
1
|
+
// Run with: npm run test:serial
|
|
2
2
|
//
|
|
3
3
|
// REAL-SDK regression tests for the latent broker gaps the viewer-reuse scout
|
|
4
4
|
// (node mq5thyli) found (findings-viewer-reuse.md §Q2). These deliberately drive
|
|
@@ -25,13 +25,10 @@ import { spawnSync } from 'node:child_process';
|
|
|
25
25
|
import { tmpdir } from 'node:os';
|
|
26
26
|
import { join, dirname } from 'node:path';
|
|
27
27
|
import { fileURLToPath } from 'node:url';
|
|
28
|
-
import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '
|
|
29
|
-
import { buildBrokerSession, makeBrokerUiContext
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import { buildGuidance } from '../memory/inline-ref-guidance.js';
|
|
33
|
-
import { resetScopeCache } from '../scope.js';
|
|
34
|
-
import { clearSessionCache } from '../substrate/session-cache.js';
|
|
28
|
+
import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../../runtime/broker-sdk.js';
|
|
29
|
+
import { buildBrokerSession, makeBrokerUiContext } from '../../runtime/broker.js';
|
|
30
|
+
import { isLeadingEngineCommand, resolveSteerCall, chooseGuidanceDeliveryMode, promptWithNextTurnGuidance, isHiddenJsonlBranchEntry, stripHiddenEntriesFromJsonlExport, engineLeadingCommandTokens, } from '../../runtime/broker/frame-dispatch.js';
|
|
31
|
+
import { CANVAS_EXTENSIONS } from '../../runtime/launch.js';
|
|
35
32
|
// The REAL engine, assembled from broker-sdk's static SDK re-exports — bypasses
|
|
36
33
|
// the CRTR_BROKER_ENGINE seam entirely so these tests can never accidentally hit
|
|
37
34
|
// the fake (the whole point: prove the wiring the mock hid).
|
|
@@ -41,7 +38,7 @@ const realEngine = {
|
|
|
41
38
|
SessionManager,
|
|
42
39
|
VERSION,
|
|
43
40
|
};
|
|
44
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
41
|
+
const HERE = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
45
42
|
const C3_EXT = join(HERE, 'fixtures', 'c3-custom-provider-ext.ts');
|
|
46
43
|
const C5_EXT = join(HERE, 'fixtures', 'c5-command-boundary-ext.ts');
|
|
47
44
|
const priorModelIntent = process.env['CRTR_MODEL_INTENT'];
|
|
@@ -161,9 +158,9 @@ function runIsolatedManagedLaunch(pool) {
|
|
|
161
158
|
const home = mkdtempSync(join(tmpdir(), 'crtr-c3-managed-home-'));
|
|
162
159
|
const cwd = mkdtempSync(join(tmpdir(), 'crtr-c3-managed-cwd-'));
|
|
163
160
|
const script = `
|
|
164
|
-
const { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION } = await import(${JSON.stringify(new URL('
|
|
165
|
-
const { buildBrokerSession } = await import(${JSON.stringify(new URL('
|
|
166
|
-
const { writeSubscriptionPool } = await import(${JSON.stringify(new URL('
|
|
161
|
+
const { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION } = await import(${JSON.stringify(new URL('../../runtime/broker-sdk.ts', import.meta.url).href)});
|
|
162
|
+
const { buildBrokerSession } = await import(${JSON.stringify(new URL('../../runtime/broker.ts', import.meta.url).href)});
|
|
163
|
+
const { writeSubscriptionPool } = await import(${JSON.stringify(new URL('../../subscription-state.ts', import.meta.url).href)});
|
|
167
164
|
await writeSubscriptionPool('anthropic', ${JSON.stringify(pool)});
|
|
168
165
|
const realEngine = { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION };
|
|
169
166
|
const engine = {
|
|
@@ -358,14 +355,13 @@ test('M2 — a forwarded dialog stays pending when its writable viewer detaches,
|
|
|
358
355
|
assert.equal(pending.size, 0, 'M2: the pending registry is drained after the timeout');
|
|
359
356
|
});
|
|
360
357
|
// ===========================================================================
|
|
361
|
-
// C5 —
|
|
362
|
-
//
|
|
363
|
-
// display:false guidance delivery ordering.
|
|
358
|
+
// C5 — exact leading engine-command suppression and hidden display:false
|
|
359
|
+
// guidance delivery ordering.
|
|
364
360
|
//
|
|
365
361
|
// REACHABILITY NOTE: broker.ts's `handleFrame`/`driveEngine` switches are
|
|
366
|
-
// private closures inside `runBroker`, so
|
|
367
|
-
// process to drive raw wire frames (that end-to-end plumbing lives
|
|
368
|
-
//
|
|
362
|
+
// private closures inside `runBroker`, so this serialized source suite does not
|
|
363
|
+
// boot a broker process to drive raw wire frames (that end-to-end plumbing lives
|
|
364
|
+
// in the compiled seam alongside the sibling `list_models` read-op). Instead every
|
|
369
365
|
// EXPORTED building block those closures call is driven directly — the pure
|
|
370
366
|
// decision functions (`isLeadingEngineCommand`, `chooseGuidanceDeliveryMode`,
|
|
371
367
|
// `engineLeadingCommandTokens`) AND the stateful delivery/export helpers
|
|
@@ -374,41 +370,10 @@ test('M2 — a forwarded dialog stays pending when its writable viewer detaches,
|
|
|
374
370
|
// JSONL bytes, including the exact interception/leak window (Major 1) and the
|
|
375
371
|
// actual exported file (Major 2). What remains untested here is only the
|
|
376
372
|
// one-line frame relay (`sendFrame(client, buildListMemoryRefsData(id))`), a
|
|
377
|
-
// verbatim sibling of the
|
|
373
|
+
// verbatim sibling of the compiled-seam-covered `list_models` dispatch whose only
|
|
378
374
|
// non-trivial input, `engineLeadingCommandTokens(session)`, is proven below
|
|
379
375
|
// against a real session.
|
|
380
376
|
// ===========================================================================
|
|
381
|
-
test('C5 — isLeadingEngineCommand truth table against structural stubs (pure, no live session)', () => {
|
|
382
|
-
// Extension command: matches / does not match.
|
|
383
|
-
const extOnly = { extensionRunner: { getCommand: (name) => (name === 'dev' ? { name: 'dev' } : undefined) } };
|
|
384
|
-
assert.equal(isLeadingEngineCommand('/dev', extOnly), true, 'registered extension command matches');
|
|
385
|
-
assert.equal(isLeadingEngineCommand('/dev extra args', extOnly), true, 'space-separated still matches (name up to first space)');
|
|
386
|
-
assert.equal(isLeadingEngineCommand('/nope', extOnly), false, 'unregistered command name does not match');
|
|
387
|
-
// Skill: matches / does not match.
|
|
388
|
-
const skillOnly = { resourceLoader: { getSkills: () => ({ skills: [{ name: 'myskill' }] }) } };
|
|
389
|
-
assert.equal(isLeadingEngineCommand('/skill:myskill', skillOnly), true, 'registered skill matches');
|
|
390
|
-
assert.equal(isLeadingEngineCommand('/skill:other', skillOnly), false, 'unregistered skill name does not match');
|
|
391
|
-
// Template: matches / does not match.
|
|
392
|
-
const templateOnly = { promptTemplates: [{ name: 'mytemplate' }] };
|
|
393
|
-
assert.equal(isLeadingEngineCommand('/mytemplate', templateOnly), true, 'registered prompt template matches');
|
|
394
|
-
assert.equal(isLeadingEngineCommand('/other', templateOnly), false, 'unregistered template name does not match');
|
|
395
|
-
// Prose with no leading slash never matches any of the three checks.
|
|
396
|
-
assert.equal(isLeadingEngineCommand('no leading slash here /dev', extOnly), false, 'a leading command check only looks at text start');
|
|
397
|
-
// An engine missing an accessor entirely degrades to "not a match", never throws.
|
|
398
|
-
assert.equal(isLeadingEngineCommand('/dev', {}), false, 'a bare {} session (no accessors) degrades to false without throwing');
|
|
399
|
-
// A throwing accessor for one check must not abort the OTHER independent
|
|
400
|
-
// checks — here extensionRunner.getCommand throws, but the SAME text still
|
|
401
|
-
// correctly resolves via promptTemplates.
|
|
402
|
-
const throwingExtButRealTemplate = {
|
|
403
|
-
extensionRunner: {
|
|
404
|
-
getCommand: () => {
|
|
405
|
-
throw new Error('boom: no live extensionRunner');
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
promptTemplates: [{ name: 'mytemplate' }],
|
|
409
|
-
};
|
|
410
|
-
assert.equal(isLeadingEngineCommand('/mytemplate', throwingExtButRealTemplate), true, 'a throwing extensionRunner check degrades to false for ITSELF but does not abort the template check');
|
|
411
|
-
});
|
|
412
377
|
test('a streaming extension command uses prompt preflight instead of the rejecting steer queue', () => {
|
|
413
378
|
const session = { extensionRunner: { getCommand: (name) => (name === 'recap' ? { name: 'recap' } : undefined) } };
|
|
414
379
|
assert.equal(resolveSteerCall('/recap', session), 'prompt');
|
|
@@ -420,9 +385,8 @@ test('C5 — isLeadingEngineCommand against a REAL session (registered extension
|
|
|
420
385
|
// (the real broker's initial-boot step, which fires `resources_discover`) —
|
|
421
386
|
// not reachable from `buildBrokerSession` alone, and driving it directly
|
|
422
387
|
// pulls in this machine's full local pi resource corpus (slow, environment-
|
|
423
|
-
// dependent).
|
|
424
|
-
//
|
|
425
|
-
// proven against a plain object shaped like the real accessors.
|
|
388
|
+
// dependent). The skill/prompt-template branches run the same accessor-
|
|
389
|
+
// guarded decision logic as the extension-command branch proven here.
|
|
426
390
|
const cwd = mkdtempSync(join(tmpdir(), 'crtr-c5-cmd-'));
|
|
427
391
|
try {
|
|
428
392
|
const { session } = await buildBrokerSession(realEngine, cfg(cwd, { extensionPaths: [C3_EXT, C5_EXT], model: 'c3prov/c3model' }));
|
|
@@ -454,77 +418,6 @@ test('C5 — chooseGuidanceDeliveryMode truth table (pure)', () => {
|
|
|
454
418
|
// steer, never nextTurn (that would attach guidance to a later, unrelated turn).
|
|
455
419
|
assert.equal(chooseGuidanceDeliveryMode('prompt', 'prompt', true), 'steer');
|
|
456
420
|
});
|
|
457
|
-
test('C5 — buildRefInventory reflects a new doc only after clearSessionCache (the invalidation contract `case \'reload\'` relies on)', () => {
|
|
458
|
-
const canvasHome = mkdtempSync(join(tmpdir(), 'crtr-c5-inv-canvas-'));
|
|
459
|
-
const userHome = mkdtempSync(join(tmpdir(), 'crtr-c5-inv-user-'));
|
|
460
|
-
const projectBase = mkdtempSync(join(tmpdir(), 'crtr-c5-inv-project-'));
|
|
461
|
-
const projectRoot = join(projectBase, 'root');
|
|
462
|
-
const prevCanvasHome = process.env['CRTR_HOME'];
|
|
463
|
-
const prevUserHome = process.env['HOME'];
|
|
464
|
-
const prevNodeId = process.env['CRTR_NODE_ID'];
|
|
465
|
-
const prevCwd = process.cwd();
|
|
466
|
-
try {
|
|
467
|
-
mkdirSync(projectRoot, { recursive: true });
|
|
468
|
-
process.env['CRTR_HOME'] = canvasHome;
|
|
469
|
-
process.env['HOME'] = userHome;
|
|
470
|
-
delete process.env['CRTR_NODE_ID'];
|
|
471
|
-
process.chdir(projectRoot);
|
|
472
|
-
resetScopeCache();
|
|
473
|
-
clearSessionCache();
|
|
474
|
-
const memoryDir = join(projectRoot, '.crouter', 'memory');
|
|
475
|
-
mkdirSync(memoryDir, { recursive: true });
|
|
476
|
-
writeFileSync(join(memoryDir, 'crtr-c5-inv-first.md'), '---\nkind: knowledge\n---\nBody.\n');
|
|
477
|
-
const first = buildRefInventory();
|
|
478
|
-
assert.ok(first.names.has('crtr-c5-inv-first'), 'the first doc is visible on the first build');
|
|
479
|
-
// A second doc written after the first inventory build must NOT appear
|
|
480
|
-
// until the session parse cache is cleared — this is the exact mechanism
|
|
481
|
-
// broker.ts's `case 'reload'` invalidates by calling `clearSessionCache()`
|
|
482
|
-
// (and, in broker.ts, also resetting its own `memoizedRefInventory`).
|
|
483
|
-
writeFileSync(join(memoryDir, 'crtr-c5-inv-second.md'), '---\nkind: knowledge\n---\nBody.\n');
|
|
484
|
-
const stale = buildRefInventory();
|
|
485
|
-
assert.ok(!stale.names.has('crtr-c5-inv-second'), 'a doc written after the cache was warmed is NOT yet visible');
|
|
486
|
-
clearSessionCache();
|
|
487
|
-
const fresh = buildRefInventory();
|
|
488
|
-
assert.ok(fresh.names.has('crtr-c5-inv-second'), 'clearSessionCache() makes the new doc visible — the reload contract');
|
|
489
|
-
}
|
|
490
|
-
finally {
|
|
491
|
-
process.chdir(prevCwd);
|
|
492
|
-
resetScopeCache();
|
|
493
|
-
clearSessionCache();
|
|
494
|
-
rmSync(canvasHome, { recursive: true, force: true });
|
|
495
|
-
rmSync(userHome, { recursive: true, force: true });
|
|
496
|
-
rmSync(projectBase, { recursive: true, force: true });
|
|
497
|
-
if (prevCanvasHome === undefined)
|
|
498
|
-
delete process.env['CRTR_HOME'];
|
|
499
|
-
else
|
|
500
|
-
process.env['CRTR_HOME'] = prevCanvasHome;
|
|
501
|
-
if (prevUserHome === undefined)
|
|
502
|
-
delete process.env['HOME'];
|
|
503
|
-
else
|
|
504
|
-
process.env['HOME'] = prevUserHome;
|
|
505
|
-
if (prevNodeId === undefined)
|
|
506
|
-
delete process.env['CRTR_NODE_ID'];
|
|
507
|
-
else
|
|
508
|
-
process.env['CRTR_NODE_ID'] = prevNodeId;
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
test('C5 — guidance composition mirrors broker.ts\'s private resolveFrameGuidance: leading-command check first, then buildGuidance', () => {
|
|
512
|
-
// Mirrors broker.ts's private `resolveFrameGuidance(text)`:
|
|
513
|
-
// if (isLeadingEngineCommand(text, session)) return null;
|
|
514
|
-
// return buildGuidance(text, getRefInventory().names);
|
|
515
|
-
// `isLeadingEngineCommand`/`buildGuidance` are each independently covered
|
|
516
|
-
// above / in C4's own suite (inline-memory-refs.test.ts) — this proves only
|
|
517
|
-
// the ORDER of composition: a leading match short-circuits before any ref
|
|
518
|
-
// in the SAME text is ever resolved.
|
|
519
|
-
const stubSession = { extensionRunner: { getCommand: () => undefined } };
|
|
520
|
-
const names = new Set(['dev']);
|
|
521
|
-
assert.equal(isLeadingEngineCommand('/dev /dev', stubSession), false, 'not a registered command against this stub');
|
|
522
|
-
assert.equal(buildGuidance('/dev /dev', names), [
|
|
523
|
-
'The human explicitly referenced these memory documents. Before acting on the portion of their message that references each document, run the corresponding command and treat its returned content as authoritative context:',
|
|
524
|
-
'- crtr memory read dev',
|
|
525
|
-
].join('\n'), 'a non-leading-command text with a resolvable ref still produces guidance');
|
|
526
|
-
assert.equal(buildGuidance('/nope has nothing to do with it', names), null, 'an unresolvable ref alone produces no guidance');
|
|
527
|
-
});
|
|
528
421
|
test('C5 — fake-engine sendCustomMessage records the call in order without crashing', async () => {
|
|
529
422
|
const home = mkdtempSync(join(tmpdir(), 'crtr-c5-fake-home-'));
|
|
530
423
|
const cwd = mkdtempSync(join(tmpdir(), 'crtr-c5-fake-cwd-'));
|
|
@@ -533,7 +426,7 @@ test('C5 — fake-engine sendCustomMessage records the call in order without cra
|
|
|
533
426
|
try {
|
|
534
427
|
process.env['CRTR_HOME'] = home;
|
|
535
428
|
process.env['CRTR_NODE_ID'] = 'crtr-c5-fake-node';
|
|
536
|
-
const fake = await import('
|
|
429
|
+
const fake = await import('.././fixtures/fake-engine.js');
|
|
537
430
|
const services = await fake.createAgentSessionServices({ cwd });
|
|
538
431
|
const sessionManager = fake.SessionManager.create(cwd);
|
|
539
432
|
const { session } = await fake.createAgentSessionFromServices({ services, sessionManager });
|
|
@@ -609,27 +502,6 @@ test('promptWithNextTurnGuidance uses a structured-clone-safe cleanup marker', a
|
|
|
609
502
|
await promptWithNextTurnGuidance(session, 'crtr memory read dev', async () => undefined);
|
|
610
503
|
assert.deepEqual(pending, [], 'clone-safe marker still identifies and clears exactly its own pending entry');
|
|
611
504
|
});
|
|
612
|
-
test('Major 1 fix — pre-fix sequence (sendCustomMessage THEN prompt, no cleanup) reproduces the leak this fix removes', async () => {
|
|
613
|
-
// Negative control: proves the fixture/interception setup above genuinely
|
|
614
|
-
// exercises the leak window — the OLD sequencing (what driveEngine did
|
|
615
|
-
// before this fix) strands the guidance under the exact same interception.
|
|
616
|
-
const cwd = mkdtempSync(join(tmpdir(), 'crtr-m1-repro-'));
|
|
617
|
-
try {
|
|
618
|
-
const { session } = await buildBrokerSession(realEngine, cfg(cwd, { extensionPaths: [C5_EXT] }));
|
|
619
|
-
try {
|
|
620
|
-
await session.sendCustomMessage({ customType: 'crtr-memory-refs', content: 'guidance', display: false }, { deliverAs: 'nextTurn' });
|
|
621
|
-
await session.prompt('/devcmd', {});
|
|
622
|
-
const pending = session._pendingNextTurnMessages;
|
|
623
|
-
assert.equal(pending.length, 1, 'Major 1 (control): the pre-fix sequence strands exactly the guidance message it pushed');
|
|
624
|
-
}
|
|
625
|
-
finally {
|
|
626
|
-
session.dispose();
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
finally {
|
|
630
|
-
rmSync(cwd, { recursive: true, force: true });
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
505
|
test('Major 1 fix — promptWithNextTurnGuidance leaves the queue drained (not doubly-cleared) on a normal successful prompt', async () => {
|
|
634
506
|
// Guards against the cleanup over-firing on the HAPPY path: a prompt that
|
|
635
507
|
// genuinely reaches pi's drain already empties `_pendingNextTurnMessages`
|
|
@@ -718,22 +590,6 @@ test('Major 2 fix — exportToJsonl (via the broker export path) strips display:
|
|
|
718
590
|
// (RefMeta rows), exactly matching `isLeadingEngineCommand`'s three sources,
|
|
719
591
|
// so viewers can combine it with their own locally-consumed commands.
|
|
720
592
|
// ===========================================================================
|
|
721
|
-
test('Major 6 (broker half) — engineLeadingCommandTokens exactly matches isLeadingEngineCommand\'s sources (round-trip, pure stubs)', () => {
|
|
722
|
-
const session = {
|
|
723
|
-
extensionRunner: {
|
|
724
|
-
getRegisteredCommands: () => [{ invocationName: 'devcmd' }],
|
|
725
|
-
getCommand: (n) => (n === 'devcmd' ? {} : undefined),
|
|
726
|
-
},
|
|
727
|
-
resourceLoader: { getSkills: () => ({ skills: [{ name: 'myskill' }] }) },
|
|
728
|
-
promptTemplates: [{ name: 'mytemplate' }],
|
|
729
|
-
};
|
|
730
|
-
const tokens = engineLeadingCommandTokens(session);
|
|
731
|
-
assert.deepEqual(new Set(tokens), new Set(['devcmd', 'skill:myskill', 'mytemplate']), 'every one of the three sources is enumerated, in isLeadingEngineCommand\'s own token shape');
|
|
732
|
-
for (const token of tokens) {
|
|
733
|
-
assert.equal(isLeadingEngineCommand(`/${token}`, session), true, `emitted token "${token}" round-trips through isLeadingEngineCommand as a leading match`);
|
|
734
|
-
}
|
|
735
|
-
assert.equal(isLeadingEngineCommand('/nope', session), false, 'a name NOT in the enumeration correctly does not match');
|
|
736
|
-
});
|
|
737
593
|
test('Major 6 (broker half) — engineLeadingCommandTokens degrades to empty per-source without throwing, and never touches refs/RefMeta shape', () => {
|
|
738
594
|
assert.deepEqual(engineLeadingCommandTokens({}), [], 'a bare session with no accessors at all degrades to an empty enumeration');
|
|
739
595
|
const throwingExtButRealTemplate = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Run with:
|
|
1
|
+
// Run with: npm run test:serial
|
|
2
2
|
//
|
|
3
3
|
// BUG-REGRESSION (real, observed; surfaced during the crouter-web build, proven
|
|
4
4
|
// broker-side). After a revive resumes a previously-CLOSED pi session, the
|
|
@@ -29,19 +29,19 @@ import { mkdtempSync, rmSync } from 'node:fs';
|
|
|
29
29
|
import { tmpdir } from 'node:os';
|
|
30
30
|
import { dirname, join } from 'node:path';
|
|
31
31
|
import { fileURLToPath } from 'node:url';
|
|
32
|
-
import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '
|
|
33
|
-
import { CANVAS_EXTENSIONS } from '
|
|
34
|
-
import { buildBrokerSession, snapshotMessages } from '
|
|
35
|
-
import { createNode } from '
|
|
36
|
-
import { closeDb } from '
|
|
37
|
-
import { transcriptMarkdown } from '
|
|
32
|
+
import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../../runtime/broker-sdk.js';
|
|
33
|
+
import { CANVAS_EXTENSIONS } from '../../runtime/launch.js';
|
|
34
|
+
import { buildBrokerSession, snapshotMessages } from '../../runtime/broker.js';
|
|
35
|
+
import { createNode } from '../../canvas/canvas.js';
|
|
36
|
+
import { closeDb } from '../../canvas/db.js';
|
|
37
|
+
import { transcriptMarkdown } from '../../runtime/node-read.js';
|
|
38
38
|
// M-9 (broker.ts fault-and-die model gate): a boot with no cfg.model now calls
|
|
39
39
|
// the REAL SDK's modelRegistry.getAvailable() and faults if it's empty, which it
|
|
40
40
|
// always is on a host/CI runner with no authenticated provider. This test only
|
|
41
41
|
// exercises snapshot/history reconstruction, so it registers the same hermetic
|
|
42
42
|
// fake-but-authenticated model the C3 wiring tests use instead of depending on
|
|
43
43
|
// ambient host credentials (see broker-sdk-wiring's c3-custom-provider-ext.ts).
|
|
44
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
44
|
+
const HERE = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
45
45
|
const C3_EXT = join(HERE, 'fixtures', 'c3-custom-provider-ext.ts');
|
|
46
46
|
const realEngine = {
|
|
47
47
|
createAgentSessionServices,
|
|
@@ -66,7 +66,7 @@ function assistantMsg(text, stopReason = 'stop') {
|
|
|
66
66
|
timestamp: Date.now(),
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
-
// 30s
|
|
69
|
+
// 30s: this boot loads the REAL mandatory
|
|
70
70
|
// canvas extension set from TypeScript sources, and those extensions pull the
|
|
71
71
|
// crouter module graph through tsx for the first time in the process — ~6s of
|
|
72
72
|
// the ~9s local runtime, and 12.6s total on a hosted runner, which blew the
|