@north-light/crouter 0.3.170 → 0.3.172
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/dist/api/client.d.ts +37 -11
- package/dist/api/client.js +84 -15
- package/dist/api/dto/human.d.ts +53 -39
- package/dist/api/dto/human.js +2 -3
- package/dist/api/dto/inbox.d.ts +0 -1
- package/dist/api/dto/nodes.d.ts +12 -0
- package/dist/api/dto/review-comments.d.ts +137 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +109 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/routes.d.ts +17 -4
- package/dist/api/routes.js +21 -5
- package/dist/build-root.d.ts +1 -16
- package/dist/build-root.js +1 -25
- package/dist/builtin-memory/00-runtime-base.md +7 -5
- package/dist/builtin-memory/04-base-worker.md +1 -1
- package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
- package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
- package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
- package/dist/builtin-memory/design.md +2 -2
- package/dist/builtin-memory/insights/capture.md +50 -0
- package/dist/builtin-memory/insights/init.md +45 -0
- package/dist/builtin-memory/insights/listen.md +9 -0
- package/dist/builtin-memory/internal/agent-shaping.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +12 -11
- package/dist/builtin-memory/internal/storage-tiers.md +2 -2
- package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
- package/dist/builtin-memory/plan.md +19 -0
- package/dist/builtin-memory/spec/guide.md +38 -0
- package/dist/builtin-memory/spec/requirements.md +31 -0
- package/dist/builtin-memory/spec/roadmap.md +35 -0
- package/dist/builtin-memory/spec.md +10 -86
- package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
- package/dist/cli.js +2 -6
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
- package/dist/clients/attach/__tests__/context-message.test.js +142 -6
- package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
- package/dist/clients/attach/__tests__/diagram.test.js +1 -1
- package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
- package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
- package/dist/clients/attach/chrome/header.d.ts +10 -0
- package/dist/clients/attach/chrome/header.js +30 -0
- package/dist/clients/attach/chrome/recap.d.ts +7 -0
- package/dist/clients/attach/chrome/recap.js +19 -0
- package/dist/clients/attach/chrome/status-line.d.ts +3 -0
- package/dist/clients/attach/chrome/status-line.js +5 -0
- package/dist/clients/attach/chrome/widgets.js +11 -21
- package/dist/clients/attach/command.js +11 -7
- package/dist/clients/attach/config.d.ts +4 -0
- package/dist/clients/attach/config.js +3 -0
- package/dist/clients/attach/input/controller.d.ts +19 -0
- package/dist/clients/attach/input/controller.js +62 -28
- package/dist/clients/attach/input/titled-editor.d.ts +0 -4
- package/dist/clients/attach/input/titled-editor.js +2 -10
- package/dist/clients/attach/overlays/file-review.d.ts +9 -5
- package/dist/clients/attach/overlays/file-review.js +9 -70
- package/dist/clients/attach/overlays/help.d.ts +33 -0
- package/dist/clients/attach/overlays/help.js +204 -0
- package/dist/clients/attach/render/activity-slot.d.ts +4 -0
- package/dist/clients/attach/render/activity-slot.js +13 -0
- package/dist/clients/attach/render/chat-view.d.ts +117 -12
- package/dist/clients/attach/render/chat-view.js +604 -135
- package/dist/clients/attach/render/context-message.d.ts +2 -1
- package/dist/clients/attach/render/context-message.js +17 -13
- package/dist/clients/attach/render/crtr-output.js +1 -3
- package/dist/clients/attach/render/diagram.js +2 -2
- package/dist/clients/attach/render/edit-diff.d.ts +4 -1
- package/dist/clients/attach/render/edit-diff.js +7 -11
- package/dist/clients/attach/render/group-activity.d.ts +32 -0
- package/dist/clients/attach/render/group-activity.js +206 -0
- package/dist/clients/attach/render/group-recap.d.ts +10 -0
- package/dist/clients/attach/render/group-recap.js +93 -0
- package/dist/clients/attach/render/html-markdown.d.ts +17 -0
- package/dist/clients/attach/render/html-markdown.js +228 -0
- package/dist/clients/attach/render/measured-container.d.ts +96 -0
- package/dist/clients/attach/render/measured-container.js +322 -0
- package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
- package/dist/clients/attach/render/scroll-animation.js +80 -0
- package/dist/clients/attach/render/tool-calls.js +6 -6
- package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
- package/dist/clients/attach/render/transcript-copy.js +81 -0
- package/dist/clients/attach/render/viewport.d.ts +29 -0
- package/dist/clients/attach/render/viewport.js +159 -0
- package/dist/clients/attach/session/bindings.d.ts +10 -7
- package/dist/clients/attach/session/bindings.js +23 -8
- package/dist/clients/attach/session/connection.js +4 -5
- package/dist/clients/attach/session/context.d.ts +6 -4
- package/dist/clients/attach/session/frame.d.ts +34 -0
- package/dist/clients/attach/session/frame.js +176 -0
- package/dist/clients/attach/session/frames.d.ts +4 -1
- package/dist/clients/attach/session/frames.js +14 -1
- package/dist/clients/attach/session/identity.js +4 -3
- package/dist/clients/attach/session/input-wiring.d.ts +14 -4
- package/dist/clients/attach/session/input-wiring.js +15 -13
- package/dist/clients/attach/session/invariant.d.ts +9 -0
- package/dist/clients/attach/session/invariant.js +15 -0
- package/dist/clients/attach/session/keys.d.ts +10 -2
- package/dist/clients/attach/session/keys.js +13 -5
- package/dist/clients/attach/session/layout.d.ts +10 -8
- package/dist/clients/attach/session/layout.js +33 -34
- package/dist/clients/attach/session/mouse.d.ts +18 -0
- package/dist/clients/attach/session/mouse.js +64 -0
- package/dist/clients/attach/session/pane-tag.d.ts +3 -0
- package/dist/clients/attach/session/pane-tag.js +51 -8
- package/dist/clients/attach/session/reconnect.d.ts +3 -0
- package/dist/clients/attach/session/reconnect.js +42 -5
- package/dist/clients/attach/session/surface-frame.d.ts +20 -0
- package/dist/clients/attach/session/surface-frame.js +73 -0
- package/dist/clients/attach/session/surface-host.d.ts +64 -0
- package/dist/clients/attach/session/surface-host.js +255 -0
- package/dist/clients/attach/session/whip.d.ts +17 -0
- package/dist/clients/attach/session/whip.js +334 -0
- package/dist/clients/attach/slash/dispatch.d.ts +13 -1
- package/dist/clients/attach/slash/dispatch.js +51 -29
- package/dist/clients/attach/viewer.js +907 -819
- package/dist/clients/conversation/conversation.d.ts +65 -0
- package/dist/clients/conversation/conversation.js +318 -0
- package/dist/clients/conversation/frames.d.ts +30 -0
- package/dist/clients/conversation/frames.js +52 -0
- package/dist/clients/conversation/region.d.ts +51 -0
- package/dist/clients/conversation/region.js +265 -0
- package/dist/clients/conversation/submit.d.ts +38 -0
- package/dist/clients/conversation/submit.js +51 -0
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
- package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
- package/dist/clients/inbox/controller.d.ts +79 -0
- package/dist/clients/inbox/controller.js +448 -0
- package/dist/clients/inbox/deck-adapter.d.ts +29 -0
- package/dist/clients/inbox/deck-adapter.js +62 -0
- package/dist/clients/inbox/layout.d.ts +8 -0
- package/dist/clients/inbox/layout.js +9 -0
- package/dist/clients/inbox/resolve.d.ts +10 -0
- package/dist/clients/inbox/resolve.js +34 -0
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
- package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
- package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
- package/dist/clients/inbox/review/anchors.d.ts +41 -0
- package/dist/clients/inbox/review/anchors.js +89 -0
- package/dist/clients/inbox/review/columns.d.ts +22 -0
- package/dist/clients/inbox/review/columns.js +40 -0
- package/dist/clients/inbox/review/comments-client.d.ts +66 -0
- package/dist/clients/inbox/review/comments-client.js +98 -0
- package/dist/clients/inbox/review/composition.d.ts +60 -0
- package/dist/clients/inbox/review/composition.js +278 -0
- package/dist/clients/inbox/review/document-region.d.ts +120 -0
- package/dist/clients/inbox/review/document-region.js +902 -0
- package/dist/clients/inbox/review/frame.d.ts +45 -0
- package/dist/clients/inbox/review/frame.js +215 -0
- package/dist/clients/inbox/review/keys.d.ts +67 -0
- package/dist/clients/inbox/review/keys.js +130 -0
- package/dist/clients/inbox/review/launch.d.ts +10 -0
- package/dist/clients/inbox/review/launch.js +129 -0
- package/dist/clients/inbox/review/live-source.d.ts +24 -0
- package/dist/clients/inbox/review/live-source.js +160 -0
- package/dist/clients/inbox/review/nvim.d.ts +13 -0
- package/dist/clients/inbox/review/nvim.js +42 -0
- package/dist/clients/inbox/review/remap.d.ts +51 -0
- package/dist/clients/inbox/review/remap.js +157 -0
- package/dist/clients/inbox/review/review-client.d.ts +30 -0
- package/dist/clients/inbox/review/review-client.js +107 -0
- package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
- package/dist/clients/inbox/review/roundtrip.js +36 -0
- package/dist/clients/inbox/review/state.d.ts +143 -0
- package/dist/clients/inbox/review/state.js +282 -0
- package/dist/clients/inbox/review-adapter.d.ts +29 -0
- package/dist/clients/inbox/review-adapter.js +92 -0
- package/dist/clients/inbox/review-visibility.d.ts +5 -0
- package/dist/clients/inbox/review-visibility.js +19 -0
- package/dist/clients/inbox/surface.d.ts +19 -0
- package/dist/clients/inbox/surface.js +128 -0
- package/dist/clients/inbox/tui/ansi.d.ts +66 -0
- package/dist/clients/inbox/tui/ansi.js +317 -0
- package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
- package/dist/clients/inbox/tui/clipboard.js +26 -0
- package/dist/clients/inbox/tui/input.d.ts +7 -0
- package/dist/clients/inbox/tui/input.js +653 -0
- package/dist/clients/inbox/tui/keys.d.ts +28 -0
- package/dist/clients/inbox/tui/keys.js +111 -0
- package/dist/clients/inbox/tui/panel.d.ts +2 -0
- package/dist/clients/inbox/tui/panel.js +217 -0
- package/dist/clients/inbox/tui/render.d.ts +37 -0
- package/dist/clients/inbox/tui/render.js +476 -0
- package/dist/clients/inbox/tui/types.d.ts +57 -0
- package/dist/clients/inbox/tui/types.js +1 -0
- package/dist/clients/inbox/tui.d.ts +6 -0
- package/dist/clients/inbox/tui.js +74 -0
- package/dist/clients/surfaces/host.d.ts +66 -0
- package/dist/clients/surfaces/host.js +1 -0
- package/dist/clients/surfaces/region.d.ts +16 -0
- package/dist/clients/surfaces/region.js +1 -0
- package/dist/clients/web/__tests__/push-engine.test.js +14 -158
- package/dist/clients/web/dev-server.d.ts +3 -3
- package/dist/clients/web/dev-server.js +9 -23
- package/dist/clients/web/events.js +4 -6
- package/dist/clients/web/push-engine.d.ts +2 -66
- package/dist/clients/web/push-engine.js +30 -161
- package/dist/clients/web/push-registry.d.ts +0 -4
- package/dist/clients/web/push-registry.js +2 -7
- package/dist/clients/web/server.js +3 -35
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
- package/dist/clients/web/web-cmd.js +2 -2
- package/dist/commands/__tests__/human.test.js +27 -15
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/canvas-browse.js +1 -1
- package/dist/commands/canvas-issue.js +1 -1
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human/doc.d.ts +2 -0
- package/dist/commands/human/doc.js +98 -0
- package/dist/commands/human/inbox.d.ts +2 -0
- package/dist/commands/human/inbox.js +101 -0
- package/dist/commands/human/prompts.d.ts +2 -3
- package/dist/commands/human/prompts.js +27 -180
- package/dist/commands/human/queue.d.ts +1 -5
- package/dist/commands/human/queue.js +54 -216
- package/dist/commands/human/review.d.ts +2 -0
- package/dist/commands/human/review.js +298 -0
- package/dist/commands/human/shared.d.ts +2 -69
- package/dist/commands/human/shared.js +1 -181
- package/dist/commands/human.js +15 -20
- package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
- package/dist/commands/memory/__tests__/lint.test.js +15 -0
- package/dist/commands/memory/delete.js +2 -2
- package/dist/commands/memory/lint.d.ts +1 -0
- package/dist/commands/memory/lint.js +21 -3
- package/dist/commands/memory/read.js +4 -4
- package/dist/commands/node.js +8 -7
- package/dist/commands/pkg/plugin-manage.js +143 -68
- package/dist/commands/surface-inspect.js +2 -2
- package/dist/commands/surface.js +6 -12
- package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
- package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
- package/dist/commands/sys/config.js +29 -3
- package/dist/commands/sys/feedback.js +1 -1
- package/dist/commands/sys/setup-core.d.ts +12 -11
- package/dist/commands/sys/setup-core.js +55 -46
- package/dist/commands/sys/setup-wizard.d.ts +4 -1
- package/dist/commands/sys/setup-wizard.js +50 -9
- package/dist/commands/sys/sync-deps.js +1 -1
- package/dist/commands/sys.js +4 -6
- package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
- package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
- package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
- package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
- package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
- package/dist/core/__tests__/full/detach-focus.test.js +1 -1
- package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
- package/dist/core/__tests__/human-deliver.test.js +71 -345
- package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
- package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
- package/dist/core/__tests__/migration.test.js +10 -0
- package/dist/core/__tests__/model-pin-durability.test.js +14 -0
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
- package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-store.test.js +143 -0
- package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
- package/dist/core/__tests__/revive.test.js +22 -53
- package/dist/core/__tests__/session-cycles.test.js +48 -18
- package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
- package/dist/core/__tests__/stop-guard.test.js +16 -1
- package/dist/core/__tests__/tmux-surface.test.js +21 -25
- package/dist/core/asset-root.d.ts +7 -0
- package/dist/core/asset-root.js +18 -0
- package/dist/core/broker-client/client.d.ts +0 -7
- package/dist/core/broker-client/client.js +4 -10
- package/dist/core/broker-client/transport-relay.d.ts +3 -4
- package/dist/core/broker-client/transport-relay.js +3 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
- package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
- package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
- package/dist/core/canvas/attention.js +4 -4
- package/dist/core/canvas/canvas.d.ts +6 -11
- package/dist/core/canvas/canvas.js +11 -33
- package/dist/core/canvas/db.js +207 -38
- package/dist/core/canvas/extensions.d.ts +1 -1
- package/dist/core/canvas/extensions.js +8 -1
- package/dist/core/canvas/index.d.ts +0 -1
- package/dist/core/canvas/index.js +0 -1
- package/dist/core/canvas/nav-model.d.ts +1 -1
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/paths.d.ts +5 -0
- package/dist/core/canvas/paths.js +16 -0
- package/dist/core/canvas/remote-canvas-source.js +2 -2
- package/dist/core/canvas/remote-transport.d.ts +7 -0
- package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/status-glyph.js +4 -12
- package/dist/core/canvas/types.d.ts +10 -35
- package/dist/core/clipboard-text.d.ts +8 -0
- package/dist/core/clipboard-text.js +18 -0
- package/dist/core/command-manifests/registry.d.ts +1 -3
- package/dist/core/command-plugins/bundle.d.ts +29 -0
- package/dist/core/command-plugins/bundle.js +198 -0
- package/dist/core/command-plugins/discovery.d.ts +0 -8
- package/dist/core/command-plugins/discovery.js +2 -39
- package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
- package/dist/core/command-plugins/transport/http-fetch.js +17 -95
- package/dist/core/command.d.ts +1 -13
- package/dist/core/command.js +1 -16
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +28 -3
- package/dist/core/document-lines.d.ts +4 -0
- package/dist/core/document-lines.js +6 -0
- package/dist/core/feed/feed.d.ts +2 -0
- package/dist/core/feed/feed.js +11 -7
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
- package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-core.test.js +144 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
- package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
- package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
- package/dist/core/human/claim.d.ts +23 -0
- package/dist/core/human/claim.js +67 -0
- package/dist/core/human/convention.d.ts +30 -0
- package/dist/core/human/convention.js +202 -0
- package/dist/core/human/deck-factories.d.ts +8 -0
- package/dist/core/human/deck-factories.js +15 -0
- package/dist/core/human/deck-schema.d.ts +70 -0
- package/dist/core/human/deck-schema.js +92 -0
- package/dist/core/human/root.d.ts +7 -0
- package/dist/core/human/root.js +37 -0
- package/dist/core/human/scan.d.ts +3 -0
- package/dist/core/human/scan.js +76 -0
- package/dist/core/human/summary.d.ts +8 -0
- package/dist/core/human/summary.js +44 -0
- package/dist/core/human/tickets.d.ts +49 -0
- package/dist/core/human/tickets.js +190 -0
- package/dist/core/human/types.d.ts +136 -0
- package/dist/core/human/types.js +5 -0
- package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
- package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
- package/dist/core/inspector/chrome.d.ts +6 -0
- package/dist/core/inspector/chrome.js +14 -0
- package/dist/core/inspector/contract.d.ts +105 -0
- package/dist/core/inspector/contract.js +1 -0
- package/dist/core/inspector/core.d.ts +4 -5
- package/dist/core/inspector/core.js +3 -5
- package/dist/core/inspector/host.d.ts +46 -0
- package/dist/core/{tui → inspector}/host.js +42 -208
- package/dist/core/inspector/text.d.ts +2 -2
- package/dist/core/inspector/transport.d.ts +6 -0
- package/dist/core/inspector/transport.js +36 -0
- package/dist/core/inspector/tui.d.ts +2 -2
- package/dist/core/inspector/tui.js +15 -15
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
- package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
- package/dist/core/keybindings/attach-control.d.ts +9 -3
- package/dist/core/keybindings/attach-control.js +3 -1
- package/dist/core/keybindings/catalog.d.ts +6 -5
- package/dist/core/keybindings/catalog.js +61 -133
- package/dist/core/keybindings/inbox.d.ts +5 -6
- package/dist/core/keybindings/inbox.js +9 -10
- package/dist/core/keybindings/index.d.ts +3 -3
- package/dist/core/keybindings/index.js +3 -3
- package/dist/core/keybindings/persistence.d.ts +5 -1
- package/dist/core/keybindings/persistence.js +24 -6
- package/dist/core/keybindings/resolve.d.ts +6 -0
- package/dist/core/keybindings/resolve.js +10 -3
- package/dist/core/memory/inline-ref-grammar.js +2 -3
- package/dist/core/memory-resolver.d.ts +27 -29
- package/dist/core/memory-resolver.js +45 -39
- package/dist/core/model-routes.d.ts +33 -0
- package/dist/core/model-routes.js +42 -3
- package/dist/core/preview-registry.js +17 -55
- package/dist/core/profiles/select.js +3 -3
- package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
- package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
- package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
- package/dist/core/review/__tests__/capture-origin.test.js +139 -0
- package/dist/core/review/__tests__/comments.test.d.ts +1 -0
- package/dist/core/review/__tests__/comments.test.js +98 -0
- package/dist/core/review/__tests__/project.test.d.ts +1 -0
- package/dist/core/review/__tests__/project.test.js +71 -0
- package/dist/core/review/__tests__/remap.test.d.ts +1 -0
- package/dist/core/review/__tests__/remap.test.js +159 -0
- package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
- package/dist/core/review/__tests__/stage-identity.test.js +140 -0
- package/dist/core/review/birth.d.ts +7 -0
- package/dist/core/review/birth.js +23 -0
- package/dist/core/review/comments.d.ts +69 -0
- package/dist/core/review/comments.js +295 -0
- package/dist/core/review/companion.d.ts +35 -0
- package/dist/core/review/companion.js +205 -0
- package/dist/core/review/document.d.ts +27 -0
- package/dist/core/review/document.js +138 -0
- package/dist/core/review/project.d.ts +13 -0
- package/dist/core/review/project.js +58 -0
- package/dist/core/review/realize.d.ts +19 -0
- package/dist/core/review/realize.js +217 -0
- package/dist/core/review/remap.d.ts +24 -0
- package/dist/core/review/remap.js +156 -0
- package/dist/core/review/signal.d.ts +5 -0
- package/dist/core/review/signal.js +31 -0
- package/dist/core/review/stage.d.ts +26 -0
- package/dist/core/review/stage.js +184 -0
- package/dist/core/review/store.d.ts +46 -0
- package/dist/core/review/store.js +163 -0
- package/dist/core/review/ticket-filter.d.ts +17 -0
- package/dist/core/review/ticket-filter.js +32 -0
- package/dist/core/review/types.d.ts +130 -0
- package/dist/core/review/types.js +23 -0
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
- package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
- package/dist/core/runtime/bearings.d.ts +5 -17
- package/dist/core/runtime/bearings.js +88 -71
- package/dist/core/runtime/broker-protocol.d.ts +31 -8
- package/dist/core/runtime/broker.d.ts +15 -1
- package/dist/core/runtime/broker.js +573 -141
- package/dist/core/runtime/canvas-extensions.d.ts +4 -5
- package/dist/core/runtime/canvas-extensions.js +5 -5
- package/dist/core/runtime/front-door.js +4 -4
- package/dist/core/runtime/headless-pi.d.ts +24 -0
- package/dist/core/runtime/headless-pi.js +152 -0
- package/dist/core/runtime/kickoff.d.ts +1 -5
- package/dist/core/runtime/kickoff.js +1 -5
- package/dist/core/runtime/model-registry.d.ts +3 -0
- package/dist/core/runtime/model-registry.js +13 -0
- package/dist/core/runtime/naming-persist.d.ts +4 -0
- package/dist/core/runtime/naming-persist.js +27 -1
- package/dist/core/runtime/naming.d.ts +17 -12
- package/dist/core/runtime/naming.js +91 -140
- package/dist/core/runtime/node-read.js +19 -10
- package/dist/core/runtime/nodes.d.ts +9 -14
- package/dist/core/runtime/nodes.js +3 -53
- package/dist/core/runtime/package-health.d.ts +6 -21
- package/dist/core/runtime/package-health.js +12 -123
- package/dist/core/runtime/placement-tmux.d.ts +2 -1
- package/dist/core/runtime/placement-tmux.js +6 -4
- package/dist/core/runtime/placement.d.ts +1 -0
- package/dist/core/runtime/placement.js +4 -8
- package/dist/core/runtime/promote.js +3 -0
- package/dist/core/runtime/recap.d.ts +2 -7
- package/dist/core/runtime/recap.js +35 -69
- package/dist/core/runtime/revive.js +34 -77
- package/dist/core/runtime/session-cycles.d.ts +4 -0
- package/dist/core/runtime/session-cycles.js +14 -1
- package/dist/core/runtime/session-visibility.d.ts +37 -0
- package/dist/core/runtime/session-visibility.js +83 -0
- package/dist/core/runtime/spawn.js +10 -22
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +18 -13
- package/dist/core/runtime/surface-bg.js +1 -1
- package/dist/core/runtime/tmux-chrome.d.ts +1 -1
- package/dist/core/runtime/tmux-chrome.js +1 -1
- package/dist/core/runtime/tmux.d.ts +35 -7
- package/dist/core/runtime/tmux.js +439 -62
- package/dist/core/runtime/tool-group-summary.d.ts +19 -0
- package/dist/core/runtime/tool-group-summary.js +88 -0
- package/dist/core/scope.d.ts +2 -7
- package/dist/core/scope.js +9 -35
- package/dist/core/substrate/schema.d.ts +2 -2
- package/dist/core/termrender/code-doc.d.ts +12 -0
- package/dist/core/termrender/code-doc.js +92 -0
- package/dist/core/termrender/display.d.ts +12 -0
- package/dist/core/termrender/display.js +19 -0
- package/dist/core/termrender/termrender.d.ts +73 -0
- package/dist/core/termrender/termrender.js +795 -0
- package/dist/core/termrender/version.d.ts +1 -0
- package/dist/core/termrender/version.js +1 -0
- package/dist/core/tui/terminal.js +1 -2
- package/dist/core/user-settings.d.ts +71 -3
- package/dist/core/user-settings.js +83 -1
- package/dist/daemon/api/__tests__/inbox.test.js +44 -133
- package/dist/daemon/api/handlers/human.d.ts +0 -10
- package/dist/daemon/api/handlers/human.js +104 -702
- package/dist/daemon/api/handlers/inbox.js +113 -142
- package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
- package/dist/daemon/api/handlers/review-comments.js +500 -0
- package/dist/daemon/api/handlers/reviews.d.ts +2 -0
- package/dist/daemon/api/handlers/reviews.js +287 -0
- package/dist/daemon/api/map.d.ts +22 -7
- package/dist/daemon/api/map.js +159 -11
- package/dist/daemon/api/server.js +4 -0
- package/dist/daemon/cron-run.js +6 -9
- package/dist/daemon/crtrd.js +17 -33
- package/dist/daemon/fleet.d.ts +1 -8
- package/dist/daemon/fleet.js +4 -30
- package/dist/daemon/human/finish.d.ts +14 -0
- package/dist/daemon/human/finish.js +115 -0
- package/dist/daemon/human/sweep.d.ts +6 -0
- package/dist/daemon/human/sweep.js +49 -0
- package/dist/daemon/messaging/node-message.d.ts +18 -0
- package/dist/daemon/messaging/node-message.js +70 -0
- package/dist/daemon/review/comment-notify.d.ts +26 -0
- package/dist/daemon/review/comment-notify.js +107 -0
- package/dist/daemon/review/deliver.d.ts +7 -0
- package/dist/daemon/review/deliver.js +56 -0
- package/dist/daemon/review/finish.d.ts +22 -0
- package/dist/daemon/review/finish.js +254 -0
- package/dist/daemon/review/sweep.d.ts +11 -0
- package/dist/daemon/review/sweep.js +120 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
- package/dist/pi-extensions/canvas-context-intro.js +50 -104
- package/dist/pi-extensions/canvas-recap.d.ts +15 -2
- package/dist/pi-extensions/canvas-recap.js +192 -69
- package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
- package/dist/pi-extensions/canvas-review-boundary.js +81 -0
- package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
- package/dist/pi-extensions/canvas-stophook.js +78 -128
- package/dist/pi-extensions/canvas-structured-output.js +52 -8
- package/dist/shared/generated-context.d.ts +29 -4
- package/dist/shared/generated-context.js +122 -7
- package/dist/shared/tool-groups.d.ts +23 -0
- package/dist/shared/tool-groups.js +60 -0
- package/dist/shared/working-activity.d.ts +8 -0
- package/dist/shared/working-activity.js +26 -0
- package/dist/types.d.ts +36 -2
- package/dist/types.js +51 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
- package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
- package/dist/web-client/index.html +2 -2
- package/dist/web-client/sw.js +1 -1
- package/docs/compat/hearth-crtr-v4.md +2 -2
- package/docs/compat/hearth-crtr-v5.md +4 -2
- package/docs/public-api.md +3 -3
- package/package.json +21 -14
- package/runtime.lock.json +4661 -1453
- package/scripts/postinstall.mjs +15 -2
- package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
- package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
- package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
- package/dist/builtin-views/_lib/states.mjs +0 -161
- package/dist/builtin-views/canvas/core.mjs +0 -657
- package/dist/builtin-views/canvas/text.mjs +0 -58
- package/dist/builtin-views/canvas/tui.mjs +0 -168
- package/dist/builtin-views/canvas/web.jsx +0 -121
- package/dist/builtin-views/chat/core.mjs +0 -684
- package/dist/builtin-views/chat/text.mjs +0 -101
- package/dist/builtin-views/chat/tui.mjs +0 -360
- package/dist/builtin-views/chat/web.jsx +0 -362
- package/dist/builtin-views/git-pr/core.mjs +0 -673
- package/dist/builtin-views/git-pr/text.mjs +0 -84
- package/dist/builtin-views/git-pr/tui.mjs +0 -301
- package/dist/builtin-views/git-pr/web.jsx +0 -216
- package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
- package/dist/builtin-views/inbox/core.mjs +0 -1273
- package/dist/builtin-views/inbox/text.mjs +0 -73
- package/dist/builtin-views/inbox/tui.mjs +0 -314
- package/dist/builtin-views/inbox/web.jsx +0 -188
- package/dist/builtin-views/linkedin/core.mjs +0 -906
- package/dist/builtin-views/linkedin/text.mjs +0 -69
- package/dist/builtin-views/linkedin/tui.mjs +0 -413
- package/dist/builtin-views/linkedin/web.jsx +0 -206
- package/dist/builtin-views/prompt-review/core.mjs +0 -735
- package/dist/builtin-views/prompt-review/text.mjs +0 -15
- package/dist/builtin-views/prompt-review/tui.mjs +0 -196
- package/dist/builtin-views/prompt-review/web.jsx +0 -484
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
- package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
- package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
- package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
- package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
- package/dist/clients/attach/session/mode.d.ts +0 -25
- package/dist/clients/attach/session/mode.js +0 -97
- package/dist/commands/sys/promptstudio.d.ts +0 -2
- package/dist/commands/sys/promptstudio.js +0 -65
- package/dist/commands/view-cycle.d.ts +0 -2
- package/dist/commands/view-cycle.js +0 -130
- package/dist/commands/view-list.d.ts +0 -2
- package/dist/commands/view-list.js +0 -66
- package/dist/commands/view-new.d.ts +0 -2
- package/dist/commands/view-new.js +0 -74
- package/dist/commands/view-pick.d.ts +0 -6
- package/dist/commands/view-pick.js +0 -129
- package/dist/commands/view-run.d.ts +0 -2
- package/dist/commands/view-run.js +0 -214
- package/dist/commands/view.d.ts +0 -2
- package/dist/commands/view.js +0 -31
- package/dist/commands/workspace.d.ts +0 -2
- package/dist/commands/workspace.js +0 -165
- package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
- package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
- package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
- package/dist/core/canvas/human-work-outbox.d.ts +0 -73
- package/dist/core/canvas/human-work-outbox.js +0 -261
- package/dist/core/command-plugins/store.d.ts +0 -16
- package/dist/core/command-plugins/store.js +0 -64
- package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
- package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
- package/dist/core/runtime/fault-recovery-nudge.js +0 -3
- package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
- package/dist/core/tui/host.d.ts +0 -66
- package/dist/core/view/__tests__/transport-cache.test.js +0 -62
- package/dist/core/view/bridge.d.ts +0 -10
- package/dist/core/view/bridge.js +0 -31
- package/dist/core/view/chrome.d.ts +0 -9
- package/dist/core/view/chrome.js +0 -22
- package/dist/core/view/contract.d.ts +0 -205
- package/dist/core/view/contract.js +0 -23
- package/dist/core/view/loader.d.ts +0 -31
- package/dist/core/view/loader.js +0 -188
- package/dist/core/view/stream-local.d.ts +0 -3
- package/dist/core/view/stream-local.js +0 -231
- package/dist/core/view/transport-cache.d.ts +0 -8
- package/dist/core/view/transport-cache.js +0 -38
- package/dist/core/view/transport-local.d.ts +0 -7
- package/dist/core/view/transport-local.js +0 -83
- package/dist/core/view/transport-remote.d.ts +0 -2
- package/dist/core/view/transport.d.ts +0 -10
- package/dist/core/view/transport.js +0 -15
- package/dist/pi-extensions/naming-tool.d.ts +0 -24
- package/dist/pi-extensions/naming-tool.js +0 -67
- package/dist/prompts/view.d.ts +0 -7
- package/dist/prompts/view.js +0 -172
- package/dist/web/ViewChrome.d.ts +0 -7
- package/dist/web/ViewChrome.js +0 -28
- package/dist/web/ViewPane.d.ts +0 -39
- package/dist/web/ViewPane.js +0 -48
- package/dist/web/index.d.ts +0 -8
- package/dist/web/index.js +0 -22
- package/dist/web/runtime.d.ts +0 -39
- package/dist/web/runtime.js +0 -232
- package/dist/web/states.d.ts +0 -24
- package/dist/web/states.js +0 -24
- package/dist/web/transport-http.d.ts +0 -5
- package/dist/web/transport-http.js +0 -34
- package/dist/web/transport-stream.d.ts +0 -3
- package/dist/web/transport-stream.js +0 -204
- package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
- package/dist/web-client/assets/index-aaeu4adv.css +0 -2
- /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
- /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
- /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
- /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
- /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
package/dist/daemon/crtrd.js
CHANGED
|
@@ -50,20 +50,22 @@ import { execFile } from 'node:child_process';
|
|
|
50
50
|
import { randomBytes } from 'node:crypto';
|
|
51
51
|
import { promisify } from 'node:util';
|
|
52
52
|
import { crtrHome, nodeDir, jobDir, isSafeNodeId } from '../core/canvas/paths.js';
|
|
53
|
-
import { listNodes, getRow, getNode, migrateLegacyPidIdentities, listFocuses, closeFocusRow, pruneToLimit, subscribersOf,
|
|
53
|
+
import { listNodes, getRow, getNode, migrateLegacyPidIdentities, listFocuses, closeFocusRow, pruneToLimit, subscribersOf, } from '../core/canvas/index.js';
|
|
54
54
|
import { fullName } from '../core/canvas/labels.js';
|
|
55
55
|
import { transition } from '../core/runtime/lifecycle.js';
|
|
56
56
|
import { isBusy, busySince } from '../core/runtime/busy.js';
|
|
57
57
|
import { FAULT_QUIET_MS, readFault, recordFault } from '../core/runtime/fault.js';
|
|
58
58
|
import { fanDoctrineWake } from '../core/runtime/close.js';
|
|
59
59
|
import { createApiServer } from './api/server.js';
|
|
60
|
+
import { reconcileUndeliveredTickets } from './human/sweep.js';
|
|
61
|
+
import { sweepReviews } from './review/sweep.js';
|
|
60
62
|
// Lean pidfile/liveness helpers now live in `pidfile.ts` (db-free, so the CLI
|
|
61
63
|
// daemon front door can import them without reaching openDb). Imported here for
|
|
62
64
|
// internal use and re-exported below to preserve the historical crtrd.ts
|
|
63
65
|
// surface (tests, `commands/sys/daemon.ts`).
|
|
64
66
|
import { pidfilePath } from './pidfile.js';
|
|
65
67
|
export { readPidfile, isDaemonRunning } from './pidfile.js';
|
|
66
|
-
import {
|
|
68
|
+
import { rendererWarning } from '../core/runtime/package-health.js';
|
|
67
69
|
import { DEFAULT_INTERVAL_MS } from './supervise-cadence.js';
|
|
68
70
|
import { readConfig } from '../core/config.js';
|
|
69
71
|
export { FAULT_QUIET_MS };
|
|
@@ -80,7 +82,7 @@ import { reviveNode } from '../core/runtime/revive.js';
|
|
|
80
82
|
import { prewarmRecentRecipes, reapStaleSpares } from '../core/runtime/warm-pool.js';
|
|
81
83
|
import { headlessBrokerHost } from '../core/runtime/host.js';
|
|
82
84
|
import { reloadAuthLive } from '../core/runtime/auth-reload.js';
|
|
83
|
-
import { DaemonFleet,
|
|
85
|
+
import { DaemonFleet, retryResumeMode } from './fleet.js';
|
|
84
86
|
export { retryResumeMode };
|
|
85
87
|
import { appendControllerDeathNotice, readInboxSince, readCursor, } from '../core/feed/inbox.js';
|
|
86
88
|
import { migrateLegacyInboxIdentities } from '../core/feed/inbox-migrate.js';
|
|
@@ -99,9 +101,6 @@ import { recoverStaleCronLeases, runDueCrons } from './cron-run.js';
|
|
|
99
101
|
// `encoding`/`timeout`, same decisions made from stdout) — only the blocking
|
|
100
102
|
// behavior changes.
|
|
101
103
|
const execFileAsync = promisify(execFile);
|
|
102
|
-
// surfaceBootFailure + reconcileFollowUpWorkOnCrash moved to ./fleet.js — the
|
|
103
|
-
// fleet's exit-policy paths are their primary consumers; the surviving crtrd
|
|
104
|
-
// passes import them back from there.
|
|
105
104
|
// Count-based auto-prune of the canvas (pruneToLimit). The canvas grows
|
|
106
105
|
// unbounded — the TTL `crtr canvas prune` is manual, so without this a long-lived
|
|
107
106
|
// daemon's canvas accumulates thousands of terminal nodes, making every scan +
|
|
@@ -359,7 +358,7 @@ export async function runStartupRecoverySweep(fleet) {
|
|
|
359
358
|
const thresholds = brokerThresholdsForDaemon();
|
|
360
359
|
for (const row of rows) {
|
|
361
360
|
if (row.kind === 'human')
|
|
362
|
-
continue; //
|
|
361
|
+
continue; // human bridge rows — never broker-hosted
|
|
363
362
|
if (fleet.size() >= thresholds.automaticReviveCap) {
|
|
364
363
|
emitEvent({
|
|
365
364
|
level: 'warn',
|
|
@@ -915,7 +914,6 @@ function handleFatalFault(id, now) {
|
|
|
915
914
|
if (terminalOverflow) {
|
|
916
915
|
try {
|
|
917
916
|
transition(id, 'crash');
|
|
918
|
-
reconcileFollowUpWorkOnCrash(id);
|
|
919
917
|
headlessBrokerHost.teardown(id);
|
|
920
918
|
}
|
|
921
919
|
catch {
|
|
@@ -1275,10 +1273,9 @@ export async function superviseTick(now = Date.now(), lifecycle = directTickLife
|
|
|
1275
1273
|
return;
|
|
1276
1274
|
}
|
|
1277
1275
|
// kind:'human' rows are NOT broker-hosted agent nodes — they are bookkeeping
|
|
1278
|
-
// rows for the `crtr human` bridge.
|
|
1279
|
-
//
|
|
1280
|
-
//
|
|
1281
|
-
// never launch a broker or record a `pi_session_id`, so the dead-node policy
|
|
1276
|
+
// rows for the `crtr human` bridge. crtrd delivers their terminal ticket result
|
|
1277
|
+
// with pushFinal when the person responds from crouter's inbox, or when `human cancel`
|
|
1278
|
+
// publishes a cancellation. They never launch a broker or record a `pi_session_id`, so the dead-node policy
|
|
1282
1279
|
// table would read every one as a never-booted broker (row 8) and crash it
|
|
1283
1280
|
// with surfaceBootFailure — exactly the regression where a headless
|
|
1284
1281
|
// orchestrator's `human ask` nodes all died at boot. The daemon must never
|
|
@@ -1433,7 +1430,6 @@ export async function superviseTick(now = Date.now(), lifecycle = directTickLife
|
|
|
1433
1430
|
},
|
|
1434
1431
|
});
|
|
1435
1432
|
transition(id, 'crash');
|
|
1436
|
-
reconcileFollowUpWorkOnCrash(id);
|
|
1437
1433
|
if (meta !== null) {
|
|
1438
1434
|
try {
|
|
1439
1435
|
fanDoctrineWake(id, subscribersOf(id), `Child crashed — ${fullName(meta)} (${id}) failed to relaunch after ${attempts} attempts while trying to ` +
|
|
@@ -1845,13 +1841,12 @@ export async function runDaemon(opts = {}) {
|
|
|
1845
1841
|
operationIdContext.fresh(() => {
|
|
1846
1842
|
emitEvent({ level: 'info', event: 'daemon.install_id.resolved', fields: { install_id: installId } });
|
|
1847
1843
|
});
|
|
1848
|
-
// The
|
|
1849
|
-
//
|
|
1850
|
-
// a stale executable without blocking supervision.
|
|
1844
|
+
// The pinned termrender renderer is an advisory dependency; setup repairs
|
|
1845
|
+
// an unprovisioned venv without blocking supervision.
|
|
1851
1846
|
operationIdContext.fresh(() => {
|
|
1852
1847
|
let warning;
|
|
1853
1848
|
try {
|
|
1854
|
-
warning =
|
|
1849
|
+
warning = rendererWarning();
|
|
1855
1850
|
}
|
|
1856
1851
|
catch {
|
|
1857
1852
|
return;
|
|
@@ -1860,25 +1855,14 @@ export async function runDaemon(opts = {}) {
|
|
|
1860
1855
|
emitEvent({
|
|
1861
1856
|
level: 'warn',
|
|
1862
1857
|
event: 'daemon.startup.warning',
|
|
1863
|
-
fields: { stage: '
|
|
1858
|
+
fields: { stage: 'termrender', warning: warning.slice(0, 2_048) },
|
|
1864
1859
|
});
|
|
1865
1860
|
}
|
|
1866
1861
|
});
|
|
1867
|
-
//
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
reconcileFollowUpWork();
|
|
1872
|
-
reconcileVisualWork();
|
|
1873
|
-
}
|
|
1874
|
-
catch (error) {
|
|
1875
|
-
emitEvent({
|
|
1876
|
-
level: 'error',
|
|
1877
|
-
event: 'consult.outbox.reconcile_failed',
|
|
1878
|
-
error,
|
|
1879
|
-
fields: { phase: 'startup' },
|
|
1880
|
-
});
|
|
1881
|
-
}
|
|
1862
|
+
// Complete ticket delivery before API traffic can observe terminal answers.
|
|
1863
|
+
await operationIdContext.fresh(async () => {
|
|
1864
|
+
await sweepReviews();
|
|
1865
|
+
await reconcileUndeliveredTickets();
|
|
1882
1866
|
});
|
|
1883
1867
|
// Boot reconciliation clears stale process identities before any tick can
|
|
1884
1868
|
// inspect them, then migrates legacy identities only with proven same-boot
|
package/dist/daemon/fleet.d.ts
CHANGED
|
@@ -9,13 +9,6 @@ import type { HostHandle } from '../core/runtime/host.js';
|
|
|
9
9
|
* urgent push so the parent learns the child failed to launch instead of just
|
|
10
10
|
* seeing a silent `dead`. */
|
|
11
11
|
export declare function surfaceBootFailure(meta: NodeMeta): Promise<void>;
|
|
12
|
-
/** Event-driven follow-up human-work settlement at daemon-detected node death
|
|
13
|
-
* (design-followup-consult-v2.md §B.4 step 4). Re-runs the consult-outbox
|
|
14
|
-
* reconcile scan right where the daemon first observes a death, so an `armed`
|
|
15
|
-
* row whose fork just died with no final report becomes the ticket's error
|
|
16
|
-
* result immediately. A no-op for every crash that isn't a consult/visual
|
|
17
|
-
* fork. Best-effort, mirrors the startup call's error handling. */
|
|
18
|
-
export declare function reconcileFollowUpWorkOnCrash(id: string): void;
|
|
19
12
|
/** Whether a dead relaunch should resume the saved session strictly, or retry
|
|
20
13
|
* as a fresh cycle instead. A cycling attempt (cycle_pending) that dies
|
|
21
14
|
* before session_start must retry AS a cycle — a strict reopen only restores
|
|
@@ -26,7 +19,7 @@ export declare function retryResumeMode(meta: Pick<NodeMeta, 'cycle_pending'> |
|
|
|
26
19
|
export type DeadNodeAction = 'forget' | 'respawn-fresh' | 'dormant' | 'respawn-cycle' | 'respawn-resume' | 'boot-failure';
|
|
27
20
|
/** The narrow durable state the policy table reads. Structural (a Pick, not
|
|
28
21
|
* NodeMeta itself) so tests fabricate table rows directly. */
|
|
29
|
-
export type DeadNodeRow = Pick<NodeMeta, 'status' | 'intent' | 'pi_session_id' | 'cycle_pending' | '
|
|
22
|
+
export type DeadNodeRow = Pick<NodeMeta, 'status' | 'intent' | 'pi_session_id' | 'cycle_pending' | 'fork_from'>;
|
|
30
23
|
/** One pure function producing the action for a node known-dead. Used at
|
|
31
24
|
* exactly two call sites — an exit-policy job and the startup recovery sweep
|
|
32
25
|
* (design D-12) — so exit recovery and startup recovery can never diverge.
|
package/dist/daemon/fleet.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// before every deliberate exit, and that durable state is robust to every kill
|
|
14
14
|
// path. Codes/signals are logged for diagnostics only. The single timing
|
|
15
15
|
// input is uptime, used only by the throttle.
|
|
16
|
-
import { getNode, subscribersOf
|
|
16
|
+
import { getNode, subscribersOf } from '../core/canvas/index.js';
|
|
17
17
|
import { fullName } from '../core/canvas/labels.js';
|
|
18
18
|
import { isSafeNodeId } from '../core/canvas/paths.js';
|
|
19
19
|
import { transition } from '../core/runtime/lifecycle.js';
|
|
@@ -50,30 +50,6 @@ async function surfaceRecoveryFailure(meta, error) {
|
|
|
50
50
|
`The node is now dead. Fix the recorded launch configuration, then revive it if the work still needs doing.`;
|
|
51
51
|
await pushUrgent(meta.node_id, body, { from: meta.node_id });
|
|
52
52
|
}
|
|
53
|
-
/** Event-driven follow-up human-work settlement at daemon-detected node death
|
|
54
|
-
* (design-followup-consult-v2.md §B.4 step 4). Re-runs the consult-outbox
|
|
55
|
-
* reconcile scan right where the daemon first observes a death, so an `armed`
|
|
56
|
-
* row whose fork just died with no final report becomes the ticket's error
|
|
57
|
-
* result immediately. A no-op for every crash that isn't a consult/visual
|
|
58
|
-
* fork. Best-effort, mirrors the startup call's error handling. */
|
|
59
|
-
export function reconcileFollowUpWorkOnCrash(id) {
|
|
60
|
-
try {
|
|
61
|
-
reconcileFollowUpWork();
|
|
62
|
-
reconcileVisualWork();
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
emitEvent({
|
|
66
|
-
level: 'error',
|
|
67
|
-
event: 'consult.outbox.reconcile_failed',
|
|
68
|
-
...(isSafeNodeId(id) ? { node_id: id } : {}),
|
|
69
|
-
error: err,
|
|
70
|
-
fields: {
|
|
71
|
-
phase: 'crash',
|
|
72
|
-
...(isSafeNodeId(id) ? {} : { affected_node_id: id }),
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
53
|
/** Whether a dead relaunch should resume the saved session strictly, or retry
|
|
78
54
|
* as a fresh cycle instead. A cycling attempt (cycle_pending) that dies
|
|
79
55
|
* before session_start must retry AS a cycle — a strict reopen only restores
|
|
@@ -104,8 +80,8 @@ export function classifyDeadNode(row, busy, cleanAbort = false) {
|
|
|
104
80
|
return 'respawn-cycle'; // row 6: dirty interrupted turn
|
|
105
81
|
if (row.pi_session_id != null)
|
|
106
82
|
return retryResumeMode(row, false) ? 'respawn-resume' : 'respawn-cycle'; // row 7
|
|
107
|
-
if (row.
|
|
108
|
-
return 'respawn-fresh'; // row 8: bounded fork-birth retry
|
|
83
|
+
if (row.fork_from != null && row.pi_session_id == null)
|
|
84
|
+
return 'respawn-fresh'; // row 8: bounded ordinary fork-birth retry
|
|
109
85
|
return 'boot-failure'; // row 9
|
|
110
86
|
}
|
|
111
87
|
// ---------------------------------------------------------------------------
|
|
@@ -377,8 +353,7 @@ export class DaemonFleet {
|
|
|
377
353
|
}
|
|
378
354
|
}
|
|
379
355
|
/** Terminal outcome shared by table row 8 and throttle exhaustion:
|
|
380
|
-
* transition('crash') +
|
|
381
|
-
* doctrine wake, counter cleared. */
|
|
356
|
+
* transition('crash') + surfaceBootFailure + doctrine wake, counter cleared. */
|
|
382
357
|
async #terminalize(nodeId, meta, opts) {
|
|
383
358
|
this.#clearThrottle(nodeId);
|
|
384
359
|
emitEvent({
|
|
@@ -387,7 +362,6 @@ export class DaemonFleet {
|
|
|
387
362
|
...(isSafeNodeId(nodeId) ? { node_id: nodeId } : { fields: { affected_node_id: nodeId } }),
|
|
388
363
|
});
|
|
389
364
|
transition(nodeId, 'crash');
|
|
390
|
-
reconcileFollowUpWorkOnCrash(nodeId);
|
|
391
365
|
try {
|
|
392
366
|
await (opts.surface ?? (() => surfaceBootFailure(meta)))();
|
|
393
367
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { InteractionResponse, TicketResult } from '../../core/human/types.js';
|
|
2
|
+
/** Resolve a deck ticket under the store-owned claim-takeover lock boundary. */
|
|
3
|
+
export declare function resolveDeckTicket(nodeId: string, responses: InteractionResponse[]): Promise<TicketResult>;
|
|
4
|
+
/** Cancel a ticket with the store's first-writer-wins publication. */
|
|
5
|
+
export declare function cancelHumanTicket(nodeId: string, opts: {
|
|
6
|
+
reason?: string;
|
|
7
|
+
actor?: string;
|
|
8
|
+
}): Promise<TicketResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Deliver a terminal ticket result to its bridge. The canonical response is the
|
|
11
|
+
* receipt: every action below is replay-safe, so lost delivery can be retried
|
|
12
|
+
* by a later resolve/cancel attempt or the daemon-start sweep.
|
|
13
|
+
*/
|
|
14
|
+
export declare function deliverTerminalResult(nodeId: string): Promise<boolean>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { ApiError } from '../../api/index.js';
|
|
3
|
+
import { getNode, subscribersOf } from '../../core/canvas/canvas.js';
|
|
4
|
+
import { ticketDir } from '../../core/human/root.js';
|
|
5
|
+
import { cancelTicket, projectReviewOutput, readTicketResult, takeoverAndCompleteDeck, } from '../../core/human/tickets.js';
|
|
6
|
+
import { readJson, responsePath } from '../../core/human/convention.js';
|
|
7
|
+
import { appendInbox } from '../../core/feed/inbox.js';
|
|
8
|
+
import { FinalDeliveryError, pushFinal } from '../../core/feed/feed.js';
|
|
9
|
+
import { transition } from '../../core/runtime/lifecycle.js';
|
|
10
|
+
function envelopeFromDeckResult(responses, summary, completedAt, resultPath) {
|
|
11
|
+
return { summary, responsePath: resultPath, schema: 'humanloop.response/v2', responses, completedAt };
|
|
12
|
+
}
|
|
13
|
+
function renderDeckAnswer(env) {
|
|
14
|
+
const summary = env.summary.trim();
|
|
15
|
+
const body = summary === '' ? '(the human submitted no answer text)' : summary;
|
|
16
|
+
return `${body}\n\nResponse metadata (question ids, selected options, timestamp): ${env.responsePath}`;
|
|
17
|
+
}
|
|
18
|
+
function deliveryFailed(error) {
|
|
19
|
+
// A canonical final is committed inside its own write boundary and can never
|
|
20
|
+
// be replayed (`already_finalized`), so a subscriber that missed the fanout
|
|
21
|
+
// stays missed. Say that rather than promising a retry that cannot happen.
|
|
22
|
+
if (error instanceof FinalDeliveryError) {
|
|
23
|
+
return new ApiError(500, 'delivery_failed', `The answer is recorded and the bridge node is finalized; its report is at ${error.reportPath}. Notifying ${error.failedTo.join(', ')} failed and will not be retried.`);
|
|
24
|
+
}
|
|
25
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
26
|
+
return new ApiError(500, 'delivery_failed', `The answer is recorded and delivery will be retried: ${detail}`);
|
|
27
|
+
}
|
|
28
|
+
async function deliverOrConflict(nodeId) {
|
|
29
|
+
try {
|
|
30
|
+
await deliverTerminalResult(nodeId);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw deliveryFailed(error);
|
|
34
|
+
}
|
|
35
|
+
throw new ApiError(409, 'ticket_already_resolved', 'ticket already resolved');
|
|
36
|
+
}
|
|
37
|
+
/** Resolve a deck ticket under the store-owned claim-takeover lock boundary. */
|
|
38
|
+
export async function resolveDeckTicket(nodeId, responses) {
|
|
39
|
+
const completed = takeoverAndCompleteDeck(ticketDir(nodeId), responses, { host: 'crtrd', pid: process.pid });
|
|
40
|
+
if (!completed.won)
|
|
41
|
+
return deliverOrConflict(nodeId);
|
|
42
|
+
try {
|
|
43
|
+
await deliverTerminalResult(nodeId);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
throw deliveryFailed(error);
|
|
47
|
+
}
|
|
48
|
+
return completed.result;
|
|
49
|
+
}
|
|
50
|
+
/** Cancel a ticket with the store's first-writer-wins publication. */
|
|
51
|
+
export async function cancelHumanTicket(nodeId, opts) {
|
|
52
|
+
const canceled = cancelTicket(ticketDir(nodeId), opts);
|
|
53
|
+
if (canceled.status === 'already_resolved')
|
|
54
|
+
return deliverOrConflict(nodeId);
|
|
55
|
+
try {
|
|
56
|
+
await deliverTerminalResult(nodeId);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw deliveryFailed(error);
|
|
60
|
+
}
|
|
61
|
+
return canceled.result;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Deliver a terminal ticket result to its bridge. The canonical response is the
|
|
65
|
+
* receipt: every action below is replay-safe, so lost delivery can be retried
|
|
66
|
+
* by a later resolve/cancel attempt or the daemon-start sweep.
|
|
67
|
+
*/
|
|
68
|
+
export async function deliverTerminalResult(nodeId) {
|
|
69
|
+
const dir = ticketDir(nodeId);
|
|
70
|
+
const run = readJson(join(dir, 'run.json'));
|
|
71
|
+
if (run?.mode === 'notify')
|
|
72
|
+
return false;
|
|
73
|
+
const result = readTicketResult(dir);
|
|
74
|
+
if (result === null)
|
|
75
|
+
return false;
|
|
76
|
+
projectReviewOutput(dir);
|
|
77
|
+
const node = getNode(nodeId);
|
|
78
|
+
if (node === null || node.status === 'dead' || node.status === 'canceled' || (node.status === 'done' && node.final_report !== null)) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (result.kind === 'canceled') {
|
|
82
|
+
const note = result.reason !== undefined && result.reason !== '' ? ` — ${result.reason}` : '';
|
|
83
|
+
// One failing subscriber must not silence the rest, and the bridge stays
|
|
84
|
+
// live until every notice lands: a partial fanout leaves the ticket for the
|
|
85
|
+
// next resolve/cancel attempt or the daemon-start sweep to replay. A
|
|
86
|
+
// subscriber notified twice reads the same idempotent "no answer is coming";
|
|
87
|
+
// a subscriber never notified waits forever.
|
|
88
|
+
const failedTo = [];
|
|
89
|
+
for (const subscriber of subscribersOf(nodeId)) {
|
|
90
|
+
if (result.actor !== undefined && subscriber.node_id === result.actor)
|
|
91
|
+
continue;
|
|
92
|
+
try {
|
|
93
|
+
appendInbox(subscriber.node_id, {
|
|
94
|
+
from: nodeId,
|
|
95
|
+
tier: 'deferred',
|
|
96
|
+
kind: 'message',
|
|
97
|
+
label: `human interaction ${nodeId} canceled — no answer is coming${note}`,
|
|
98
|
+
data: { body: `The human interaction ${nodeId} was canceled${note}. No response will arrive.` },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
failedTo.push(subscriber.node_id);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (failedTo.length > 0)
|
|
106
|
+
throw new Error(`cancellation notice failed for ${failedTo.join(', ')}`);
|
|
107
|
+
transition(nodeId, 'finish');
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (result.kind !== 'deck')
|
|
111
|
+
return true;
|
|
112
|
+
const envelope = envelopeFromDeckResult(result.responses, result.summary, result.completedAt, responsePath(dir));
|
|
113
|
+
await pushFinal(nodeId, renderDeckAnswer(envelope));
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { getNode } from '../../core/canvas/canvas.js';
|
|
4
|
+
import { getReviewByBridge } from '../../core/review/store.js';
|
|
5
|
+
import { emitEvent } from '../../core/events/emit.js';
|
|
6
|
+
import { ticketsRoot } from '../../core/human/root.js';
|
|
7
|
+
import { readTicketResult } from '../../core/human/tickets.js';
|
|
8
|
+
import { deliverTerminalResult } from './finish.js';
|
|
9
|
+
function isTerminalBridge(status) {
|
|
10
|
+
return status === 'done' || status === 'dead' || status === 'canceled';
|
|
11
|
+
}
|
|
12
|
+
/** Deliver terminal ticket results left behind before their bridge could finish. */
|
|
13
|
+
export async function reconcileUndeliveredTickets() {
|
|
14
|
+
let scanned = 0;
|
|
15
|
+
let delivered = 0;
|
|
16
|
+
let failed = 0;
|
|
17
|
+
const root = ticketsRoot();
|
|
18
|
+
for (const entry of readdirSync(root)) {
|
|
19
|
+
try {
|
|
20
|
+
const dir = join(root, entry);
|
|
21
|
+
if (!statSync(dir).isDirectory())
|
|
22
|
+
continue;
|
|
23
|
+
scanned += 1;
|
|
24
|
+
if (readTicketResult(dir) === null)
|
|
25
|
+
continue;
|
|
26
|
+
// Canonical reviews own terminal delivery and bridge retirement. Their
|
|
27
|
+
// finisher retries only when its winning operation is explicitly repeated.
|
|
28
|
+
if (getReviewByBridge(entry) !== null)
|
|
29
|
+
continue;
|
|
30
|
+
const bridge = getNode(entry);
|
|
31
|
+
if (bridge === null || isTerminalBridge(bridge.status))
|
|
32
|
+
continue;
|
|
33
|
+
if (await deliverTerminalResult(entry))
|
|
34
|
+
delivered += 1;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
failed += 1;
|
|
38
|
+
emitEvent({
|
|
39
|
+
level: 'error',
|
|
40
|
+
event: 'human.delivery.reconcile_failed',
|
|
41
|
+
node_id: entry,
|
|
42
|
+
error,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const result = { scanned, delivered, failed };
|
|
47
|
+
emitEvent({ level: 'info', event: 'human.delivery.reconciled', fields: result });
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type NodeMessageMode = 'interactive' | 'wake' | 'quiet';
|
|
2
|
+
export interface NodeMessageDelivery {
|
|
3
|
+
entry_id: string | null;
|
|
4
|
+
via: 'engine' | 'inbox';
|
|
5
|
+
revived: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Deliver one daemon-originated node message. Interactive messages use the live
|
|
9
|
+
* broker when available; every other successful path is a durable inbox entry.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deliverNodeMessage(args: {
|
|
12
|
+
node_id: string;
|
|
13
|
+
body: string;
|
|
14
|
+
label: string;
|
|
15
|
+
from?: string | null;
|
|
16
|
+
mode: NodeMessageMode;
|
|
17
|
+
data?: Record<string, unknown>;
|
|
18
|
+
}): Promise<NodeMessageDelivery>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getNode } from '../../core/canvas/canvas.js';
|
|
2
|
+
import { withFreshTerminalGuard } from '../../core/canvas/canvas.js';
|
|
3
|
+
import { appendInbox } from '../../core/feed/inbox.js';
|
|
4
|
+
import { BrokerUnreachableError } from '../../core/runtime/broker-request.js';
|
|
5
|
+
import { deliverLive } from '../../core/runtime/interactive-deliver.js';
|
|
6
|
+
import { isBrokerLive } from '../../core/runtime/model-swap.js';
|
|
7
|
+
import { reviveNode } from '../../core/runtime/revive.js';
|
|
8
|
+
import { hasNoNaturalCycle } from '../../core/runtime/revive-all.js';
|
|
9
|
+
import { ReviewOperationError } from '../../core/review/types.js';
|
|
10
|
+
function deliveryUnroutable(nodeId, reason) {
|
|
11
|
+
throw new ReviewOperationError('delivery_unroutable', reason === 'origin_missing' ? 'message target was not found' : 'message target has no natural delivery cycle', { node_id: nodeId, reason });
|
|
12
|
+
}
|
|
13
|
+
/** Run a fresh terminal guard before any delivery path, including live engine sends. */
|
|
14
|
+
function guardRoutable(nodeId, body) {
|
|
15
|
+
const outcome = withFreshTerminalGuard(nodeId, hasNoNaturalCycle, body);
|
|
16
|
+
if (outcome.kind === 'missing')
|
|
17
|
+
deliveryUnroutable(nodeId, 'origin_missing');
|
|
18
|
+
if (outcome.kind === 'terminal')
|
|
19
|
+
deliveryUnroutable(nodeId, 'no_natural_cycle');
|
|
20
|
+
return outcome.result;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Deliver one daemon-originated node message. Interactive messages use the live
|
|
24
|
+
* broker when available; every other successful path is a durable inbox entry.
|
|
25
|
+
*/
|
|
26
|
+
export async function deliverNodeMessage(args) {
|
|
27
|
+
// A live interactive delivery has no durable append to guard, so establish
|
|
28
|
+
// routability first. The durable fallback below takes the guard again to
|
|
29
|
+
// close the race before its append.
|
|
30
|
+
guardRoutable(args.node_id, () => undefined);
|
|
31
|
+
let target = getNode(args.node_id);
|
|
32
|
+
if (target === null)
|
|
33
|
+
deliveryUnroutable(args.node_id, 'origin_missing');
|
|
34
|
+
if (args.mode === 'interactive' && isBrokerLive(target)) {
|
|
35
|
+
try {
|
|
36
|
+
await deliverLive(args.node_id, args.body);
|
|
37
|
+
// The broker acknowledgement is asynchronous to the SQLite guard. Recheck
|
|
38
|
+
// before reporting an engine receipt so a final that committed during the
|
|
39
|
+
// request is not represented as a routable delivery.
|
|
40
|
+
guardRoutable(args.node_id, () => undefined);
|
|
41
|
+
return { entry_id: null, via: 'engine', revived: false };
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (!(error instanceof BrokerUnreachableError))
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const entry = guardRoutable(args.node_id, () => appendInbox(args.node_id, {
|
|
49
|
+
from: args.from ?? null,
|
|
50
|
+
tier: args.mode === 'quiet' ? 'deferred' : 'normal',
|
|
51
|
+
kind: 'message',
|
|
52
|
+
label: args.label,
|
|
53
|
+
data: { ...args.data, body: args.body },
|
|
54
|
+
}));
|
|
55
|
+
let revived = false;
|
|
56
|
+
if (args.mode !== 'quiet') {
|
|
57
|
+
target = getNode(args.node_id);
|
|
58
|
+
if (target === null)
|
|
59
|
+
deliveryUnroutable(args.node_id, 'origin_missing');
|
|
60
|
+
if (!isBrokerLive(target)) {
|
|
61
|
+
try {
|
|
62
|
+
revived = reviveNode(args.node_id, { resume: true }).launch !== undefined;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// The durable entry remains authoritative; one wake attempt is enough.
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { entry_id: entry.entry_id, via: 'inbox', revived };
|
|
70
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReviewComment, ReviewRecord } from '../../core/review/types.js';
|
|
2
|
+
export type DeliverMode = 'wake' | 'quiet';
|
|
3
|
+
type CommentVerb = 'create' | 'edit' | 'resolve' | 'reopen' | 'delete';
|
|
4
|
+
export interface CommentDelivery {
|
|
5
|
+
attempted: boolean;
|
|
6
|
+
target_node_id?: string;
|
|
7
|
+
status: 'delivered' | 'skipped' | 'failed';
|
|
8
|
+
via?: 'engine' | 'inbox';
|
|
9
|
+
woke: boolean;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Render the one bounded, durable comment notice delivered to a review companion. */
|
|
13
|
+
export declare function renderCommentNotice(review: ReviewRecord, comment: ReviewComment, verb: CommentVerb): string;
|
|
14
|
+
/**
|
|
15
|
+
* Best-effort post-commit notice for one review-comment mutation. Delivery and
|
|
16
|
+
* its audit are deliberately outside the comment's state transaction.
|
|
17
|
+
*/
|
|
18
|
+
export declare function notifyComment(args: {
|
|
19
|
+
review: ReviewRecord;
|
|
20
|
+
comment: ReviewComment;
|
|
21
|
+
verb: CommentVerb;
|
|
22
|
+
actor_node_id: string | null;
|
|
23
|
+
deliver: DeliverMode | undefined;
|
|
24
|
+
operation_id: string;
|
|
25
|
+
}): Promise<CommentDelivery>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { appendDeliveryEvent } from '../../core/review/comments.js';
|
|
2
|
+
import { deliverNodeMessage } from '../messaging/node-message.js';
|
|
3
|
+
function defaultDeliverMode(verb) {
|
|
4
|
+
switch (verb) {
|
|
5
|
+
case 'create':
|
|
6
|
+
case 'edit':
|
|
7
|
+
case 'reopen':
|
|
8
|
+
return 'wake';
|
|
9
|
+
case 'resolve':
|
|
10
|
+
case 'delete':
|
|
11
|
+
return 'quiet';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function range(comment) {
|
|
15
|
+
return comment.anchor.end_line > comment.anchor.line
|
|
16
|
+
? `L${comment.anchor.line}-${comment.anchor.end_line}`
|
|
17
|
+
: `L${comment.anchor.line}`;
|
|
18
|
+
}
|
|
19
|
+
function quotedSource(comment) {
|
|
20
|
+
const quote = comment.anchor.quote;
|
|
21
|
+
return quote === undefined || quote === '' ? comment.anchor_line_text : quote;
|
|
22
|
+
}
|
|
23
|
+
function verbPastTense(verb) {
|
|
24
|
+
switch (verb) {
|
|
25
|
+
case 'create': return 'created';
|
|
26
|
+
case 'edit': return 'edited';
|
|
27
|
+
case 'resolve': return 'resolved';
|
|
28
|
+
case 'reopen': return 'reopened';
|
|
29
|
+
case 'delete': return 'deleted';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Render the one bounded, durable comment notice delivered to a review companion. */
|
|
33
|
+
export function renderCommentNotice(review, comment, verb) {
|
|
34
|
+
return [
|
|
35
|
+
`Review comment ${comment.comment_id} was ${verbPastTense(verb)} in review ${review.review_id}.`,
|
|
36
|
+
'',
|
|
37
|
+
`File: ${review.file}`,
|
|
38
|
+
`Range: ${range(comment)}`,
|
|
39
|
+
'Quoted source:',
|
|
40
|
+
quotedSource(comment),
|
|
41
|
+
'',
|
|
42
|
+
'Comment:',
|
|
43
|
+
comment.text,
|
|
44
|
+
].join('\n');
|
|
45
|
+
}
|
|
46
|
+
function errorMessage(error) {
|
|
47
|
+
return error instanceof Error ? error.message : String(error);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Best-effort post-commit notice for one review-comment mutation. Delivery and
|
|
51
|
+
* its audit are deliberately outside the comment's state transaction.
|
|
52
|
+
*/
|
|
53
|
+
export async function notifyComment(args) {
|
|
54
|
+
if (args.actor_node_id === args.review.companion_node_id && args.deliver === undefined) {
|
|
55
|
+
return { attempted: false, status: 'skipped', woke: false };
|
|
56
|
+
}
|
|
57
|
+
const target_node_id = args.review.companion_node_id;
|
|
58
|
+
const mode = args.deliver ?? defaultDeliverMode(args.verb);
|
|
59
|
+
const body = renderCommentNotice(args.review, args.comment, args.verb);
|
|
60
|
+
let delivery;
|
|
61
|
+
try {
|
|
62
|
+
delivery = await deliverNodeMessage({
|
|
63
|
+
node_id: target_node_id,
|
|
64
|
+
body,
|
|
65
|
+
label: 'review comment',
|
|
66
|
+
from: 'crtrd',
|
|
67
|
+
mode: mode === 'wake' ? 'interactive' : 'quiet',
|
|
68
|
+
data: {
|
|
69
|
+
review_id: args.review.review_id,
|
|
70
|
+
comment_id: args.comment.comment_id,
|
|
71
|
+
verb: args.verb,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
const projection = {
|
|
77
|
+
attempted: true,
|
|
78
|
+
target_node_id,
|
|
79
|
+
status: 'failed',
|
|
80
|
+
woke: false,
|
|
81
|
+
error: errorMessage(error),
|
|
82
|
+
};
|
|
83
|
+
appendDeliveryEvent({
|
|
84
|
+
review_id: args.review.review_id,
|
|
85
|
+
comment_id: args.comment.comment_id,
|
|
86
|
+
kind: 'notify_failed',
|
|
87
|
+
payload: projection,
|
|
88
|
+
operation_id: args.operation_id,
|
|
89
|
+
});
|
|
90
|
+
return projection;
|
|
91
|
+
}
|
|
92
|
+
const projection = {
|
|
93
|
+
attempted: true,
|
|
94
|
+
target_node_id,
|
|
95
|
+
status: 'delivered',
|
|
96
|
+
via: delivery.via,
|
|
97
|
+
woke: delivery.revived,
|
|
98
|
+
};
|
|
99
|
+
appendDeliveryEvent({
|
|
100
|
+
review_id: args.review.review_id,
|
|
101
|
+
comment_id: args.comment.comment_id,
|
|
102
|
+
kind: 'notified',
|
|
103
|
+
payload: projection,
|
|
104
|
+
operation_id: args.operation_id,
|
|
105
|
+
});
|
|
106
|
+
return projection;
|
|
107
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReviewRecord } from '../../core/review/types.js';
|
|
2
|
+
/** Render the immutable approval fact without replaying comment text. */
|
|
3
|
+
export declare function renderApprovalMessage(review: ReviewRecord, resultPath: string): string;
|
|
4
|
+
/** Deliver an approval through its origin-specific canonical route. */
|
|
5
|
+
export declare function deliverApproval(review: ReviewRecord, resultPath: string): Promise<{
|
|
6
|
+
receipt: string | null;
|
|
7
|
+
}>;
|