@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
|
@@ -1,111 +1,56 @@
|
|
|
1
|
-
// push-engine.ts — the server-side web-push
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// trigger, diffs against persisted last-seen state, and decides what (if
|
|
5
|
-
// anything) to push. It never invents a second attention signal — decks/canvas
|
|
6
|
-
// stay the truth.
|
|
1
|
+
// push-engine.ts — the server-side web-push diff engine. SSE (`events.ts`) is
|
|
2
|
+
// a trigger only (`{kind, ts}`, never data); this module re-reads the canvas,
|
|
3
|
+
// diffs persisted last-seen state, and emits done-transition notifications.
|
|
7
4
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// from a non-done status, emit one 'done' push per transition.
|
|
12
|
-
// - 'inbox' -> re-read pending asks (deck provenance), detect an ask id that
|
|
13
|
-
// is present now but was not known-notified before, emit one
|
|
14
|
-
// 'needs-you' push per NEW ask, coalesced per conversation.
|
|
15
|
-
//
|
|
16
|
-
// On server start, `seed()` records the current state and sends NOTHING — a
|
|
17
|
-
// restart is not an attention event.
|
|
18
|
-
//
|
|
19
|
-
// Last-seen state is only advanced past a suppressed (rate-capped) item when
|
|
20
|
-
// that item was not actually the reason for suppression; a rate-capped
|
|
21
|
-
// transition/ask is deliberately left out of the persisted state so the NEXT
|
|
22
|
-
// invalidation retries it rather than silently losing it forever.
|
|
5
|
+
// A `nodes` invalidation detects a conversation root (`parent === null`) crossing
|
|
6
|
+
// from a nonterminal state into done, dead, or canceled. On server start,
|
|
7
|
+
// `seed()` records the current state and sends nothing.
|
|
23
8
|
import { isAllowedPushEndpoint } from './push-registry.js';
|
|
24
9
|
const DONE_STATUSES = new Set(['done', 'dead', 'canceled']);
|
|
25
|
-
/** Minimum interval between pushes for the same conversation root — coalesces
|
|
26
|
-
* a burst of distinct events (several new asks, or an ask+done in close
|
|
27
|
-
* succession) into at most one send per window, never a storm. */
|
|
28
10
|
const DEFAULT_RATE_WINDOW_MS = 30_000;
|
|
29
11
|
export class PushDiffEngine {
|
|
30
12
|
registry;
|
|
31
13
|
lastSeen;
|
|
32
14
|
readCanvasNodes;
|
|
33
|
-
readPendingAsks;
|
|
34
15
|
sendPush;
|
|
35
16
|
isTargetScope;
|
|
36
17
|
now;
|
|
37
18
|
rateWindowMs;
|
|
38
|
-
/** Drain-queue state: only one diff pass mutates last-seen at a time. An
|
|
39
|
-
* invalidation arriving mid-pass sets its pending flag and is reprocessed
|
|
40
|
-
* when the current pass finishes — no two passes race the same snapshot. */
|
|
41
19
|
draining = false;
|
|
42
20
|
pendingNodes = false;
|
|
43
|
-
pendingInbox = false;
|
|
44
|
-
/** Per-conversation rate-cap clock. Deliberately in-memory/process-lifetime
|
|
45
|
-
* only (not persisted) — a restart re-seeding silently is already the
|
|
46
|
-
* no-storm guarantee; the rate cap only smooths a live process's bursts. */
|
|
47
21
|
lastPushAt = new Map();
|
|
48
|
-
/** Per-(conversationId+kind) set of subscription ids already delivered for
|
|
49
|
-
* the CURRENT still-pending notification. A transient failure on one
|
|
50
|
-
* subscription must never cause a later retry to re-send to subscriptions
|
|
51
|
-
* that already got `'sent'` — this is exactly what remembers them across
|
|
52
|
-
* passes. Cleared the moment the event fully succeeds (or has no eligible
|
|
53
|
-
* subscriber left), since a later, distinct event reusing the same key
|
|
54
|
-
* must start fresh. */
|
|
55
22
|
deliveredForKey = new Map();
|
|
56
23
|
constructor(deps) {
|
|
57
24
|
this.registry = deps.registry;
|
|
58
25
|
this.lastSeen = deps.lastSeen;
|
|
59
26
|
this.readCanvasNodes = deps.readCanvasNodes;
|
|
60
|
-
this.readPendingAsks = deps.readPendingAsks;
|
|
61
27
|
this.sendPush = deps.sendPush;
|
|
62
28
|
this.isTargetScope = deps.isTargetScope;
|
|
63
29
|
this.now = deps.now ?? (() => Date.now());
|
|
64
30
|
this.rateWindowMs = deps.rateWindowMs ?? DEFAULT_RATE_WINDOW_MS;
|
|
65
31
|
}
|
|
66
|
-
/**
|
|
67
|
-
* on server start — a restart must never be an attention event. */
|
|
32
|
+
/** Record the current canvas state without sending notifications. */
|
|
68
33
|
async seed() {
|
|
69
|
-
const
|
|
34
|
+
const nodes = await this.readCanvasNodes();
|
|
70
35
|
const roots = {};
|
|
71
|
-
for (const
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
roots[n.node_id] = { status: n.status, attention_count: n.attention_count };
|
|
36
|
+
for (const node of nodes) {
|
|
37
|
+
if (node.parent === null)
|
|
38
|
+
roots[node.node_id] = { status: node.status, attention_count: node.attention_count };
|
|
75
39
|
}
|
|
76
|
-
|
|
77
|
-
for (const a of asks)
|
|
78
|
-
askState[a.id] = { present: true };
|
|
79
|
-
this.lastSeen.replace({ schemaVersion: 1, updatedAt: this.now(), roots, asks: askState });
|
|
40
|
+
this.lastSeen.replace({ schemaVersion: 1, updatedAt: this.now(), roots });
|
|
80
41
|
}
|
|
81
|
-
/** 'nodes' invalidation: re-read the canvas roster, emit a 'done' push for
|
|
82
|
-
* every conversation root that just crossed into a done|dead|canceled
|
|
83
|
-
* status from a non-done status. */
|
|
84
42
|
async onNodesInvalidation() {
|
|
85
43
|
this.pendingNodes = true;
|
|
86
44
|
await this.drain();
|
|
87
45
|
}
|
|
88
|
-
async onInboxInvalidation() {
|
|
89
|
-
this.pendingInbox = true;
|
|
90
|
-
await this.drain();
|
|
91
|
-
}
|
|
92
|
-
/** Serialize passes: if a pass is already running, just set the pending flag
|
|
93
|
-
* and return — the running drain loop will pick it up. Otherwise run pending
|
|
94
|
-
* passes until none remain. */
|
|
95
46
|
async drain() {
|
|
96
47
|
if (this.draining)
|
|
97
48
|
return;
|
|
98
49
|
this.draining = true;
|
|
99
50
|
try {
|
|
100
|
-
while (this.pendingNodes
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await this.runNodesPass();
|
|
104
|
-
}
|
|
105
|
-
if (this.pendingInbox) {
|
|
106
|
-
this.pendingInbox = false;
|
|
107
|
-
await this.runInboxPass();
|
|
108
|
-
}
|
|
51
|
+
while (this.pendingNodes) {
|
|
52
|
+
this.pendingNodes = false;
|
|
53
|
+
await this.runNodesPass();
|
|
109
54
|
}
|
|
110
55
|
}
|
|
111
56
|
finally {
|
|
@@ -114,93 +59,30 @@ export class PushDiffEngine {
|
|
|
114
59
|
}
|
|
115
60
|
async runNodesPass() {
|
|
116
61
|
const nodes = await this.readCanvasNodes();
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
for (const
|
|
120
|
-
if (
|
|
62
|
+
const previous = this.lastSeen.snapshot();
|
|
63
|
+
const roots = {};
|
|
64
|
+
for (const node of nodes) {
|
|
65
|
+
if (node.parent !== null)
|
|
121
66
|
continue;
|
|
122
|
-
const before =
|
|
123
|
-
const
|
|
124
|
-
if (!
|
|
125
|
-
|
|
67
|
+
const before = previous.roots[node.node_id];
|
|
68
|
+
const transitioned = before !== undefined && !DONE_STATUSES.has(before.status) && DONE_STATUSES.has(node.status);
|
|
69
|
+
if (!transitioned) {
|
|
70
|
+
roots[node.node_id] = { status: node.status, attention_count: node.attention_count };
|
|
126
71
|
continue;
|
|
127
72
|
}
|
|
128
|
-
const sent = await this.emit(
|
|
129
|
-
conversationId:
|
|
73
|
+
const sent = await this.emit(node.node_id, {
|
|
74
|
+
conversationId: node.node_id,
|
|
130
75
|
kind: 'done',
|
|
131
76
|
title: 'Conversation finished',
|
|
132
|
-
snippet: `This conversation is now ${
|
|
133
|
-
});
|
|
134
|
-
// Rate-capped: keep the PRE-transition state so the next 'nodes'
|
|
135
|
-
// invalidation still sees a non-done -> done edge and retries.
|
|
136
|
-
nextRoots[n.node_id] = sent ? { status: n.status, attention_count: n.attention_count } : before;
|
|
137
|
-
}
|
|
138
|
-
this.lastSeen.replace({ schemaVersion: prev.schemaVersion, updatedAt: this.now(), roots: nextRoots, asks: prev.asks });
|
|
139
|
-
}
|
|
140
|
-
/** 'inbox' invalidation: re-read pending asks, emit exactly one 'needs-you'
|
|
141
|
-
* push per conversation for its NEW (not-yet-notified) asks, coalesced. An
|
|
142
|
-
* ask no longer present (resolved/missing) is simply dropped, never
|
|
143
|
-
* notified. */
|
|
144
|
-
async runInboxPass() {
|
|
145
|
-
const asks = await this.readPendingAsks();
|
|
146
|
-
const prev = this.lastSeen.snapshot();
|
|
147
|
-
const nextAsks = {};
|
|
148
|
-
const newByConversation = new Map();
|
|
149
|
-
for (const ask of asks) {
|
|
150
|
-
if (prev.asks[ask.id]?.present === true) {
|
|
151
|
-
// Already known + already notified at some point — keep tracked, never
|
|
152
|
-
// re-notify the same unresolved ask.
|
|
153
|
-
nextAsks[ask.id] = { present: true };
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
const list = newByConversation.get(ask.conversationId) ?? [];
|
|
157
|
-
list.push(ask);
|
|
158
|
-
newByConversation.set(ask.conversationId, list);
|
|
159
|
-
}
|
|
160
|
-
for (const [conversationId, list] of newByConversation) {
|
|
161
|
-
const first = list[0];
|
|
162
|
-
const extra = list.length - 1;
|
|
163
|
-
const sent = await this.emit(conversationId, {
|
|
164
|
-
conversationId,
|
|
165
|
-
kind: 'needs-you',
|
|
166
|
-
askId: first.jobId,
|
|
167
|
-
title: first.conversationTitle,
|
|
168
|
-
snippet: extra > 0 ? `${first.title} (+${extra} more)` : first.title,
|
|
77
|
+
snippet: `This conversation is now ${node.status}.`,
|
|
169
78
|
});
|
|
170
|
-
|
|
171
|
-
for (const ask of list)
|
|
172
|
-
nextAsks[ask.id] = { present: true };
|
|
173
|
-
}
|
|
174
|
-
// Rate-capped: leave these ask ids OUT of nextAsks so the next 'inbox'
|
|
175
|
-
// invalidation still sees them as new and retries once the window clears.
|
|
79
|
+
roots[node.node_id] = sent ? { status: node.status, attention_count: node.attention_count } : before;
|
|
176
80
|
}
|
|
177
|
-
this.lastSeen.replace({ schemaVersion:
|
|
81
|
+
this.lastSeen.replace({ schemaVersion: previous.schemaVersion, updatedAt: this.now(), roots });
|
|
178
82
|
}
|
|
179
|
-
/** Send one push per ELIGIBLE subscription — one whose authScope is on the
|
|
180
|
-
* watched boundary (`isTargetScope`) AND that opted in for this payload kind.
|
|
181
|
-
* Respects the per-conversation rate cap; prunes any subscription the push
|
|
182
|
-
* service reports gone (404/410) or whose endpoint fails the push-service
|
|
183
|
-
* allowlist re-check. Tracks per-subscription delivery for this notification
|
|
184
|
-
* (`deliveredForKey`) so a retry after a transient failure on one
|
|
185
|
-
* subscription never re-sends to a subscription that already got `'sent'`.
|
|
186
|
-
* Returns true iff last-seen may advance: false when suppressed by the rate
|
|
187
|
-
* cap OR when a transient send error means the item must be retried next
|
|
188
|
-
* pass. A no-eligible pass returns true (nothing to retry). */
|
|
189
83
|
async emit(conversationId, payload) {
|
|
190
|
-
|
|
191
|
-
const eligible = this.registry.snapshot().filter((r) => {
|
|
192
|
-
if (!this.isTargetScope(r.authScope))
|
|
193
|
-
return false;
|
|
194
|
-
if (payload.kind === 'done' && !r.prefs.doneNotifications)
|
|
195
|
-
return false;
|
|
196
|
-
return true;
|
|
197
|
-
});
|
|
198
|
-
// Keyed by conversation + kind: a later, distinct event reusing this key
|
|
199
|
-
// (once cleared below) must start with a fresh delivered set.
|
|
84
|
+
const eligible = this.registry.snapshot().filter((record) => this.isTargetScope(record.authScope) && record.prefs.doneNotifications);
|
|
200
85
|
const key = `${conversationId}:${payload.kind}`;
|
|
201
|
-
// No eligible subscriber -> the event is fully handled (nothing to retry);
|
|
202
|
-
// advance last-seen. Checked BEFORE the rate cap so a no-eligible pass never
|
|
203
|
-
// stalls the state on a phantom retry.
|
|
204
86
|
if (eligible.length === 0) {
|
|
205
87
|
this.deliveredForKey.delete(key);
|
|
206
88
|
return true;
|
|
@@ -208,22 +90,14 @@ export class PushDiffEngine {
|
|
|
208
90
|
const now = this.now();
|
|
209
91
|
const last = this.lastPushAt.get(conversationId) ?? 0;
|
|
210
92
|
if (now - last < this.rateWindowMs)
|
|
211
|
-
return false;
|
|
93
|
+
return false;
|
|
212
94
|
this.lastPushAt.set(conversationId, now);
|
|
213
95
|
const delivered = this.deliveredForKey.get(key) ?? new Set();
|
|
214
96
|
let transientFailure = false;
|
|
215
97
|
for (const record of eligible) {
|
|
216
|
-
// Already delivered to this subscription for this event on an earlier
|
|
217
|
-
// pass — never re-send it (this is the fix for duplicate pushes on
|
|
218
|
-
// transient-failure retry: only the subscriptions that actually failed
|
|
219
|
-
// are retried).
|
|
220
98
|
if (delivered.has(record.id))
|
|
221
99
|
continue;
|
|
222
100
|
if (!isAllowedPushEndpoint(record.endpoint)) {
|
|
223
|
-
// Defense in depth: re-check the push-service allowlist immediately
|
|
224
|
-
// before every outbound connect (no DNS/host TOCTOU), even though
|
|
225
|
-
// normalizeEndpoint already enforced it at subscribe time. A record
|
|
226
|
-
// that fails this can never be sent to safely — prune it.
|
|
227
101
|
this.registry.deleteById(record.id);
|
|
228
102
|
continue;
|
|
229
103
|
}
|
|
@@ -241,11 +115,6 @@ export class PushDiffEngine {
|
|
|
241
115
|
else
|
|
242
116
|
transientFailure = true;
|
|
243
117
|
}
|
|
244
|
-
// A transient send failure must NOT advance last-seen — retry next pass
|
|
245
|
-
// (design: "update last-seen only after a successful diff pass"), and the
|
|
246
|
-
// subscriptions already delivered above must stay remembered so that retry
|
|
247
|
-
// only reaches the ones that failed. A pruned 'gone'/disallowed record is
|
|
248
|
-
// not a failure: nothing left to retry for it.
|
|
249
118
|
if (transientFailure) {
|
|
250
119
|
this.deliveredForKey.set(key, delivered);
|
|
251
120
|
return false;
|
|
@@ -22,14 +22,10 @@ export interface PushLastSeenRootState {
|
|
|
22
22
|
status: NodeLifeStatus;
|
|
23
23
|
attention_count: number;
|
|
24
24
|
}
|
|
25
|
-
export interface PushLastSeenAskState {
|
|
26
|
-
present: boolean;
|
|
27
|
-
}
|
|
28
25
|
export interface PushLastSeenFile {
|
|
29
26
|
schemaVersion: number;
|
|
30
27
|
updatedAt: number;
|
|
31
28
|
roots: Record<string, PushLastSeenRootState>;
|
|
32
|
-
asks: Record<string, PushLastSeenAskState>;
|
|
33
29
|
}
|
|
34
30
|
/** A locally generated VAPID keypair, persisted so the same identity signs
|
|
35
31
|
* every outbound push across restarts. The private key never leaves this
|
|
@@ -222,16 +222,12 @@ function isValidRegistryFile(value) {
|
|
|
222
222
|
function isValidLastSeenFile(value) {
|
|
223
223
|
if (!isRecord(value) || value.schemaVersion !== SCHEMA_VERSION || !isNumber(value.updatedAt))
|
|
224
224
|
return false;
|
|
225
|
-
if (!isRecord(value.roots)
|
|
225
|
+
if (!isRecord(value.roots))
|
|
226
226
|
return false;
|
|
227
227
|
for (const record of Object.values(value.roots)) {
|
|
228
228
|
if (!isRecord(record) || !isString(record.status) || !isNumber(record.attention_count))
|
|
229
229
|
return false;
|
|
230
230
|
}
|
|
231
|
-
for (const record of Object.values(value.asks)) {
|
|
232
|
-
if (!isRecord(record) || typeof record.present !== 'boolean')
|
|
233
|
-
return false;
|
|
234
|
-
}
|
|
235
231
|
return true;
|
|
236
232
|
}
|
|
237
233
|
function loadRegistryFile(path) {
|
|
@@ -245,7 +241,7 @@ function loadRegistryFile(path) {
|
|
|
245
241
|
}
|
|
246
242
|
function loadLastSeenFile(path) {
|
|
247
243
|
if (!existsSync(path)) {
|
|
248
|
-
return { schemaVersion: SCHEMA_VERSION, updatedAt: 0, roots: {}
|
|
244
|
+
return { schemaVersion: SCHEMA_VERSION, updatedAt: 0, roots: {} };
|
|
249
245
|
}
|
|
250
246
|
const parsed = readJsonFile(path);
|
|
251
247
|
if (!isValidLastSeenFile(parsed)) {
|
|
@@ -362,7 +358,6 @@ export class PushLastSeenStore {
|
|
|
362
358
|
schemaVersion: this.state.schemaVersion,
|
|
363
359
|
updatedAt: this.state.updatedAt,
|
|
364
360
|
roots: { ...this.state.roots },
|
|
365
|
-
asks: { ...this.state.asks },
|
|
366
361
|
};
|
|
367
362
|
}
|
|
368
363
|
replace(next) {
|
|
@@ -42,7 +42,6 @@ import { apiSocketPath, isSafeNodeId } from '../../core/canvas/paths.js';
|
|
|
42
42
|
import { emitEvent } from '../../core/events/emit.js';
|
|
43
43
|
import { bindWebEventSource } from '../../core/events/source.js';
|
|
44
44
|
import { canvasRosterLeaf } from '../../commands/canvas-roster.js';
|
|
45
|
-
import { humanList } from '../../commands/human/queue.js';
|
|
46
45
|
import { startEventHub } from './events.js';
|
|
47
46
|
import { createDevServer } from './dev-server.js';
|
|
48
47
|
import { PushLastSeenStore, PushRegistryStore, PushRequestError, loadOrCreateVapidKeypair, parsePushDeleteBody, parsePushSubscriptionBody, pushBodyMaxBytes, } from './push-registry.js';
|
|
@@ -399,41 +398,13 @@ export async function startWebServer(opts) {
|
|
|
399
398
|
targetScopes.add('local');
|
|
400
399
|
// §push — the server-side web-push registry + diff engine (design D8). One
|
|
401
400
|
// persisted, auth-scoped subscription registry; one locally-generated VAPID
|
|
402
|
-
// identity signing every send; one diff engine that re-reads canvas
|
|
403
|
-
//
|
|
404
|
-
//
|
|
401
|
+
// identity signing every send; one diff engine that re-reads the canvas on
|
|
402
|
+
// node invalidations received through eventHub.subscribe (no HTTP self-loop)
|
|
403
|
+
// and pushes done-transition notifications.
|
|
405
404
|
const pushRegistry = new PushRegistryStore();
|
|
406
405
|
const pushLastSeen = new PushLastSeenStore();
|
|
407
406
|
const vapid = loadOrCreateVapidKeypair();
|
|
408
407
|
webpush.setVapidDetails(vapid.subject, vapid.publicKey, vapid.privateKey);
|
|
409
|
-
// Page through every pending human ask, keeping only entries with the deck
|
|
410
|
-
// provenance (job + conversation) the payload/dedupe logic needs.
|
|
411
|
-
const collectPendingAsks = async () => {
|
|
412
|
-
const out = [];
|
|
413
|
-
let cursor;
|
|
414
|
-
for (let page = 0; page < 50; page++) {
|
|
415
|
-
const result = (await humanList.run({
|
|
416
|
-
limit: 100,
|
|
417
|
-
...(cursor !== undefined ? { cursor } : {}),
|
|
418
|
-
}));
|
|
419
|
-
for (const item of result.items) {
|
|
420
|
-
if (item.job_id === undefined || item.conversation_id === undefined)
|
|
421
|
-
continue;
|
|
422
|
-
out.push({
|
|
423
|
-
id: item.id,
|
|
424
|
-
jobId: item.job_id,
|
|
425
|
-
title: item.title ?? item.job_id,
|
|
426
|
-
conversationId: item.conversation_id,
|
|
427
|
-
conversationTitle: item.conversation_title ?? item.conversation_id,
|
|
428
|
-
blockedSince: item.blocked_since,
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
if (result.next_cursor === null)
|
|
432
|
-
break;
|
|
433
|
-
cursor = result.next_cursor;
|
|
434
|
-
}
|
|
435
|
-
return out;
|
|
436
|
-
};
|
|
437
408
|
const pushEngine = new PushDiffEngine({
|
|
438
409
|
registry: pushRegistry,
|
|
439
410
|
lastSeen: pushLastSeen,
|
|
@@ -445,7 +416,6 @@ export async function startWebServer(opts) {
|
|
|
445
416
|
const snap = (await canvasRosterLeaf.run({}));
|
|
446
417
|
return snap.nodes;
|
|
447
418
|
},
|
|
448
|
-
readPendingAsks: collectPendingAsks,
|
|
449
419
|
isTargetScope: (s) => targetScopes.has(s),
|
|
450
420
|
sendPush: async (record, payload) => {
|
|
451
421
|
try {
|
|
@@ -463,8 +433,6 @@ export async function startWebServer(opts) {
|
|
|
463
433
|
const unsubscribePush = eventHub.subscribe((kind) => {
|
|
464
434
|
if (kind === 'nodes')
|
|
465
435
|
void pushEngine.onNodesInvalidation();
|
|
466
|
-
else if (kind === 'inbox')
|
|
467
|
-
void pushEngine.onInboxInvalidation();
|
|
468
436
|
});
|
|
469
437
|
// Assigned before listen() when --dev; the request handler closes over it.
|
|
470
438
|
let vite;
|
|
@@ -191,84 +191,6 @@ export interface MessageRequest {
|
|
|
191
191
|
export interface ReviveRequest {
|
|
192
192
|
fresh?: boolean;
|
|
193
193
|
}
|
|
194
|
-
/**
|
|
195
|
-
* The five resolution flows (design §5.2). humanloop's `InteractionKind` also
|
|
196
|
-
* has `review`; the deck loader normalizes it (and any unknown/absent kind)
|
|
197
|
-
* onto one of these five so a deck always renders through a known flow.
|
|
198
|
-
*/
|
|
199
|
-
export type DeckKind = 'notify' | 'validation' | 'decision' | 'context' | 'error';
|
|
200
|
-
/** One option of a decision/validation interaction (humanloop InteractionOption). */
|
|
201
|
-
export interface DeckOption {
|
|
202
|
-
id: string;
|
|
203
|
-
label: string;
|
|
204
|
-
/** The option's consequence/explanation (humanloop `description`). */
|
|
205
|
-
description?: string;
|
|
206
|
-
}
|
|
207
|
-
/** One interaction within a deck (humanloop Interaction, normalized for the web). */
|
|
208
|
-
export interface DeckInteraction {
|
|
209
|
-
id: string;
|
|
210
|
-
title: string;
|
|
211
|
-
subtitle: string;
|
|
212
|
-
/** Markdown body (bodyPath already inlined by `crtr human deck`). */
|
|
213
|
-
body?: string;
|
|
214
|
-
kind: DeckKind;
|
|
215
|
-
options: DeckOption[];
|
|
216
|
-
multiSelect: boolean;
|
|
217
|
-
allowFreetext: boolean;
|
|
218
|
-
freetextLabel?: string;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* A pending ask, ranked in the inbox list (design §5.2). Provenance carries
|
|
222
|
-
* private node routing and an optional authored source label for presentation.
|
|
223
|
-
*/
|
|
224
|
-
export interface DeckSummary {
|
|
225
|
-
/** Opaque, stable inbox-entry id (base64url of the interaction dir). */
|
|
226
|
-
id: string;
|
|
227
|
-
/** The interaction job id (basename of the interaction dir). */
|
|
228
|
-
job_id: string;
|
|
229
|
-
/** The first interaction's kind — the glyph + flow for the row. */
|
|
230
|
-
kind: DeckKind;
|
|
231
|
-
title: string;
|
|
232
|
-
subtitle: string;
|
|
233
|
-
/** ISO-8601 — when the ask started blocking (drives the wait duration + rank). */
|
|
234
|
-
blocked_since: string;
|
|
235
|
-
/** Humanloop's current claim owner, when a person/session is handling it. */
|
|
236
|
-
claim_owner?: string;
|
|
237
|
-
/** Authored display label: source sessionName, then askedBy. */
|
|
238
|
-
source_label?: string;
|
|
239
|
-
/** The conversation (spine root) this ask belongs to. */
|
|
240
|
-
conversation_id: string;
|
|
241
|
-
conversation_title: string;
|
|
242
|
-
/** The node that raised the ask. */
|
|
243
|
-
asking_node_id: string;
|
|
244
|
-
asking_node_name: string;
|
|
245
|
-
/** The asking node's cwd — sub-DAG scoping. */
|
|
246
|
-
cwd: string;
|
|
247
|
-
/** How many interactions the deck holds (a multi-question deck). */
|
|
248
|
-
interaction_count: number;
|
|
249
|
-
}
|
|
250
|
-
/** The full deck for a resolution flow (`crtr human deck <id> --json`). */
|
|
251
|
-
export interface DeckDetail extends DeckSummary {
|
|
252
|
-
interactions: DeckInteraction[];
|
|
253
|
-
}
|
|
254
|
-
/** One interaction's answer (humanloop InteractionResponse). */
|
|
255
|
-
export interface DeckAnswer {
|
|
256
|
-
id: string;
|
|
257
|
-
selectedOptionId?: string;
|
|
258
|
-
selectedOptionIds?: string[];
|
|
259
|
-
freetext?: string;
|
|
260
|
-
optionComments?: Record<string, string>;
|
|
261
|
-
}
|
|
262
|
-
/** `crtr human resolve <id> --json` body. */
|
|
263
|
-
export interface ResolveDeckRequest {
|
|
264
|
-
responses: DeckAnswer[];
|
|
265
|
-
}
|
|
266
|
-
/** `crtr human resolve <id> --json` success. */
|
|
267
|
-
export interface ResolveDeckResponse {
|
|
268
|
-
resolved: true;
|
|
269
|
-
job_id: string;
|
|
270
|
-
delivered: boolean;
|
|
271
|
-
}
|
|
272
194
|
/**
|
|
273
195
|
* Engine state carried in `snapshot.state` — pi's OWN `get_state` payload, not a
|
|
274
196
|
* mirror of it. `BrokerSnapshot['state']` is this same type, so the welcome frame
|
|
@@ -290,33 +212,3 @@ export type DialogResponseValue = {
|
|
|
290
212
|
} | {
|
|
291
213
|
cancelled: true;
|
|
292
214
|
};
|
|
293
|
-
/**
|
|
294
|
-
* A typed content block within a view tab. Discriminated union of three
|
|
295
|
-
* block kinds: inline/sourced markdown, a KPI grid, and a bar-list chart.
|
|
296
|
-
*/
|
|
297
|
-
export type ViewBlock = {
|
|
298
|
-
kind: 'markdown';
|
|
299
|
-
source: {
|
|
300
|
-
node_id: string;
|
|
301
|
-
path: string;
|
|
302
|
-
} | {
|
|
303
|
-
inline: string;
|
|
304
|
-
};
|
|
305
|
-
} | {
|
|
306
|
-
kind: 'kpis';
|
|
307
|
-
items: {
|
|
308
|
-
label: string;
|
|
309
|
-
value: string;
|
|
310
|
-
unit?: string;
|
|
311
|
-
sub?: string;
|
|
312
|
-
}[];
|
|
313
|
-
} | {
|
|
314
|
-
kind: 'barlist';
|
|
315
|
-
title: string;
|
|
316
|
-
rows: {
|
|
317
|
-
label: string;
|
|
318
|
-
value: number;
|
|
319
|
-
max?: number;
|
|
320
|
-
note?: string;
|
|
321
|
-
}[];
|
|
322
|
-
};
|
|
@@ -81,7 +81,7 @@ const webServeLeaf = defineLeaf({
|
|
|
81
81
|
type: 'bool',
|
|
82
82
|
required: false,
|
|
83
83
|
default: false,
|
|
84
|
-
constraint: 'Serve shell assets via a Vite dev server (middleware mode, HMR) instead of the prebuilt dist/web-client/ bundle.
|
|
84
|
+
constraint: 'Serve shell assets via a Vite dev server (middleware mode, HMR) instead of the prebuilt dist/web-client/ bundle. The REST proxy, SSE lane, and WS relay are identical in both modes.',
|
|
85
85
|
},
|
|
86
86
|
],
|
|
87
87
|
output: [],
|
|
@@ -100,7 +100,7 @@ const webServeLeaf = defineLeaf({
|
|
|
100
100
|
const open = input['open'] ?? false;
|
|
101
101
|
const dev = input['dev'] ?? false;
|
|
102
102
|
const server = await startWebServer({ port, host, token, dev });
|
|
103
|
-
const nodeUrlShape = `${server.url}/
|
|
103
|
+
const nodeUrlShape = `${server.url}/nodes/<id>`;
|
|
104
104
|
const browserUrl = token !== undefined ? `${server.url}?token=${encodeURIComponent(token)}` : server.url;
|
|
105
105
|
process.stdout.write(`crtr surface web serving on ${server.url}${dev ? ' (--dev: Vite middleware)' : ''}\n` +
|
|
106
106
|
` open a node: ${nodeUrlShape}\n` +
|
|
@@ -10,9 +10,11 @@ import { tmpdir } from 'node:os';
|
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { randomBytes } from 'node:crypto';
|
|
12
12
|
import { Readable } from 'node:stream';
|
|
13
|
-
import { parseArgv } from '../../core/command.js';
|
|
13
|
+
import { parseArgv, unknownPathError } from '../../core/command.js';
|
|
14
14
|
import { renderLeafArgv } from '../../core/help.js';
|
|
15
15
|
import { humanAsk, sourceStamp } from '../human/prompts.js';
|
|
16
|
+
import { humanReviewBranch } from '../human/review.js';
|
|
17
|
+
import { registerHuman } from '../human.js';
|
|
16
18
|
import { coerceSingleSelectAgainst } from '../human/queue.js';
|
|
17
19
|
// ---------------------------------------------------------------------------
|
|
18
20
|
// Helper: write a temp JSON file and return its path.
|
|
@@ -37,32 +39,42 @@ async function withPipedStdin(body, fn) {
|
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
// ---------------------------------------------------------------------------
|
|
40
|
-
// human review — positional file (path) + required --subtitle + optional --output
|
|
42
|
+
// human review new — positional file (path) + required --subtitle + optional --output
|
|
41
43
|
// ---------------------------------------------------------------------------
|
|
42
|
-
describe('human review
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
describe('human review command branch', () => {
|
|
45
|
+
const review = registerHuman().children.find((child) => child.name === 'review');
|
|
46
|
+
const newLeaf = humanReviewBranch.children.find((child) => child.name === 'new' && child.kind === 'leaf');
|
|
47
|
+
test('registers the canonical review branch', () => {
|
|
48
|
+
assert.equal(review, humanReviewBranch);
|
|
49
|
+
assert.deepEqual(humanReviewBranch.children.map((child) => child.name), ['new', 'comment']);
|
|
50
|
+
});
|
|
51
|
+
test('bare review names valid children rather than accepting the legacy file positional', () => {
|
|
52
|
+
const error = unknownPathError(humanReviewBranch, ['human', 'review'], '/tmp/plan.md');
|
|
53
|
+
assert.equal(error.code, 'unknown_path');
|
|
54
|
+
assert.match(error.message, /unknown subcommand: \/tmp\/plan\.md/);
|
|
55
|
+
assert.match(String(error.details?.next), /Valid children: new, comment/);
|
|
56
|
+
});
|
|
57
|
+
test('new parses file + required subtitle', async () => {
|
|
58
|
+
assert.ok(newLeaf);
|
|
59
|
+
const result = await parseArgv(newLeaf.help.params ?? [], ['/tmp/plan.md', '--subtitle', 'Review this plan so implementation can begin safely.']);
|
|
50
60
|
assert.equal(result['file'], '/tmp/plan.md');
|
|
51
61
|
assert.equal(result['subtitle'], 'Review this plan so implementation can begin safely.');
|
|
52
62
|
});
|
|
53
|
-
test('parses file + subtitle + --output', async () => {
|
|
54
|
-
|
|
63
|
+
test('new parses file + subtitle + --output', async () => {
|
|
64
|
+
assert.ok(newLeaf);
|
|
65
|
+
const result = await parseArgv(newLeaf.help.params ?? [], ['/tmp/plan.md', '--subtitle', 'Review this plan so implementation can begin safely.', '--output', '/tmp/fb.json']);
|
|
55
66
|
assert.equal(result['file'], '/tmp/plan.md');
|
|
56
67
|
assert.equal(result['output'], '/tmp/fb.json');
|
|
57
68
|
});
|
|
58
69
|
// Validation is complete, never first-failure: one invocation yields ONE
|
|
59
70
|
// error naming every missing required parameter, and its Next: mandates the
|
|
60
71
|
// schema read rather than patching the first field.
|
|
61
|
-
test('missing file AND
|
|
62
|
-
|
|
72
|
+
test('new missing file AND subtitle throws ONE missing_parameter naming both', async () => {
|
|
73
|
+
assert.ok(newLeaf);
|
|
74
|
+
await assert.rejects(() => parseArgv(newLeaf.help.params ?? [], [], { leafPath: ['human', 'review', 'new'] }), (err) => {
|
|
63
75
|
assert.match(err.message, /required parameters are missing: positional FILE, --subtitle/);
|
|
64
76
|
assert.equal(err.details?.field, 'file, subtitle');
|
|
65
|
-
assert.match(err.details?.next ?? '', /Run `crtr human review -h` and read the full schema before re-issuing/);
|
|
77
|
+
assert.match(err.details?.next ?? '', /Run `crtr human review new -h` and read the full schema before re-issuing/);
|
|
66
78
|
return true;
|
|
67
79
|
});
|
|
68
80
|
});
|
|
@@ -20,7 +20,7 @@ import { CrtrClient, ApiError } from '../api/index.js';
|
|
|
20
20
|
import { apiErrorToCliError } from '../core/io.js';
|
|
21
21
|
import { ensureDaemon, DAEMON_VERIFY_WINDOW_MS } from '../daemon/manage.js';
|
|
22
22
|
import { readState } from '../core/config.js';
|
|
23
|
-
import { resolveRemoteCanvasTarget } from '../core/
|
|
23
|
+
import { resolveRemoteCanvasTarget } from '../core/remote-canvas-target.js';
|
|
24
24
|
import { RemoteCanvasSource } from '../core/canvas/remote-canvas-source.js';
|
|
25
25
|
import { crtrHome } from '../core/canvas/paths.js';
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
@@ -186,8 +186,8 @@ function summaryToRow(s) {
|
|
|
186
186
|
}
|
|
187
187
|
/** `NodeDetailDTO` → `NodeMeta`. Populates the durable-identity ∪ runtime fields
|
|
188
188
|
* the DTO projects; the durable LAUNCH-RECIPE facts a projection cannot carry
|
|
189
|
-
* (`launch`/`env`, `persona_ack`, `
|
|
190
|
-
* `
|
|
189
|
+
* (`launch`/`env`, `persona_ack`, `model_override`, `passive_default`,
|
|
190
|
+
* `fork_from`, `pi_session_file`,
|
|
191
191
|
* `cycle_pending`) are left undefined — read-only viewer/inspect consumers
|
|
192
192
|
* (Stage B-7/B-9) never read them; the daemon owns the full meta for revive. */
|
|
193
193
|
function detailToMeta(d) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { defineLeaf } from '../core/command.js';
|
|
9
9
|
import { runBrowse } from '../core/canvas/browse/app.js';
|
|
10
10
|
import { cliClient, cliCanvasSource } from './api-client.js';
|
|
11
|
-
import { resolveRemoteCanvasTarget } from '../core/
|
|
11
|
+
import { resolveRemoteCanvasTarget } from '../core/remote-canvas-target.js';
|
|
12
12
|
import { RemoteEventStream } from '../core/canvas/remote-event-stream.js';
|
|
13
13
|
import { readState } from '../core/config.js';
|
|
14
14
|
import { getDefaultProfileId } from '../core/profiles/default-binding.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// `crtr canvas issue new` — capture a quick todo/idea/bug into a GitHub issue.
|
|
2
2
|
//
|
|
3
|
-
// Bound to the alt+c →
|
|
3
|
+
// Bound to the alt+c → c → (idea|bug) prefix chord: the menu opens a tmux
|
|
4
4
|
// display-popup that runs this leaf in the originating pane's cwd (the popup is
|
|
5
5
|
// started with `-d #{pane_current_path}`). The leaf:
|
|
6
6
|
// 1. reads a free-text note from the popup's TTY (type, Ctrl-D to submit),
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { defineLeaf } from '../core/command.js';
|
|
6
6
|
import { InputError } from '../core/io.js';
|
|
7
7
|
import { updateState } from '../core/config.js';
|
|
8
|
-
import { getRemoteCanvasTarget } from '../core/
|
|
8
|
+
import { getRemoteCanvasTarget } from '../core/remote-canvas-target.js';
|
|
9
9
|
const SCOPE = 'user';
|
|
10
10
|
export const canvasUseLeaf = defineLeaf({
|
|
11
11
|
name: 'use',
|