@north-light/crouter 0.3.172 → 0.3.174
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/runtime-selector.mjs +8 -1
- package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
- package/dist/api/client.d.ts +12 -21
- package/dist/api/client.js +22 -31
- package/dist/api/dto/broker-ops.d.ts +158 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/crons.d.ts +6 -0
- package/dist/api/dto/human.d.ts +7 -1
- package/dist/api/dto/inbox.d.ts +1 -71
- package/dist/api/dto/inbox.js +1 -9
- package/dist/api/dto/nodes.d.ts +6 -7
- package/dist/api/dto/reviews.d.ts +1 -11
- package/dist/api/routes.d.ts +7 -4
- package/dist/api/routes.js +8 -5
- package/dist/build-root.js +3 -3
- package/dist/builtin-memory/04-base-worker.md +1 -4
- package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
- package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
- package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
- package/dist/builtin-memory/advisor/council.md +1 -6
- package/dist/builtin-memory/design.md +2 -7
- package/dist/builtin-memory/development.md +9 -14
- package/dist/builtin-memory/internal/marketplaces.md +2 -6
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +2 -8
- package/dist/builtin-memory/internal/storage-tiers.md +1 -2
- package/dist/builtin-memory/testing.md +41 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +106 -177
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +55 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +60 -0
- package/dist/cli.js +2 -2
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
- package/dist/clients/attach/__tests__/context-message.test.js +16 -174
- package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
- package/dist/clients/attach/__tests__/diagram.test.js +2 -2
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
- package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
- package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
- package/dist/clients/attach/command.d.ts +2 -1
- package/dist/clients/attach/command.js +81 -76
- package/dist/clients/attach/input/capabilities.d.ts +27 -0
- package/dist/clients/attach/input/capabilities.js +96 -0
- package/dist/clients/attach/input/controller.d.ts +20 -182
- package/dist/clients/attach/input/controller.js +128 -537
- package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
- package/dist/clients/attach/input/overlay-owner.js +199 -0
- package/dist/clients/attach/overlays/file-review.d.ts +0 -4
- package/dist/clients/attach/overlays/file-review.js +13 -5
- package/dist/clients/attach/overlays/graph.js +2 -10
- package/dist/clients/attach/render/chat-view.d.ts +4 -3
- package/dist/clients/attach/render/chat-view.js +39 -33
- package/dist/clients/attach/render/group-activity.d.ts +1 -0
- package/dist/clients/attach/render/group-activity.js +20 -13
- package/dist/clients/attach/render/group-recap.js +12 -3
- package/dist/clients/attach/session/connection.js +9 -15
- package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
- package/dist/clients/attach/session/editor-inventory.js +7 -8
- package/dist/clients/attach/session/file-links.d.ts +13 -0
- package/dist/clients/attach/session/file-links.js +107 -0
- package/dist/clients/attach/session/frame.d.ts +3 -0
- package/dist/clients/attach/session/frame.js +10 -1
- package/dist/clients/attach/session/frames.js +2 -3
- package/dist/clients/attach/session/input-wiring.d.ts +4 -1
- package/dist/clients/attach/session/input-wiring.js +15 -14
- package/dist/clients/attach/session/mouse.d.ts +6 -1
- package/dist/clients/attach/session/mouse.js +8 -5
- package/dist/clients/attach/session/profile-files.js +18 -12
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/session/state-sync.js +1 -2
- package/dist/clients/attach/session/surface-host.d.ts +3 -2
- package/dist/clients/attach/session/surface-host.js +4 -4
- package/dist/clients/attach/slash/dispatch.d.ts +8 -31
- package/dist/clients/attach/slash/dispatch.js +34 -81
- package/dist/clients/attach/viewer.js +820 -860
- package/dist/clients/conversation/projection.d.ts +79 -0
- package/dist/clients/conversation/projection.js +341 -0
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
- package/dist/clients/inbox/controller.d.ts +0 -4
- package/dist/clients/inbox/controller.js +0 -2
- package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
- package/dist/clients/inbox/review/comments-client.d.ts +3 -2
- package/dist/clients/inbox/review/comments-client.js +12 -12
- package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
- package/dist/clients/inbox/review/companion-pane.js +86 -0
- package/dist/clients/inbox/review/document-surface.d.ts +182 -0
- package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
- package/dist/clients/inbox/review/frame.js +5 -4
- package/dist/clients/inbox/review/launch.d.ts +8 -8
- package/dist/clients/inbox/review/launch.js +52 -92
- package/dist/clients/inbox/review/nvim.d.ts +2 -0
- package/dist/clients/inbox/review/nvim.js +14 -12
- package/dist/clients/inbox/review/review-client.d.ts +12 -8
- package/dist/clients/inbox/review/review-client.js +46 -35
- package/dist/clients/inbox/review-adapter.d.ts +3 -10
- package/dist/clients/inbox/review-adapter.js +27 -19
- package/dist/clients/inbox/surface.d.ts +0 -4
- package/dist/clients/inbox/surface.js +0 -2
- package/dist/clients/surfaces/host.d.ts +11 -3
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
- package/dist/commands/__tests__/human.test.js +11 -322
- package/dist/commands/api-client.d.ts +5 -5
- package/dist/commands/api-client.js +6 -85
- package/dist/commands/canvas-browse.js +3 -29
- package/dist/commands/canvas-config.js +1 -1
- package/dist/commands/canvas-use.js +3 -3
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/cron.js +5 -1
- package/dist/commands/human/queue.d.ts +0 -4
- package/dist/commands/human/queue.js +7 -40
- package/dist/commands/memory/list.d.ts +14 -0
- package/dist/commands/memory/list.js +35 -31
- package/dist/commands/memory/read.d.ts +7 -0
- package/dist/commands/memory/read.js +14 -8
- package/dist/commands/node/bash.d.ts +1 -0
- package/dist/commands/node/bash.js +198 -0
- package/dist/commands/node/create.d.ts +23 -0
- package/dist/commands/node/create.js +207 -0
- package/dist/commands/node/inspect.d.ts +2 -0
- package/dist/commands/node/inspect.js +302 -0
- package/dist/commands/node/lifecycle.d.ts +4 -0
- package/dist/commands/node/lifecycle.js +415 -0
- package/dist/commands/node/message.d.ts +1 -0
- package/dist/commands/node/message.js +164 -0
- package/dist/commands/node/pyramid.d.ts +2 -0
- package/dist/commands/node/pyramid.js +79 -0
- package/dist/commands/node/subscription.d.ts +1 -0
- package/dist/commands/node/subscription.js +82 -0
- package/dist/commands/node/wait.d.ts +1 -0
- package/dist/commands/node/wait.js +159 -0
- package/dist/commands/node-lifecycle-revive.js +10 -57
- package/dist/commands/node.d.ts +0 -42
- package/dist/commands/node.js +11 -2065
- package/dist/commands/search.js +1 -1
- package/dist/commands/surface/node/cycle.d.ts +1 -0
- package/dist/commands/surface/node/cycle.js +83 -0
- package/dist/commands/surface/node/focus.d.ts +1 -0
- package/dist/commands/surface/node/focus.js +67 -0
- package/dist/commands/surface/node/id.d.ts +1 -0
- package/dist/commands/surface/node/id.js +38 -0
- package/dist/commands/surface/node/pin.d.ts +1 -0
- package/dist/commands/surface/node/pin.js +42 -0
- package/dist/commands/surface/node/placement.d.ts +46 -0
- package/dist/commands/surface/node/placement.js +124 -0
- package/dist/commands/surface-node.js +4 -1
- package/dist/commands/surface-reload.js +1 -2
- package/dist/commands/surface-tmux-spread.js +1 -1
- package/dist/commands/surface.js +5 -20
- package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
- package/dist/commands/sys/config.js +6 -6
- package/dist/commands/sys/logs.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
- package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
- package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
- package/dist/commands/sys/panels/dependencies-panel.js +80 -0
- package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
- package/dist/commands/sys/panels/keybindings-panel.js +703 -0
- package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
- package/dist/commands/sys/panels/keys-panel.js +60 -0
- package/dist/commands/sys/panels/models-panel.d.ts +77 -0
- package/dist/commands/sys/panels/models-panel.js +647 -0
- package/dist/commands/sys/panels/panel.d.ts +45 -0
- package/dist/commands/sys/panels/panel.js +137 -0
- package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
- package/dist/commands/sys/panels/plugins-panel.js +80 -0
- package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
- package/dist/commands/sys/panels/prefs-panel.js +85 -0
- package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
- package/dist/commands/sys/panels/provider-panel.js +538 -0
- package/dist/commands/sys/settings-shell.d.ts +55 -0
- package/dist/commands/sys/settings-shell.js +400 -0
- package/dist/commands/sys/settings.d.ts +2 -0
- package/dist/commands/sys/settings.js +31 -0
- package/dist/commands/sys/setup-core.d.ts +3 -33
- package/dist/commands/sys/setup-core.js +27 -78
- package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
- package/dist/commands/sys/setup-settings-runner.js +63 -0
- package/dist/commands/sys/setup-wizard.d.ts +26 -125
- package/dist/commands/sys/setup-wizard.js +209 -2473
- package/dist/commands/sys/setup.js +5 -7
- package/dist/commands/sys.js +3 -2
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
- package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
- package/dist/core/__tests__/broker-preflight.test.js +1 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
- package/dist/core/__tests__/canvas.test.js +2 -36
- package/dist/core/__tests__/close.test.js +14 -3
- package/dist/core/__tests__/context-intro.test.js +32 -143
- package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
- package/dist/core/__tests__/daemon-boot.test.js +2 -20
- package/dist/core/__tests__/daemon-wedge.test.js +1 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +4 -98
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
- package/dist/core/__tests__/helpers/broker-clients.js +0 -14
- package/dist/core/__tests__/helpers/harness.d.ts +0 -8
- package/dist/core/__tests__/helpers/harness.js +7 -87
- package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
- package/dist/core/__tests__/kickoff.test.js +1 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
- package/dist/core/__tests__/migration.test.js +35 -48
- package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
- package/dist/core/__tests__/passive-subscription.test.js +26 -49
- package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
- package/dist/core/__tests__/prune.test.js +94 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -32
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
- package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
- package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
- package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
- package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
- package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
- package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
- package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
- package/dist/core/__tests__/secrets.test.js +1 -7
- package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
- package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
- package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
- package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
- package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
- package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
- package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
- package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
- package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
- package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
- package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
- package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
- package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
- package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
- package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
- package/dist/core/__tests__/session-model.test.js +0 -18
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
- package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
- package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
- package/dist/core/broker-client/client.d.ts +2 -2
- package/dist/core/broker-client/client.js +4 -7
- package/dist/core/broker-client/transport-relay.d.ts +13 -19
- package/dist/core/broker-client/transport-relay.js +19 -34
- package/dist/core/broker-client/transport-socket.d.ts +2 -2
- package/dist/core/broker-client/transport-socket.js +9 -2
- package/dist/core/broker-client/transport.d.ts +7 -3
- package/dist/core/broker-client/transport.js +4 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -18
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
- package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
- package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
- package/dist/core/canvas/browse/app.d.ts +2 -17
- package/dist/core/canvas/browse/app.js +16 -88
- package/dist/core/canvas/browse/model.d.ts +0 -4
- package/dist/core/canvas/browse/model.js +1 -12
- package/dist/core/canvas/browse/render.js +6 -3
- package/dist/core/canvas/crons.d.ts +8 -5
- package/dist/core/canvas/crons.js +7 -6
- package/dist/core/canvas/extensions.d.ts +7 -3
- package/dist/core/canvas/extensions.js +16 -4
- package/dist/core/canvas/nav-model.d.ts +0 -4
- package/dist/core/canvas/nav-model.js +2 -14
- package/dist/core/canvas/node-order.d.ts +3 -0
- package/dist/core/canvas/node-order.js +12 -0
- package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
- package/dist/core/canvas/remote-canvas-source.js +8 -15
- package/dist/core/command.js +11 -4
- package/dist/core/config.js +3 -1
- package/dist/core/events/envelope.js +1 -1
- package/dist/core/events/read.js +7 -21
- package/dist/core/events/source.d.ts +0 -2
- package/dist/core/events/source.js +0 -16
- package/dist/core/events/types.d.ts +1 -1
- package/dist/core/fault-classifier.d.ts +1 -1
- package/dist/core/feed/passive.d.ts +0 -11
- package/dist/core/feed/passive.js +1 -62
- package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
- package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
- package/dist/core/keybindings/background-bash.js +3 -4
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/memory/inline-ref-grammar.js +3 -3
- package/dist/core/memory-resolver.d.ts +11 -25
- package/dist/core/memory-resolver.js +51 -33
- package/dist/core/model-routes.d.ts +15 -0
- package/dist/core/model-routes.js +12 -0
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/preview-registry.js +8 -9
- package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
- package/dist/core/review/realize.d.ts +0 -13
- package/dist/core/review/realize.js +0 -40
- package/dist/core/review/types.d.ts +1 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
- package/dist/core/runtime/bearings.js +1 -11
- package/dist/core/runtime/broker/client-registry.d.ts +33 -0
- package/dist/core/runtime/broker/client-registry.js +164 -0
- package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
- package/dist/core/runtime/broker/daemon-ops.js +49 -0
- package/dist/core/runtime/broker/event-projection.d.ts +42 -0
- package/dist/core/runtime/broker/event-projection.js +178 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
- package/dist/core/runtime/broker/fault-retry.js +277 -0
- package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
- package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
- package/dist/core/runtime/broker/inbox.d.ts +22 -0
- package/dist/core/runtime/broker/inbox.js +167 -0
- package/dist/core/runtime/broker/passive.d.ts +16 -0
- package/dist/core/runtime/broker/passive.js +44 -0
- package/dist/core/runtime/broker/read-ops.d.ts +23 -0
- package/dist/core/runtime/broker/read-ops.js +150 -0
- package/dist/core/runtime/broker/rebind.d.ts +74 -0
- package/dist/core/runtime/broker/rebind.js +211 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
- package/dist/core/runtime/broker/tool-groups.js +244 -0
- package/dist/core/runtime/broker-extension-render.d.ts +11 -0
- package/dist/core/runtime/broker-extension-render.js +181 -0
- package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
- package/dist/core/runtime/broker-persona-guidance.js +58 -0
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/broker-protocol.js +1 -1
- package/dist/core/runtime/broker.d.ts +5 -196
- package/dist/core/runtime/broker.js +276 -3059
- package/dist/core/runtime/canvas-extensions.js +11 -2
- package/dist/core/runtime/fault.js +1 -1
- package/dist/core/runtime/model-selection.d.ts +9 -0
- package/dist/core/runtime/model-selection.js +12 -0
- package/dist/core/runtime/model-swap.d.ts +3 -3
- package/dist/core/runtime/model-swap.js +33 -25
- package/dist/core/runtime/placement-tmux.d.ts +3 -14
- package/dist/core/runtime/placement-tmux.js +11 -80
- package/dist/core/runtime/placement.d.ts +4 -2
- package/dist/core/runtime/placement.js +7 -12
- package/dist/core/runtime/promote.d.ts +14 -1
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/reset.d.ts +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/runtime/spawn.d.ts +8 -0
- package/dist/core/runtime/spawn.js +36 -6
- package/dist/core/runtime/stop-guard.d.ts +4 -3
- package/dist/core/runtime/stop-guard.js +36 -18
- package/dist/core/runtime/stop-signals.d.ts +4 -1
- package/dist/core/runtime/stream-watchdog.js +4 -5
- package/dist/core/runtime/structured-output.d.ts +15 -2
- package/dist/core/runtime/structured-output.js +35 -12
- package/dist/core/runtime/tmux-bindings.d.ts +25 -0
- package/dist/core/runtime/tmux-bindings.js +682 -0
- package/dist/core/runtime/tmux-chrome.d.ts +2 -1
- package/dist/core/runtime/tmux-chrome.js +3 -2
- package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
- package/dist/core/runtime/tmux-driver.js +598 -0
- package/dist/core/runtime/view-socket.d.ts +14 -0
- package/dist/core/runtime/view-socket.js +83 -0
- package/dist/core/session-model/session-state.d.ts +1 -2
- package/dist/core/session-model/session-state.js +5 -8
- package/dist/core/spawn.d.ts +1 -1
- package/dist/core/spawn.js +2 -2
- package/dist/core/substrate/gate.d.ts +1 -1
- package/dist/core/substrate/on-read-pure.d.ts +7 -0
- package/dist/core/substrate/on-read-pure.js +272 -0
- package/dist/core/termrender/termrender.js +32 -2
- package/dist/core/user-settings.d.ts +23 -1
- package/dist/core/user-settings.js +18 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
- package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
- package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
- package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
- package/dist/daemon/api/bridge.js +40 -81
- package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
- package/dist/daemon/api/handlers/broker-ops.js +383 -0
- package/dist/daemon/api/handlers/crons.js +9 -4
- package/dist/daemon/api/handlers/files.js +6 -7
- package/dist/daemon/api/handlers/inbox.js +2 -340
- package/dist/daemon/api/handlers/nodes.d.ts +10 -1
- package/dist/daemon/api/handlers/nodes.js +74 -39
- package/dist/daemon/api/handlers/review-comments.js +5 -1
- package/dist/daemon/api/handlers/reviews.js +0 -19
- package/dist/daemon/api/map.js +25 -4
- package/dist/daemon/api/router.js +2 -3
- package/dist/daemon/api/server.js +5 -7
- package/dist/daemon/cron-run.d.ts +4 -0
- package/dist/daemon/cron-run.js +30 -13
- package/dist/daemon/crtrd.d.ts +3 -58
- package/dist/daemon/crtrd.js +28 -1244
- package/dist/daemon/manage.js +0 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
- package/dist/daemon/reconcilers/broker-supervision.js +549 -0
- package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
- package/dist/daemon/reconcilers/cron-lane.js +32 -0
- package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
- package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
- package/dist/daemon/review/finish.js +2 -5
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
- package/dist/pi-extensions/broker-local.d.ts +20 -0
- package/dist/pi-extensions/broker-local.js +89 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
- package/dist/pi-extensions/canvas-context-intro.js +22 -11
- package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
- package/dist/pi-extensions/canvas-goal-capture.js +7 -12
- package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
- package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
- package/dist/pi-extensions/canvas-passive-context.js +22 -18
- package/dist/pi-extensions/canvas-recap.d.ts +2 -2
- package/dist/pi-extensions/canvas-recap.js +48 -21
- package/dist/pi-extensions/canvas-review-boundary.js +10 -4
- package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
- package/dist/pi-extensions/canvas-stophook.js +149 -431
- package/dist/pi-extensions/canvas-structured-output.js +52 -30
- package/dist/pi-extensions/envelope-merge.d.ts +13 -0
- package/dist/pi-extensions/envelope-merge.js +29 -0
- package/dist/shared/working-activity.d.ts +3 -2
- package/dist/shared/working-activity.js +3 -2
- package/dist/types.d.ts +6 -5
- package/dist/types.js +2 -2
- package/docs/compat/hearth-crtr-v1.md +4 -12
- package/docs/compat/hearth-crtr-v2.md +3 -11
- package/docs/compat/hearth-crtr-v3.md +4 -12
- package/docs/compat/hearth-crtr-v4.md +3 -11
- package/docs/compat/hearth-crtr-v5.md +3 -11
- package/docs/public-api.md +3 -7
- package/package.json +7 -49
- package/runtime.lock.json +2766 -14533
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
- package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
- package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
- package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
- package/dist/clients/conversation/conversation.d.ts +0 -65
- package/dist/clients/conversation/conversation.js +0 -318
- package/dist/clients/conversation/frames.d.ts +0 -30
- package/dist/clients/conversation/frames.js +0 -52
- package/dist/clients/conversation/region.d.ts +0 -51
- package/dist/clients/conversation/region.js +0 -265
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
- package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
- package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
- package/dist/clients/inbox/review/columns.d.ts +0 -22
- package/dist/clients/inbox/review/columns.js +0 -40
- package/dist/clients/inbox/review/composition.d.ts +0 -60
- package/dist/clients/inbox/review/composition.js +0 -278
- package/dist/clients/inbox/review/document-region.d.ts +0 -120
- package/dist/clients/surfaces/region.d.ts +0 -16
- package/dist/clients/web/__tests__/push-engine.test.js +0 -158
- package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
- package/dist/clients/web/__tests__/push-registry.test.js +0 -177
- package/dist/clients/web/dev-server.d.ts +0 -7
- package/dist/clients/web/dev-server.js +0 -46
- package/dist/clients/web/events.d.ts +0 -19
- package/dist/clients/web/events.js +0 -163
- package/dist/clients/web/push-engine.d.ts +0 -44
- package/dist/clients/web/push-engine.js +0 -125
- package/dist/clients/web/push-registry.d.ts +0 -85
- package/dist/clients/web/push-registry.js +0 -373
- package/dist/clients/web/server.d.ts +0 -19
- package/dist/clients/web/server.js +0 -661
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
- package/dist/clients/web/web-client/shared/protocol.js +0 -8
- package/dist/clients/web/web-cmd.d.ts +0 -2
- package/dist/clients/web/web-cmd.js +0 -141
- package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
- package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
- package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
- package/dist/commands/__tests__/canvas-config.test.js +0 -107
- package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
- package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
- package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
- package/dist/commands/__tests__/search-contents.test.js +0 -52
- package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/lint.test.js +0 -15
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
- package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
- package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
- package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
- package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
- package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
- package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
- package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
- package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
- package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
- package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
- package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
- package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
- package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
- package/dist/core/__tests__/finalization-migration.test.js +0 -38
- package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
- package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
- package/dist/core/__tests__/fork.test.d.ts +0 -1
- package/dist/core/__tests__/fork.test.js +0 -108
- package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
- package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
- package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
- package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
- package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
- package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
- package/dist/core/__tests__/full/cascade-close.test.js +0 -240
- package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/detach-focus.test.js +0 -126
- package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
- package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
- package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
- package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.js +0 -60
- package/dist/core/__tests__/model-routes.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes.test.js +0 -41
- package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-identity.test.js +0 -61
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
- package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
- package/dist/core/__tests__/prune-to-limit.test.js +0 -126
- package/dist/core/__tests__/reset.test.d.ts +0 -1
- package/dist/core/__tests__/reset.test.js +0 -69
- package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
- package/dist/core/__tests__/steer-note.test.d.ts +0 -1
- package/dist/core/__tests__/steer-note.test.js +0 -41
- package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
- package/dist/core/__tests__/subcommand-tier.test.js +0 -99
- package/dist/core/__tests__/subscription-delivery.test.js +0 -211
- package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
- package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
- package/dist/core/__tests__/tmux-surface.test.js +0 -484
- package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
- package/dist/core/__tests__/wake-bearings.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
- package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
- package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
- package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
- package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
- package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
- package/dist/core/canvas/remote-event-stream.d.ts +0 -24
- package/dist/core/canvas/remote-event-stream.js +0 -94
- package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
- package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
- package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
- package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
- package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
- package/dist/core/human/__tests__/visible-paths.test.js +0 -28
- package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
- package/dist/core/review/__tests__/project.test.d.ts +0 -1
- package/dist/core/review/__tests__/project.test.js +0 -71
- package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
- package/dist/core/runtime/tmux.js +0 -1314
- package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
- package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/inbox.test.js +0 -489
- package/dist/web-client/apple-touch-icon.png +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
- package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
- package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
- package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
- package/dist/web-client/icon-192.png +0 -0
- package/dist/web-client/icon-512.png +0 -0
- package/dist/web-client/icon-maskable-512.png +0 -0
- package/dist/web-client/index.html +0 -17
- package/dist/web-client/manifest.webmanifest +0 -1
- package/dist/web-client/sw.js +0 -1
- /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
- /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
- /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
- /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
- /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
- /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
- /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
- /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
- /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
- /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
- /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
- /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
- /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
- /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
- /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
- /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
- /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
|
@@ -1,85 +1,12 @@
|
|
|
1
|
-
// Ticket
|
|
2
|
-
// v1, inbox-contract.md §A). This public ticket-serving resource enumerates,
|
|
3
|
-
// reads, responds to, and cancels tickets while preserving its product DTOs.
|
|
4
|
-
//
|
|
5
|
-
// Every ticket is addressed on the wire by an opaque, stable id: lowercase
|
|
6
|
-
// SHA-256 hex of `canonicalRoot + "\0" + ticketBasename`. The wire never exposes
|
|
7
|
-
// a ticket directory, review file/output, claim owner/heartbeat, or other host
|
|
8
|
-
// path or process metadata. The daemon's shared ticket finish path owns claims,
|
|
9
|
-
// terminal publication, and bridge delivery.
|
|
1
|
+
// Ticket-inbox listing for the attached terminal viewer.
|
|
10
2
|
import { createHash } from 'node:crypto';
|
|
11
|
-
import {
|
|
12
|
-
import { basename, resolve } from 'node:path';
|
|
13
|
-
import { ApiError } from '../../../api/index.js';
|
|
14
|
-
import { deckPath, readJson, reviewPath } from '../../../core/human/convention.js';
|
|
15
|
-
import { parseDeck } from '../../../core/human/deck-schema.js';
|
|
3
|
+
import { realpathSync } from 'node:fs';
|
|
16
4
|
import { ticketsRoot } from '../../../core/human/root.js';
|
|
17
5
|
import { scanInbox } from '../../../core/human/scan.js';
|
|
18
|
-
import { readTicketResult } from '../../../core/human/tickets.js';
|
|
19
|
-
import { getReviewByBridge } from '../../../core/review/store.js';
|
|
20
|
-
import { ReviewOperationError } from '../../../core/review/types.js';
|
|
21
|
-
import { cancelHumanTicket, resolveDeckTicket } from '../../human/finish.js';
|
|
22
|
-
import { cancelReview } from '../../review/finish.js';
|
|
23
6
|
import { filterTerminalReviewTickets } from '../../../core/review/ticket-filter.js';
|
|
24
|
-
const DEFAULT_CANCEL_REASON = 'Canceled from the inbox.';
|
|
25
|
-
const CANCEL_REASON_MAX = 1000;
|
|
26
|
-
const TICKET_ID_PATTERN = /^[a-f0-9]{64}$/;
|
|
27
|
-
// ===========================================================================
|
|
28
|
-
// Opaque ticket id resolution
|
|
29
|
-
// ===========================================================================
|
|
30
|
-
/** Opaque ids hash the canonical derived tickets root and ticket basename. */
|
|
31
7
|
function ticketHash(canonicalRoot, ticketBasename) {
|
|
32
8
|
return createHash('sha256').update(`${canonicalRoot}\0${ticketBasename}`, 'utf8').digest('hex');
|
|
33
9
|
}
|
|
34
|
-
/** Resolve an opaque id against the single tickets root. Includes terminal
|
|
35
|
-
* tickets so a stale client receives the stable already-resolved response. */
|
|
36
|
-
function resolveTicket(ticketId) {
|
|
37
|
-
let canonicalRoot;
|
|
38
|
-
try {
|
|
39
|
-
canonicalRoot = realpathSync(ticketsRoot());
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
let entries;
|
|
45
|
-
try {
|
|
46
|
-
entries = readdirSync(canonicalRoot);
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
for (const entry of entries) {
|
|
52
|
-
if (ticketHash(canonicalRoot, entry) !== ticketId)
|
|
53
|
-
continue;
|
|
54
|
-
const candidate = resolve(canonicalRoot, entry);
|
|
55
|
-
let canonicalDir;
|
|
56
|
-
try {
|
|
57
|
-
if (!statSync(candidate).isDirectory())
|
|
58
|
-
continue;
|
|
59
|
-
canonicalDir = realpathSync(candidate);
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (resolve(canonicalDir, '..') !== canonicalRoot || basename(canonicalDir) !== entry)
|
|
65
|
-
continue;
|
|
66
|
-
if (existsSync(deckPath(canonicalDir)))
|
|
67
|
-
return { nodeId: entry, dir: canonicalDir, kind: 'deck' };
|
|
68
|
-
if (existsSync(reviewPath(canonicalDir)))
|
|
69
|
-
return { nodeId: entry, dir: canonicalDir, kind: 'review' };
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
function requireTicketId(params) {
|
|
74
|
-
const ticketId = params['ticket_id'];
|
|
75
|
-
if (ticketId === undefined || !TICKET_ID_PATTERN.test(ticketId)) {
|
|
76
|
-
throw new ApiError(400, 'invalid_request', 'invalid ticket id');
|
|
77
|
-
}
|
|
78
|
-
return ticketId;
|
|
79
|
-
}
|
|
80
|
-
// ===========================================================================
|
|
81
|
-
// Projections — humanloop canonical shapes → wire DTOs
|
|
82
|
-
// ===========================================================================
|
|
83
10
|
function toDeckSourceDTO(source) {
|
|
84
11
|
const dto = {};
|
|
85
12
|
if (source.sessionName !== undefined)
|
|
@@ -90,39 +17,6 @@ function toDeckSourceDTO(source) {
|
|
|
90
17
|
dto.blockedSince = source.blockedSince;
|
|
91
18
|
return dto;
|
|
92
19
|
}
|
|
93
|
-
function toOptionDTO(option) {
|
|
94
|
-
const dto = { id: option.id, label: option.label };
|
|
95
|
-
if (option.description !== undefined)
|
|
96
|
-
dto.description = option.description;
|
|
97
|
-
return dto;
|
|
98
|
-
}
|
|
99
|
-
function toInteractionDTO(interaction) {
|
|
100
|
-
const dto = {
|
|
101
|
-
id: interaction.id,
|
|
102
|
-
title: interaction.title,
|
|
103
|
-
subtitle: interaction.subtitle,
|
|
104
|
-
options: interaction.options.map(toOptionDTO),
|
|
105
|
-
};
|
|
106
|
-
if (interaction.body !== undefined)
|
|
107
|
-
dto.body = interaction.body;
|
|
108
|
-
if (interaction.multiSelect !== undefined)
|
|
109
|
-
dto.multiSelect = interaction.multiSelect;
|
|
110
|
-
if (interaction.allowFreetext !== undefined)
|
|
111
|
-
dto.allowFreetext = interaction.allowFreetext;
|
|
112
|
-
if (interaction.freetextLabel !== undefined)
|
|
113
|
-
dto.freetextLabel = interaction.freetextLabel;
|
|
114
|
-
if (interaction.kind !== undefined)
|
|
115
|
-
dto.kind = interaction.kind;
|
|
116
|
-
if (interaction.preAnswered !== undefined)
|
|
117
|
-
dto.preAnswered = interaction.preAnswered;
|
|
118
|
-
return dto;
|
|
119
|
-
}
|
|
120
|
-
function toDeckDTO(deck) {
|
|
121
|
-
const dto = { title: deck.title, interactions: deck.interactions.map(toInteractionDTO) };
|
|
122
|
-
if (deck.source !== undefined)
|
|
123
|
-
dto.source = toDeckSourceDTO(deck.source);
|
|
124
|
-
return dto;
|
|
125
|
-
}
|
|
126
20
|
function toTicketSummaryDTO(item) {
|
|
127
21
|
const ticket_id = ticketHash(realpathSync(ticketsRoot()), item.id);
|
|
128
22
|
const source = toDeckSourceDTO(item.source);
|
|
@@ -149,246 +43,14 @@ function toTicketSummaryDTO(item) {
|
|
|
149
43
|
dto.interaction_kind = item.interactionKind;
|
|
150
44
|
return dto;
|
|
151
45
|
}
|
|
152
|
-
// ===========================================================================
|
|
153
|
-
// Request-body validation — structural only. Semantic response↔deck
|
|
154
|
-
// validation (option ids, single/multi-select shape, freetext permission,
|
|
155
|
-
// option comments, required notify acknowledgement) belongs to the ticket
|
|
156
|
-
// store via the daemon finish path; a structural violation here is
|
|
157
|
-
// `invalid_request`, a semantic rejection there is `invalid_ticket_response`.
|
|
158
|
-
// ===========================================================================
|
|
159
|
-
function isPlainObject(value) {
|
|
160
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
161
|
-
}
|
|
162
|
-
function requireNoExtraKeys(obj, allowed) {
|
|
163
|
-
for (const key of Object.keys(obj)) {
|
|
164
|
-
if (!allowed.includes(key))
|
|
165
|
-
throw new ApiError(400, 'invalid_request', `unexpected field: ${key}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
const RESPONSE_FIELDS = ['id', 'selectedOptionId', 'selectedOptionIds', 'freetext', 'optionComments'];
|
|
169
|
-
function validateInteractionResponse(raw) {
|
|
170
|
-
if (!isPlainObject(raw))
|
|
171
|
-
throw new ApiError(400, 'invalid_request', 'each response must be an object');
|
|
172
|
-
requireNoExtraKeys(raw, RESPONSE_FIELDS);
|
|
173
|
-
const { id, selectedOptionId, selectedOptionIds, freetext, optionComments } = raw;
|
|
174
|
-
if (typeof id !== 'string' || id === '') {
|
|
175
|
-
throw new ApiError(400, 'invalid_request', 'response.id must be a nonempty string');
|
|
176
|
-
}
|
|
177
|
-
const response = { id };
|
|
178
|
-
if (selectedOptionId !== undefined) {
|
|
179
|
-
if (typeof selectedOptionId !== 'string') {
|
|
180
|
-
throw new ApiError(400, 'invalid_request', 'response.selectedOptionId must be a string');
|
|
181
|
-
}
|
|
182
|
-
response.selectedOptionId = selectedOptionId;
|
|
183
|
-
}
|
|
184
|
-
if (selectedOptionIds !== undefined) {
|
|
185
|
-
if (!Array.isArray(selectedOptionIds) || !selectedOptionIds.every((v) => typeof v === 'string')) {
|
|
186
|
-
throw new ApiError(400, 'invalid_request', 'response.selectedOptionIds must be a string array');
|
|
187
|
-
}
|
|
188
|
-
response.selectedOptionIds = selectedOptionIds;
|
|
189
|
-
}
|
|
190
|
-
if (freetext !== undefined) {
|
|
191
|
-
if (typeof freetext !== 'string')
|
|
192
|
-
throw new ApiError(400, 'invalid_request', 'response.freetext must be a string');
|
|
193
|
-
response.freetext = freetext;
|
|
194
|
-
}
|
|
195
|
-
if (optionComments !== undefined) {
|
|
196
|
-
if (!isPlainObject(optionComments) || !Object.values(optionComments).every((v) => typeof v === 'string')) {
|
|
197
|
-
throw new ApiError(400, 'invalid_request', 'response.optionComments must be a string map');
|
|
198
|
-
}
|
|
199
|
-
response.optionComments = optionComments;
|
|
200
|
-
}
|
|
201
|
-
return response;
|
|
202
|
-
}
|
|
203
|
-
function validateRespondRequest(raw) {
|
|
204
|
-
if (!isPlainObject(raw))
|
|
205
|
-
throw new ApiError(400, 'invalid_request', 'respond body is required');
|
|
206
|
-
requireNoExtraKeys(raw, ['responses']);
|
|
207
|
-
if (!Array.isArray(raw['responses']))
|
|
208
|
-
throw new ApiError(400, 'invalid_request', '`responses` must be an array');
|
|
209
|
-
return { responses: raw['responses'].map(validateInteractionResponse) };
|
|
210
|
-
}
|
|
211
|
-
function validateCancelRequest(raw) {
|
|
212
|
-
if (raw === undefined)
|
|
213
|
-
return {};
|
|
214
|
-
if (!isPlainObject(raw))
|
|
215
|
-
throw new ApiError(400, 'invalid_request', 'cancel body must be an object');
|
|
216
|
-
requireNoExtraKeys(raw, ['reason']);
|
|
217
|
-
if (raw['reason'] === undefined)
|
|
218
|
-
return {};
|
|
219
|
-
const reason = raw['reason'];
|
|
220
|
-
if (typeof reason !== 'string')
|
|
221
|
-
throw new ApiError(400, 'invalid_request', '`reason` must be a string');
|
|
222
|
-
if (reason.trim() === '' || reason.length > CANCEL_REASON_MAX) {
|
|
223
|
-
throw new ApiError(400, 'invalid_request', '`reason` must be nonempty after trim and at most 1000 characters');
|
|
224
|
-
}
|
|
225
|
-
return { reason };
|
|
226
|
-
}
|
|
227
|
-
// ===========================================================================
|
|
228
|
-
// GET /v1/human/inbox — enumerate
|
|
229
|
-
// ===========================================================================
|
|
230
46
|
function handleList() {
|
|
231
47
|
const items = filterTerminalReviewTickets(scanInbox());
|
|
232
|
-
// `blocked_since` is an RFC 3339 timestamp that may carry a non-`Z` offset;
|
|
233
|
-
// two offsets are not lexically comparable (`+14:00` can sort after `Z`
|
|
234
|
-
// while naming an earlier instant), so sort by parsed instant and use the
|
|
235
|
-
// ticket id only to break an exact tie.
|
|
236
48
|
const tickets = items.map(toTicketSummaryDTO).sort((a, b) => {
|
|
237
49
|
const byTime = Date.parse(b.blocked_since) - Date.parse(a.blocked_since);
|
|
238
50
|
return byTime !== 0 ? byTime : a.ticket_id.localeCompare(b.ticket_id);
|
|
239
51
|
});
|
|
240
52
|
return { status: 200, body: { tickets } };
|
|
241
53
|
}
|
|
242
|
-
// ===========================================================================
|
|
243
|
-
// GET /v1/human/inbox/:ticket_id — read a pending deck
|
|
244
|
-
// ===========================================================================
|
|
245
|
-
function handleGetDeck(ctx) {
|
|
246
|
-
const ticketId = requireTicketId(ctx.params);
|
|
247
|
-
const resolved = resolveTicket(ticketId);
|
|
248
|
-
if (resolved === null)
|
|
249
|
-
throw new ApiError(404, 'ticket_not_found', 'no matching ticket');
|
|
250
|
-
if (resolved.kind === 'review') {
|
|
251
|
-
throw new ApiError(409, 'ticket_kind_unsupported', 'review tickets have no v1 read operation');
|
|
252
|
-
}
|
|
253
|
-
if (readTicketResult(resolved.dir) !== null) {
|
|
254
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
255
|
-
}
|
|
256
|
-
// A malformed stored ticket is omitted from enumeration by `scanInbox`; if
|
|
257
|
-
// independently reached during a race (or a ticket is mutated on disk after
|
|
258
|
-
// enumeration), `parseDeck` throws a plain Error whose message can carry a
|
|
259
|
-
// `bodyPath` value or another host filesystem path (e.g. "bodyPath '/etc/
|
|
260
|
-
// passwd' escapes the deck directory"). That message must never reach the
|
|
261
|
-
// wire, so it is never allowed to fall through to the router's generic
|
|
262
|
-
// mapper unsanitized — humanloop validation itself is never weakened to
|
|
263
|
-
// serve unvalidated content, only its failure message is sanitized.
|
|
264
|
-
let deck;
|
|
265
|
-
try {
|
|
266
|
-
deck = parseDeck(deckPath(resolved.dir));
|
|
267
|
-
}
|
|
268
|
-
catch {
|
|
269
|
-
throw new ApiError(500, 'internal', 'the ticket could not be read');
|
|
270
|
-
}
|
|
271
|
-
return { status: 200, body: { ticket_id: ticketId, kind: 'deck', deck: toDeckDTO(deck) } };
|
|
272
|
-
}
|
|
273
|
-
// ===========================================================================
|
|
274
|
-
// POST /v1/human/inbox/:ticket_id/respond — submit
|
|
275
|
-
// ===========================================================================
|
|
276
|
-
// The exhaustive set of messages the ticket store's response validator throws
|
|
277
|
-
// for a genuine response-shape
|
|
278
|
-
// rejection — duplicate/unknown interaction id, invalid single/multi-select
|
|
279
|
-
// shape, disallowed freetext, invalid option comments, or a missing required
|
|
280
|
-
// notify acknowledgement. None of these ever carry a filesystem path (only
|
|
281
|
-
// client-supplied interaction ids), so their message is safe to forward
|
|
282
|
-
// verbatim as `invalid_ticket_response`. Any other failure — a malformed
|
|
283
|
-
// stored deck, a lock/dispatch/filesystem error — is not a response-shape
|
|
284
|
-
// problem and must not be mislabeled or leak its cause; it is sanitized to
|
|
285
|
-
// `500 internal`.
|
|
286
|
-
const RESPONSE_VALIDATION_MESSAGE_PATTERNS = [
|
|
287
|
-
/^response does not match a unique deck interaction: /,
|
|
288
|
-
/^invalid single-select response for /,
|
|
289
|
-
/^invalid multi-select response for /,
|
|
290
|
-
/^freetext is not allowed for /,
|
|
291
|
-
/^invalid option comments for /,
|
|
292
|
-
/^notification requires an explicit acknowledgement: /,
|
|
293
|
-
];
|
|
294
|
-
function isResponseValidationError(err) {
|
|
295
|
-
return err instanceof Error && RESPONSE_VALIDATION_MESSAGE_PATTERNS.some((pattern) => pattern.test(err.message));
|
|
296
|
-
}
|
|
297
|
-
function coerceSingleSelect(responses, dir) {
|
|
298
|
-
const deck = readJson(deckPath(dir));
|
|
299
|
-
if (deck === null)
|
|
300
|
-
return responses;
|
|
301
|
-
const multiSelect = new Map(deck.interactions.map((interaction) => [interaction.id, interaction.multiSelect === true]));
|
|
302
|
-
return responses.map((response) => {
|
|
303
|
-
if (multiSelect.get(response.id) === true || response.selectedOptionId !== undefined || response.selectedOptionIds?.length !== 1)
|
|
304
|
-
return response;
|
|
305
|
-
const { selectedOptionIds: _selectedOptionIds, ...rest } = response;
|
|
306
|
-
return { ...rest, selectedOptionId: response.selectedOptionIds[0] };
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
async function handleRespond(ctx) {
|
|
310
|
-
const ticketId = requireTicketId(ctx.params);
|
|
311
|
-
const request = validateRespondRequest(ctx.body);
|
|
312
|
-
const resolved = resolveTicket(ticketId);
|
|
313
|
-
if (resolved === null)
|
|
314
|
-
throw new ApiError(404, 'ticket_not_found', 'no matching ticket');
|
|
315
|
-
if (resolved.kind === 'review') {
|
|
316
|
-
throw new ApiError(409, 'ticket_kind_unsupported', 'review tickets submit through POST /v1/human/reviews/:id/submit');
|
|
317
|
-
}
|
|
318
|
-
if (readTicketResult(resolved.dir) !== null) {
|
|
319
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
320
|
-
}
|
|
321
|
-
try {
|
|
322
|
-
const result = await resolveDeckTicket(resolved.nodeId, coerceSingleSelect(request.responses, resolved.dir));
|
|
323
|
-
if (result.kind !== 'deck')
|
|
324
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
325
|
-
return { status: 200, body: result };
|
|
326
|
-
}
|
|
327
|
-
catch (error) {
|
|
328
|
-
// The daemon's terminal errors are public protocol outcomes: preserve both
|
|
329
|
-
// their code and message so Northlight can distinguish conflict from a
|
|
330
|
-
// recorded-but-undelivered answer.
|
|
331
|
-
if (error instanceof ApiError)
|
|
332
|
-
throw error;
|
|
333
|
-
if (isResponseValidationError(error)) {
|
|
334
|
-
throw new ApiError(400, 'invalid_ticket_response', error.message);
|
|
335
|
-
}
|
|
336
|
-
throw new ApiError(500, 'internal', 'the ticket could not be finalized');
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
// ===========================================================================
|
|
340
|
-
// POST /v1/human/inbox/:ticket_id/cancel — cancel
|
|
341
|
-
// ===========================================================================
|
|
342
|
-
async function handleCancel(ctx) {
|
|
343
|
-
const ticketId = requireTicketId(ctx.params);
|
|
344
|
-
const request = validateCancelRequest(ctx.body);
|
|
345
|
-
const resolved = resolveTicket(ticketId);
|
|
346
|
-
if (resolved === null)
|
|
347
|
-
throw new ApiError(404, 'ticket_not_found', 'no matching ticket');
|
|
348
|
-
try {
|
|
349
|
-
if (resolved.kind === 'review') {
|
|
350
|
-
const review = getReviewByBridge(resolved.nodeId);
|
|
351
|
-
if (review !== null) {
|
|
352
|
-
if (review.state === 'approved') {
|
|
353
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
354
|
-
}
|
|
355
|
-
const finished = await cancelReview(review.review_id, {
|
|
356
|
-
reason: request.reason ?? DEFAULT_CANCEL_REASON,
|
|
357
|
-
actor: 'human',
|
|
358
|
-
});
|
|
359
|
-
if (finished.outcome === 'already_settled') {
|
|
360
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
361
|
-
}
|
|
362
|
-
if (finished.ticket_result?.kind !== 'canceled') {
|
|
363
|
-
throw new Error('canonical review cancellation did not produce a ticket result');
|
|
364
|
-
}
|
|
365
|
-
return { status: 200, body: finished.ticket_result };
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
const result = await cancelHumanTicket(resolved.nodeId, {
|
|
369
|
-
reason: request.reason ?? DEFAULT_CANCEL_REASON,
|
|
370
|
-
actor: 'human',
|
|
371
|
-
});
|
|
372
|
-
if (result.kind !== 'canceled')
|
|
373
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
374
|
-
return { status: 200, body: result };
|
|
375
|
-
}
|
|
376
|
-
catch (error) {
|
|
377
|
-
if (error instanceof ApiError)
|
|
378
|
-
throw error;
|
|
379
|
-
// Review errors are canonical lifecycle vocabulary, not ticket protocol.
|
|
380
|
-
// A concurrent terminal winner is the same public ticket conflict.
|
|
381
|
-
if (error instanceof ReviewOperationError) {
|
|
382
|
-
throw new ApiError(409, 'ticket_already_resolved', 'ticket was already resolved');
|
|
383
|
-
}
|
|
384
|
-
// A lock/filesystem/delivery failure is not a request-shape problem; do
|
|
385
|
-
// not leak its cause through the generic router mapper.
|
|
386
|
-
throw new ApiError(500, 'internal', 'the ticket could not be canceled');
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
54
|
export const inboxRoutes = [
|
|
390
55
|
{ method: 'GET', pattern: '/v1/human/inbox', handler: handleList },
|
|
391
|
-
{ method: 'GET', pattern: '/v1/human/inbox/:ticket_id', handler: handleGetDeck },
|
|
392
|
-
{ method: 'POST', pattern: '/v1/human/inbox/:ticket_id/respond', handler: handleRespond },
|
|
393
|
-
{ method: 'POST', pattern: '/v1/human/inbox/:ticket_id/cancel', handler: handleCancel },
|
|
394
56
|
];
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ModelRegistryLike } from '../../../core/model-routes.js';
|
|
2
|
+
import type { HandlerResult, RequestContext, RouteTable } from '../router.js';
|
|
3
|
+
interface NodeHandlerDeps {
|
|
4
|
+
modelRegistry?: ModelRegistryLike;
|
|
5
|
+
}
|
|
6
|
+
export declare function handleCreate(ctx: RequestContext, deps?: NodeHandlerDeps): Promise<HandlerResult>;
|
|
7
|
+
export declare function handlePromote(ctx: RequestContext, deps?: NodeHandlerDeps): Promise<HandlerResult>;
|
|
8
|
+
export declare function handleYield(ctx: RequestContext, deps?: NodeHandlerDeps): Promise<HandlerResult>;
|
|
9
|
+
export declare function handleConfig(ctx: RequestContext, deps?: NodeHandlerDeps): Promise<HandlerResult>;
|
|
2
10
|
export declare const nodeRoutes: RouteTable;
|
|
11
|
+
export {};
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
// `{id}` is the target node.
|
|
9
9
|
import { readdirSync } from 'node:fs';
|
|
10
10
|
import { appendSituationalContext, closeNode, getNode, listNodes, nowIso, reviveNode, } from '../../../index.js';
|
|
11
|
-
import { forkNode, spawnChild } from '../../../core/runtime/spawn.js';
|
|
11
|
+
import { assertLaunchModelRegistered, forkNode, resolveProfileId, spawnChild } from '../../../core/runtime/spawn.js';
|
|
12
12
|
import { childrenOf, subscribersOf, subscriptionsOf, setMessageWait, updateNode } from '../../../core/canvas/canvas.js';
|
|
13
13
|
import { subtreeIds } from '../../../core/canvas/nav-model.js';
|
|
14
14
|
import { contextDir, reportsDir } from '../../../core/canvas/paths.js';
|
|
15
15
|
import { nodeArtifacts } from '../../../core/canvas/history.js';
|
|
16
16
|
import { readNodeSession, readNodeSnapshot, transcriptMarkdown } from '../../../core/runtime/node-read.js';
|
|
17
17
|
import { reviveAll } from '../../../core/runtime/revive-all.js';
|
|
18
|
-
import { promote, requestYield } from '../../../core/runtime/promote.js';
|
|
18
|
+
import { promote, requestYield, reshapeNode } from '../../../core/runtime/promote.js';
|
|
19
19
|
import { recycleNode } from '../../../core/runtime/recycle.js';
|
|
20
20
|
import { relaunchRoot } from '../../../core/runtime/reset.js';
|
|
21
21
|
import { assertReopenGate } from '../../../core/runtime/reopen.js';
|
|
@@ -24,6 +24,7 @@ import { hasRoadmap, seedRoadmap } from '../../../core/runtime/roadmap.js';
|
|
|
24
24
|
import { renameWindow } from '../../../core/runtime/placement.js';
|
|
25
25
|
import { readMergedLaunchConfig } from '../../../core/config.js';
|
|
26
26
|
import { buildLaunchSpec, isProviderPinnedModelToken, normalizeModel } from '../../../core/runtime/launch.js';
|
|
27
|
+
import { modelRequestFromConfig } from '../../../core/model-routes.js';
|
|
27
28
|
import { BrokerUnreachableError } from '../../../core/runtime/broker-request.js';
|
|
28
29
|
import { isBrokerLive, persistDormantModel, setModelLive } from '../../../core/runtime/model-swap.js';
|
|
29
30
|
import { writeOutputSchema } from '../../../core/runtime/structured-output.js';
|
|
@@ -142,7 +143,23 @@ function warmRequestFor(req) {
|
|
|
142
143
|
name: req.name ?? null,
|
|
143
144
|
};
|
|
144
145
|
}
|
|
145
|
-
|
|
146
|
+
function requestFromLaunch(launch) {
|
|
147
|
+
const intent = launch.modelIntent === undefined
|
|
148
|
+
? undefined
|
|
149
|
+
: `${launch.modelIntent.family}/${launch.modelIntent.strength}`;
|
|
150
|
+
return modelRequestFromConfig(launch.model, intent, launch.modelExact === true);
|
|
151
|
+
}
|
|
152
|
+
async function assertNodeModelChangeRegistered(meta, target, registry) {
|
|
153
|
+
const launch = buildLaunchSpec(target.kind, target.mode, {
|
|
154
|
+
lifecycle: target.lifecycle,
|
|
155
|
+
hasManager: meta.parent !== null,
|
|
156
|
+
model: target.model,
|
|
157
|
+
cwd: meta.cwd,
|
|
158
|
+
profileId: meta.profile_id ?? null,
|
|
159
|
+
}).launch;
|
|
160
|
+
await assertLaunchModelRegistered(requestFromLaunch(launch), { cwd: meta.cwd, profileId: meta.profile_id ?? null }, registry);
|
|
161
|
+
}
|
|
162
|
+
export async function handleCreate(ctx, deps = {}) {
|
|
146
163
|
const req = parseCreateBody(ctx.body);
|
|
147
164
|
// `no_kickoff` needs no dedicated recipe field: an empty prompt IS the
|
|
148
165
|
// no-kickoff mechanism (spawnChild runs no launch turn on prompt===''), and
|
|
@@ -164,6 +181,19 @@ async function handleCreate(ctx) {
|
|
|
164
181
|
throw usage('output_schema must be a JSON schema string');
|
|
165
182
|
}
|
|
166
183
|
}
|
|
184
|
+
// Resolve and validate the exact launch recipe before the warm pool can claim
|
|
185
|
+
// a spare (or the cold path can create a worktree/node). The registry belongs
|
|
186
|
+
// to this daemon, never to the possibly-remote CLI caller.
|
|
187
|
+
const cwd = req.cwd ?? process.cwd();
|
|
188
|
+
const profileId = await resolveProfileId(req.profile, parent ?? null, cwd);
|
|
189
|
+
const launch = buildLaunchSpec(req.kind, (req.mode ?? 'base'), {
|
|
190
|
+
lifecycle: req.root === true ? 'resident' : 'terminal',
|
|
191
|
+
hasManager: req.root !== true,
|
|
192
|
+
...(req.model !== undefined ? { model: req.model } : {}),
|
|
193
|
+
cwd,
|
|
194
|
+
profileId,
|
|
195
|
+
}).launch;
|
|
196
|
+
await assertLaunchModelRegistered(requestFromLaunch(launch), { cwd, profileId }, deps.modelRegistry);
|
|
167
197
|
// --- Warm path: hand out an already-booted spare instead of paying a full
|
|
168
198
|
// engine boot. A miss is not a failure — it falls through to the cold
|
|
169
199
|
// spawn below and mints the spare that serves the NEXT create. ---
|
|
@@ -356,26 +386,24 @@ async function handleRecycle(ctx) {
|
|
|
356
386
|
}
|
|
357
387
|
function handleDemote(ctx) {
|
|
358
388
|
const id = ctx.params['id'];
|
|
359
|
-
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
hasManager: meta.parent != null,
|
|
364
|
-
...(meta.model_override != null ? { model: meta.model_override } : {}),
|
|
365
|
-
...(meta.launch?.modelProviderPinned !== undefined
|
|
366
|
-
? { modelProviderPinned: meta.launch.modelProviderPinned }
|
|
367
|
-
: {}),
|
|
368
|
-
...(meta.launch?.modelIntent !== undefined ? { modelIntent: meta.launch.modelIntent } : {}),
|
|
369
|
-
cwd: meta.cwd,
|
|
370
|
-
profileId: meta.profile_id ?? null,
|
|
371
|
-
});
|
|
372
|
-
updateNode(id, { lifecycle: 'terminal', launch });
|
|
389
|
+
requireMeta(id);
|
|
390
|
+
// Use the canonical reshape primitive to ensure modelExact, provider
|
|
391
|
+
// pin/intent, and default-name migration are all preserved.
|
|
392
|
+
reshapeNode(id, { lifecycle: 'terminal' });
|
|
373
393
|
return { status: 200, body: detailOf(id) };
|
|
374
394
|
}
|
|
375
|
-
function handlePromote(ctx) {
|
|
395
|
+
export async function handlePromote(ctx, deps = {}) {
|
|
376
396
|
const id = ctx.params['id'];
|
|
377
|
-
requireMeta(id);
|
|
397
|
+
const meta = requireMeta(id);
|
|
378
398
|
const req = ctx.body ?? {};
|
|
399
|
+
if (req.model !== undefined) {
|
|
400
|
+
await assertNodeModelChangeRegistered(meta, {
|
|
401
|
+
kind: req.kind ?? meta.kind,
|
|
402
|
+
mode: 'orchestrator',
|
|
403
|
+
lifecycle: req.resident === true ? 'resident' : meta.lifecycle,
|
|
404
|
+
model: req.model,
|
|
405
|
+
}, deps.modelRegistry);
|
|
406
|
+
}
|
|
379
407
|
const result = promote(id, {
|
|
380
408
|
...(req.kind !== undefined ? { kind: req.kind } : {}),
|
|
381
409
|
...(req.resident === true ? { resident: true } : {}),
|
|
@@ -389,10 +417,18 @@ function handlePromote(ctx) {
|
|
|
389
417
|
dto.goal_path = result.goalPath;
|
|
390
418
|
return { status: 200, body: dto };
|
|
391
419
|
}
|
|
392
|
-
function handleYield(ctx) {
|
|
420
|
+
export async function handleYield(ctx, deps = {}) {
|
|
393
421
|
const id = ctx.params['id'];
|
|
394
|
-
requireMeta(id);
|
|
422
|
+
const meta = requireMeta(id);
|
|
395
423
|
const req = ctx.body ?? {};
|
|
424
|
+
if (req.model !== undefined) {
|
|
425
|
+
await assertNodeModelChangeRegistered(meta, {
|
|
426
|
+
kind: req.kind ?? meta.kind,
|
|
427
|
+
mode: req.promote === true ? 'orchestrator' : meta.mode,
|
|
428
|
+
lifecycle: meta.lifecycle,
|
|
429
|
+
model: req.model,
|
|
430
|
+
}, deps.modelRegistry);
|
|
431
|
+
}
|
|
396
432
|
const note = req.note ?? 'Refresh: continue against your roadmap or goal.';
|
|
397
433
|
writeYieldMessage(id, note);
|
|
398
434
|
const result = requestYield(id, {
|
|
@@ -429,7 +465,7 @@ function handleReviveAll() {
|
|
|
429
465
|
// ---------------------------------------------------------------------------
|
|
430
466
|
// PATCH /v1/nodes/{id}/config — model / situational-context (spec §6.2)
|
|
431
467
|
// ---------------------------------------------------------------------------
|
|
432
|
-
async function handleConfig(ctx) {
|
|
468
|
+
export async function handleConfig(ctx, deps = {}) {
|
|
433
469
|
const id = ctx.params['id'];
|
|
434
470
|
let meta = requireMeta(id);
|
|
435
471
|
const patch = ctx.body ?? {};
|
|
@@ -438,9 +474,11 @@ async function handleConfig(ctx) {
|
|
|
438
474
|
}
|
|
439
475
|
if (patch.model !== undefined) {
|
|
440
476
|
const pinned = isProviderPinnedModelToken(patch.model);
|
|
477
|
+
const ladders = readMergedLaunchConfig(meta.cwd, meta.profile_id ?? null).modelLadders;
|
|
478
|
+
const spec = normalizeModel(patch.model, ladders);
|
|
479
|
+
await assertLaunchModelRegistered({ kind: 'concrete', spec }, { cwd: meta.cwd, profileId: meta.profile_id ?? null }, deps.modelRegistry);
|
|
441
480
|
const persistDormant = () => {
|
|
442
481
|
// Dormant: persist a fully-qualified `provider/id` spec to the row.
|
|
443
|
-
const spec = normalizeModel(patch.model);
|
|
444
482
|
if (!spec.includes('/'))
|
|
445
483
|
throw usage(`model must resolve to a provider/id spec: ${patch.model}`);
|
|
446
484
|
persistDormantModel(id, spec, pinned);
|
|
@@ -455,7 +493,7 @@ async function handleConfig(ctx) {
|
|
|
455
493
|
// rather than 500ing. A genuine broker rejection (e.g. an invalid model)
|
|
456
494
|
// rejects with a plain Error and still surfaces.
|
|
457
495
|
try {
|
|
458
|
-
await setModelLive(id,
|
|
496
|
+
await setModelLive(id, spec, pinned);
|
|
459
497
|
}
|
|
460
498
|
catch (err) {
|
|
461
499
|
if (!(err instanceof BrokerUnreachableError))
|
|
@@ -469,7 +507,7 @@ async function handleConfig(ctx) {
|
|
|
469
507
|
// Re-read so the launch-spec rebuild below sees the fresh model pin.
|
|
470
508
|
meta = requireMeta(id);
|
|
471
509
|
}
|
|
472
|
-
// --- kind / mode / lifecycle:
|
|
510
|
+
// --- kind / mode / lifecycle: reshape via canonical primitive (CLI parity). ---
|
|
473
511
|
if (patch.kind !== undefined || patch.mode !== undefined || patch.lifecycle !== undefined) {
|
|
474
512
|
if (patch.kind !== undefined)
|
|
475
513
|
assertKindServer(patch.kind);
|
|
@@ -477,25 +515,22 @@ async function handleConfig(ctx) {
|
|
|
477
515
|
const newMode = (patch.mode ?? meta.mode);
|
|
478
516
|
const newLifecycle = patch.lifecycle ?? meta.lifecycle;
|
|
479
517
|
// Setting orchestrator seeds a roadmap scaffold if absent (from the goal).
|
|
518
|
+
// Pass as beforePersist callback so roadmap seeding is atomic with the
|
|
519
|
+
// launch spec rebuild.
|
|
520
|
+
let beforePersist;
|
|
480
521
|
if (newMode === 'orchestrator' && !hasRoadmap(id)) {
|
|
481
|
-
|
|
482
|
-
|
|
522
|
+
beforePersist = () => {
|
|
523
|
+
const goal = readGoal(id);
|
|
524
|
+
seedRoadmap(id, goal !== null && goal.trim() !== '' ? { goal: goal.trim() } : {});
|
|
525
|
+
};
|
|
483
526
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
...(meta.model_override != null ? { model: meta.model_override } : {}),
|
|
488
|
-
...(meta.launch?.modelProviderPinned !== undefined ? { modelProviderPinned: meta.launch.modelProviderPinned } : {}),
|
|
489
|
-
...(meta.launch?.modelIntent !== undefined ? { modelIntent: meta.launch.modelIntent } : {}),
|
|
490
|
-
cwd: meta.cwd,
|
|
491
|
-
profileId: meta.profile_id ?? null,
|
|
492
|
-
});
|
|
493
|
-
meta = updateNode(id, {
|
|
527
|
+
// Use canonical reshape primitive to preserve modelExact, provider pin/intent,
|
|
528
|
+
// and default-name migration.
|
|
529
|
+
meta = reshapeNode(id, {
|
|
494
530
|
...(patch.kind !== undefined ? { kind: newKind } : {}),
|
|
495
531
|
...(patch.mode !== undefined ? { mode: newMode } : {}),
|
|
496
532
|
...(patch.lifecycle !== undefined ? { lifecycle: newLifecycle } : {}),
|
|
497
|
-
|
|
498
|
-
});
|
|
533
|
+
}, beforePersist);
|
|
499
534
|
}
|
|
500
535
|
// --- name: rename the row and, when it has a live viewer window, that window. ---
|
|
501
536
|
if (patch.name !== undefined) {
|
|
@@ -160,7 +160,11 @@ function requireVisibleReview(reviewId) {
|
|
|
160
160
|
function requireOpenReview(reviewId) {
|
|
161
161
|
const review = requireVisibleReview(reviewId);
|
|
162
162
|
if (review.state !== 'open') {
|
|
163
|
-
throw new ReviewOperationError('
|
|
163
|
+
throw new ReviewOperationError('review_terminal', 'review already has a terminal outcome', {
|
|
164
|
+
state: review.state,
|
|
165
|
+
requested: 'comment',
|
|
166
|
+
review,
|
|
167
|
+
});
|
|
164
168
|
}
|
|
165
169
|
return review;
|
|
166
170
|
}
|
|
@@ -7,7 +7,6 @@ import { isSafeNodeId, reviewResultPath } from '../../../core/canvas/paths.js';
|
|
|
7
7
|
import { responsePath, reviewPath } from '../../../core/human/convention.js';
|
|
8
8
|
import { ticketDir } from '../../../core/human/root.js';
|
|
9
9
|
import { createReview } from '../../../core/review/birth.js';
|
|
10
|
-
import { openExistingReview } from '../../../core/review/realize.js';
|
|
11
10
|
import { readAnchorBase, getReview, getReviewByBridge, listReviews } from '../../../core/review/store.js';
|
|
12
11
|
import { ReviewOperationError } from '../../../core/review/types.js';
|
|
13
12
|
import { cancelReview, submitReviewApproval } from '../../review/finish.js';
|
|
@@ -214,23 +213,6 @@ function handleByBridge(ctx) {
|
|
|
214
213
|
}
|
|
215
214
|
throw new ReviewOperationError('unknown_review', 'review was not found', { received: bridgeNodeId });
|
|
216
215
|
}
|
|
217
|
-
async function handleOpen(ctx) {
|
|
218
|
-
const violations = [];
|
|
219
|
-
const reviewId = requireReviewId(ctx, violations);
|
|
220
|
-
requireEmptyBody(ctx, violations);
|
|
221
|
-
if (violations.length > 0 || reviewId === undefined)
|
|
222
|
-
invalidRequest(violations);
|
|
223
|
-
const opened = await openExistingReview(reviewId);
|
|
224
|
-
const body = opened.disposition === 'terminal'
|
|
225
|
-
? { review: toReviewResponseDTO(opened.review), disposition: 'terminal' }
|
|
226
|
-
: {
|
|
227
|
-
review: toReviewResponseDTO(opened.review),
|
|
228
|
-
companion_node_id: opened.review.companion_node_id,
|
|
229
|
-
companion_status: opened.companion_status,
|
|
230
|
-
disposition: 'open',
|
|
231
|
-
};
|
|
232
|
-
return { status: 200, body };
|
|
233
|
-
}
|
|
234
216
|
async function handleSubmit(ctx) {
|
|
235
217
|
const violations = [];
|
|
236
218
|
const reviewId = requireReviewId(ctx, violations);
|
|
@@ -280,7 +262,6 @@ export const reviewRoutes = [
|
|
|
280
262
|
{ method: 'GET', pattern: '/v1/human/reviews', handler: handleList },
|
|
281
263
|
{ method: 'GET', pattern: '/v1/human/reviews/by-bridge/:bridge_node_id', handler: handleByBridge },
|
|
282
264
|
{ method: 'GET', pattern: '/v1/human/reviews/:review_id', handler: handleRead },
|
|
283
|
-
{ method: 'POST', pattern: '/v1/human/reviews/:review_id/open', handler: handleOpen },
|
|
284
265
|
{ method: 'POST', pattern: '/v1/human/reviews/:review_id/submit', handler: handleSubmit },
|
|
285
266
|
{ method: 'POST', pattern: '/v1/human/reviews/:review_id/cancel', handler: handleCancel },
|
|
286
267
|
{ method: 'GET', pattern: '/v1/human/reviews/:review_id/document', handler: handleDocument },
|