@north-light/crouter 0.3.172 → 0.3.174
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/runtime-selector.mjs +8 -1
- package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
- package/dist/api/client.d.ts +12 -21
- package/dist/api/client.js +22 -31
- package/dist/api/dto/broker-ops.d.ts +158 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/crons.d.ts +6 -0
- package/dist/api/dto/human.d.ts +7 -1
- package/dist/api/dto/inbox.d.ts +1 -71
- package/dist/api/dto/inbox.js +1 -9
- package/dist/api/dto/nodes.d.ts +6 -7
- package/dist/api/dto/reviews.d.ts +1 -11
- package/dist/api/routes.d.ts +7 -4
- package/dist/api/routes.js +8 -5
- package/dist/build-root.js +3 -3
- package/dist/builtin-memory/04-base-worker.md +1 -4
- package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
- package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
- package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
- package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
- package/dist/builtin-memory/advisor/council.md +1 -6
- package/dist/builtin-memory/design.md +2 -7
- package/dist/builtin-memory/development.md +9 -14
- package/dist/builtin-memory/internal/marketplaces.md +2 -6
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +2 -8
- package/dist/builtin-memory/internal/storage-tiers.md +1 -2
- package/dist/builtin-memory/testing.md +41 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +106 -177
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +55 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +60 -0
- package/dist/cli.js +2 -2
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
- package/dist/clients/attach/__tests__/context-message.test.js +16 -174
- package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
- package/dist/clients/attach/__tests__/diagram.test.js +2 -2
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
- package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
- package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
- package/dist/clients/attach/command.d.ts +2 -1
- package/dist/clients/attach/command.js +81 -76
- package/dist/clients/attach/input/capabilities.d.ts +27 -0
- package/dist/clients/attach/input/capabilities.js +96 -0
- package/dist/clients/attach/input/controller.d.ts +20 -182
- package/dist/clients/attach/input/controller.js +128 -537
- package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
- package/dist/clients/attach/input/overlay-owner.js +199 -0
- package/dist/clients/attach/overlays/file-review.d.ts +0 -4
- package/dist/clients/attach/overlays/file-review.js +13 -5
- package/dist/clients/attach/overlays/graph.js +2 -10
- package/dist/clients/attach/render/chat-view.d.ts +4 -3
- package/dist/clients/attach/render/chat-view.js +39 -33
- package/dist/clients/attach/render/group-activity.d.ts +1 -0
- package/dist/clients/attach/render/group-activity.js +20 -13
- package/dist/clients/attach/render/group-recap.js +12 -3
- package/dist/clients/attach/session/connection.js +9 -15
- package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
- package/dist/clients/attach/session/editor-inventory.js +7 -8
- package/dist/clients/attach/session/file-links.d.ts +13 -0
- package/dist/clients/attach/session/file-links.js +107 -0
- package/dist/clients/attach/session/frame.d.ts +3 -0
- package/dist/clients/attach/session/frame.js +10 -1
- package/dist/clients/attach/session/frames.js +2 -3
- package/dist/clients/attach/session/input-wiring.d.ts +4 -1
- package/dist/clients/attach/session/input-wiring.js +15 -14
- package/dist/clients/attach/session/mouse.d.ts +6 -1
- package/dist/clients/attach/session/mouse.js +8 -5
- package/dist/clients/attach/session/profile-files.js +18 -12
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/session/state-sync.js +1 -2
- package/dist/clients/attach/session/surface-host.d.ts +3 -2
- package/dist/clients/attach/session/surface-host.js +4 -4
- package/dist/clients/attach/slash/dispatch.d.ts +8 -31
- package/dist/clients/attach/slash/dispatch.js +34 -81
- package/dist/clients/attach/viewer.js +820 -860
- package/dist/clients/conversation/projection.d.ts +79 -0
- package/dist/clients/conversation/projection.js +341 -0
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
- package/dist/clients/inbox/controller.d.ts +0 -4
- package/dist/clients/inbox/controller.js +0 -2
- package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
- package/dist/clients/inbox/review/comments-client.d.ts +3 -2
- package/dist/clients/inbox/review/comments-client.js +12 -12
- package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
- package/dist/clients/inbox/review/companion-pane.js +86 -0
- package/dist/clients/inbox/review/document-surface.d.ts +182 -0
- package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
- package/dist/clients/inbox/review/frame.js +5 -4
- package/dist/clients/inbox/review/launch.d.ts +8 -8
- package/dist/clients/inbox/review/launch.js +52 -92
- package/dist/clients/inbox/review/nvim.d.ts +2 -0
- package/dist/clients/inbox/review/nvim.js +14 -12
- package/dist/clients/inbox/review/review-client.d.ts +12 -8
- package/dist/clients/inbox/review/review-client.js +46 -35
- package/dist/clients/inbox/review-adapter.d.ts +3 -10
- package/dist/clients/inbox/review-adapter.js +27 -19
- package/dist/clients/inbox/surface.d.ts +0 -4
- package/dist/clients/inbox/surface.js +0 -2
- package/dist/clients/surfaces/host.d.ts +11 -3
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
- package/dist/commands/__tests__/human.test.js +11 -322
- package/dist/commands/api-client.d.ts +5 -5
- package/dist/commands/api-client.js +6 -85
- package/dist/commands/canvas-browse.js +3 -29
- package/dist/commands/canvas-config.js +1 -1
- package/dist/commands/canvas-use.js +3 -3
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/cron.js +5 -1
- package/dist/commands/human/queue.d.ts +0 -4
- package/dist/commands/human/queue.js +7 -40
- package/dist/commands/memory/list.d.ts +14 -0
- package/dist/commands/memory/list.js +35 -31
- package/dist/commands/memory/read.d.ts +7 -0
- package/dist/commands/memory/read.js +14 -8
- package/dist/commands/node/bash.d.ts +1 -0
- package/dist/commands/node/bash.js +198 -0
- package/dist/commands/node/create.d.ts +23 -0
- package/dist/commands/node/create.js +207 -0
- package/dist/commands/node/inspect.d.ts +2 -0
- package/dist/commands/node/inspect.js +302 -0
- package/dist/commands/node/lifecycle.d.ts +4 -0
- package/dist/commands/node/lifecycle.js +415 -0
- package/dist/commands/node/message.d.ts +1 -0
- package/dist/commands/node/message.js +164 -0
- package/dist/commands/node/pyramid.d.ts +2 -0
- package/dist/commands/node/pyramid.js +79 -0
- package/dist/commands/node/subscription.d.ts +1 -0
- package/dist/commands/node/subscription.js +82 -0
- package/dist/commands/node/wait.d.ts +1 -0
- package/dist/commands/node/wait.js +159 -0
- package/dist/commands/node-lifecycle-revive.js +10 -57
- package/dist/commands/node.d.ts +0 -42
- package/dist/commands/node.js +11 -2065
- package/dist/commands/search.js +1 -1
- package/dist/commands/surface/node/cycle.d.ts +1 -0
- package/dist/commands/surface/node/cycle.js +83 -0
- package/dist/commands/surface/node/focus.d.ts +1 -0
- package/dist/commands/surface/node/focus.js +67 -0
- package/dist/commands/surface/node/id.d.ts +1 -0
- package/dist/commands/surface/node/id.js +38 -0
- package/dist/commands/surface/node/pin.d.ts +1 -0
- package/dist/commands/surface/node/pin.js +42 -0
- package/dist/commands/surface/node/placement.d.ts +46 -0
- package/dist/commands/surface/node/placement.js +124 -0
- package/dist/commands/surface-node.js +4 -1
- package/dist/commands/surface-reload.js +1 -2
- package/dist/commands/surface-tmux-spread.js +1 -1
- package/dist/commands/surface.js +5 -20
- package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
- package/dist/commands/sys/config.js +6 -6
- package/dist/commands/sys/logs.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
- package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
- package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
- package/dist/commands/sys/panels/dependencies-panel.js +80 -0
- package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
- package/dist/commands/sys/panels/keybindings-panel.js +703 -0
- package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
- package/dist/commands/sys/panels/keys-panel.js +60 -0
- package/dist/commands/sys/panels/models-panel.d.ts +77 -0
- package/dist/commands/sys/panels/models-panel.js +647 -0
- package/dist/commands/sys/panels/panel.d.ts +45 -0
- package/dist/commands/sys/panels/panel.js +137 -0
- package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
- package/dist/commands/sys/panels/plugins-panel.js +80 -0
- package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
- package/dist/commands/sys/panels/prefs-panel.js +85 -0
- package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
- package/dist/commands/sys/panels/provider-panel.js +538 -0
- package/dist/commands/sys/settings-shell.d.ts +55 -0
- package/dist/commands/sys/settings-shell.js +400 -0
- package/dist/commands/sys/settings.d.ts +2 -0
- package/dist/commands/sys/settings.js +31 -0
- package/dist/commands/sys/setup-core.d.ts +3 -33
- package/dist/commands/sys/setup-core.js +27 -78
- package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
- package/dist/commands/sys/setup-settings-runner.js +63 -0
- package/dist/commands/sys/setup-wizard.d.ts +26 -125
- package/dist/commands/sys/setup-wizard.js +209 -2473
- package/dist/commands/sys/setup.js +5 -7
- package/dist/commands/sys.js +3 -2
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
- package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
- package/dist/core/__tests__/broker-preflight.test.js +1 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
- package/dist/core/__tests__/canvas.test.js +2 -36
- package/dist/core/__tests__/close.test.js +14 -3
- package/dist/core/__tests__/context-intro.test.js +32 -143
- package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
- package/dist/core/__tests__/daemon-boot.test.js +2 -20
- package/dist/core/__tests__/daemon-wedge.test.js +1 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +4 -98
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
- package/dist/core/__tests__/helpers/broker-clients.js +0 -14
- package/dist/core/__tests__/helpers/harness.d.ts +0 -8
- package/dist/core/__tests__/helpers/harness.js +7 -87
- package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
- package/dist/core/__tests__/kickoff.test.js +1 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
- package/dist/core/__tests__/migration.test.js +35 -48
- package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
- package/dist/core/__tests__/passive-subscription.test.js +26 -49
- package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
- package/dist/core/__tests__/prune.test.js +94 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -32
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
- package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
- package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
- package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
- package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
- package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
- package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
- package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
- package/dist/core/__tests__/secrets.test.js +1 -7
- package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
- package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
- package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
- package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
- package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
- package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
- package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
- package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
- package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
- package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
- package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
- package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
- package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
- package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
- package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
- package/dist/core/__tests__/session-model.test.js +0 -18
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
- package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
- package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
- package/dist/core/broker-client/client.d.ts +2 -2
- package/dist/core/broker-client/client.js +4 -7
- package/dist/core/broker-client/transport-relay.d.ts +13 -19
- package/dist/core/broker-client/transport-relay.js +19 -34
- package/dist/core/broker-client/transport-socket.d.ts +2 -2
- package/dist/core/broker-client/transport-socket.js +9 -2
- package/dist/core/broker-client/transport.d.ts +7 -3
- package/dist/core/broker-client/transport.js +4 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -18
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
- package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
- package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
- package/dist/core/canvas/browse/app.d.ts +2 -17
- package/dist/core/canvas/browse/app.js +16 -88
- package/dist/core/canvas/browse/model.d.ts +0 -4
- package/dist/core/canvas/browse/model.js +1 -12
- package/dist/core/canvas/browse/render.js +6 -3
- package/dist/core/canvas/crons.d.ts +8 -5
- package/dist/core/canvas/crons.js +7 -6
- package/dist/core/canvas/extensions.d.ts +7 -3
- package/dist/core/canvas/extensions.js +16 -4
- package/dist/core/canvas/nav-model.d.ts +0 -4
- package/dist/core/canvas/nav-model.js +2 -14
- package/dist/core/canvas/node-order.d.ts +3 -0
- package/dist/core/canvas/node-order.js +12 -0
- package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
- package/dist/core/canvas/remote-canvas-source.js +8 -15
- package/dist/core/command.js +11 -4
- package/dist/core/config.js +3 -1
- package/dist/core/events/envelope.js +1 -1
- package/dist/core/events/read.js +7 -21
- package/dist/core/events/source.d.ts +0 -2
- package/dist/core/events/source.js +0 -16
- package/dist/core/events/types.d.ts +1 -1
- package/dist/core/fault-classifier.d.ts +1 -1
- package/dist/core/feed/passive.d.ts +0 -11
- package/dist/core/feed/passive.js +1 -62
- package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
- package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
- package/dist/core/keybindings/background-bash.js +3 -4
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/memory/inline-ref-grammar.js +3 -3
- package/dist/core/memory-resolver.d.ts +11 -25
- package/dist/core/memory-resolver.js +51 -33
- package/dist/core/model-routes.d.ts +15 -0
- package/dist/core/model-routes.js +12 -0
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/preview-registry.js +8 -9
- package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
- package/dist/core/review/realize.d.ts +0 -13
- package/dist/core/review/realize.js +0 -40
- package/dist/core/review/types.d.ts +1 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
- package/dist/core/runtime/bearings.js +1 -11
- package/dist/core/runtime/broker/client-registry.d.ts +33 -0
- package/dist/core/runtime/broker/client-registry.js +164 -0
- package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
- package/dist/core/runtime/broker/daemon-ops.js +49 -0
- package/dist/core/runtime/broker/event-projection.d.ts +42 -0
- package/dist/core/runtime/broker/event-projection.js +178 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
- package/dist/core/runtime/broker/fault-retry.js +277 -0
- package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
- package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
- package/dist/core/runtime/broker/inbox.d.ts +22 -0
- package/dist/core/runtime/broker/inbox.js +167 -0
- package/dist/core/runtime/broker/passive.d.ts +16 -0
- package/dist/core/runtime/broker/passive.js +44 -0
- package/dist/core/runtime/broker/read-ops.d.ts +23 -0
- package/dist/core/runtime/broker/read-ops.js +150 -0
- package/dist/core/runtime/broker/rebind.d.ts +74 -0
- package/dist/core/runtime/broker/rebind.js +211 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
- package/dist/core/runtime/broker/tool-groups.js +244 -0
- package/dist/core/runtime/broker-extension-render.d.ts +11 -0
- package/dist/core/runtime/broker-extension-render.js +181 -0
- package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
- package/dist/core/runtime/broker-persona-guidance.js +58 -0
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/broker-protocol.js +1 -1
- package/dist/core/runtime/broker.d.ts +5 -196
- package/dist/core/runtime/broker.js +276 -3059
- package/dist/core/runtime/canvas-extensions.js +11 -2
- package/dist/core/runtime/fault.js +1 -1
- package/dist/core/runtime/model-selection.d.ts +9 -0
- package/dist/core/runtime/model-selection.js +12 -0
- package/dist/core/runtime/model-swap.d.ts +3 -3
- package/dist/core/runtime/model-swap.js +33 -25
- package/dist/core/runtime/placement-tmux.d.ts +3 -14
- package/dist/core/runtime/placement-tmux.js +11 -80
- package/dist/core/runtime/placement.d.ts +4 -2
- package/dist/core/runtime/placement.js +7 -12
- package/dist/core/runtime/promote.d.ts +14 -1
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/reset.d.ts +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/runtime/spawn.d.ts +8 -0
- package/dist/core/runtime/spawn.js +36 -6
- package/dist/core/runtime/stop-guard.d.ts +4 -3
- package/dist/core/runtime/stop-guard.js +36 -18
- package/dist/core/runtime/stop-signals.d.ts +4 -1
- package/dist/core/runtime/stream-watchdog.js +4 -5
- package/dist/core/runtime/structured-output.d.ts +15 -2
- package/dist/core/runtime/structured-output.js +35 -12
- package/dist/core/runtime/tmux-bindings.d.ts +25 -0
- package/dist/core/runtime/tmux-bindings.js +682 -0
- package/dist/core/runtime/tmux-chrome.d.ts +2 -1
- package/dist/core/runtime/tmux-chrome.js +3 -2
- package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
- package/dist/core/runtime/tmux-driver.js +598 -0
- package/dist/core/runtime/view-socket.d.ts +14 -0
- package/dist/core/runtime/view-socket.js +83 -0
- package/dist/core/session-model/session-state.d.ts +1 -2
- package/dist/core/session-model/session-state.js +5 -8
- package/dist/core/spawn.d.ts +1 -1
- package/dist/core/spawn.js +2 -2
- package/dist/core/substrate/gate.d.ts +1 -1
- package/dist/core/substrate/on-read-pure.d.ts +7 -0
- package/dist/core/substrate/on-read-pure.js +272 -0
- package/dist/core/termrender/termrender.js +32 -2
- package/dist/core/user-settings.d.ts +23 -1
- package/dist/core/user-settings.js +18 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
- package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
- package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
- package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
- package/dist/daemon/api/bridge.js +40 -81
- package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
- package/dist/daemon/api/handlers/broker-ops.js +383 -0
- package/dist/daemon/api/handlers/crons.js +9 -4
- package/dist/daemon/api/handlers/files.js +6 -7
- package/dist/daemon/api/handlers/inbox.js +2 -340
- package/dist/daemon/api/handlers/nodes.d.ts +10 -1
- package/dist/daemon/api/handlers/nodes.js +74 -39
- package/dist/daemon/api/handlers/review-comments.js +5 -1
- package/dist/daemon/api/handlers/reviews.js +0 -19
- package/dist/daemon/api/map.js +25 -4
- package/dist/daemon/api/router.js +2 -3
- package/dist/daemon/api/server.js +5 -7
- package/dist/daemon/cron-run.d.ts +4 -0
- package/dist/daemon/cron-run.js +30 -13
- package/dist/daemon/crtrd.d.ts +3 -58
- package/dist/daemon/crtrd.js +28 -1244
- package/dist/daemon/manage.js +0 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
- package/dist/daemon/reconcilers/broker-supervision.js +549 -0
- package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
- package/dist/daemon/reconcilers/cron-lane.js +32 -0
- package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
- package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
- package/dist/daemon/review/finish.js +2 -5
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
- package/dist/pi-extensions/broker-local.d.ts +20 -0
- package/dist/pi-extensions/broker-local.js +89 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
- package/dist/pi-extensions/canvas-context-intro.js +22 -11
- package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
- package/dist/pi-extensions/canvas-goal-capture.js +7 -12
- package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
- package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
- package/dist/pi-extensions/canvas-passive-context.js +22 -18
- package/dist/pi-extensions/canvas-recap.d.ts +2 -2
- package/dist/pi-extensions/canvas-recap.js +48 -21
- package/dist/pi-extensions/canvas-review-boundary.js +10 -4
- package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
- package/dist/pi-extensions/canvas-stophook.js +149 -431
- package/dist/pi-extensions/canvas-structured-output.js +52 -30
- package/dist/pi-extensions/envelope-merge.d.ts +13 -0
- package/dist/pi-extensions/envelope-merge.js +29 -0
- package/dist/shared/working-activity.d.ts +3 -2
- package/dist/shared/working-activity.js +3 -2
- package/dist/types.d.ts +6 -5
- package/dist/types.js +2 -2
- package/docs/compat/hearth-crtr-v1.md +4 -12
- package/docs/compat/hearth-crtr-v2.md +3 -11
- package/docs/compat/hearth-crtr-v3.md +4 -12
- package/docs/compat/hearth-crtr-v4.md +3 -11
- package/docs/compat/hearth-crtr-v5.md +3 -11
- package/docs/public-api.md +3 -7
- package/package.json +7 -49
- package/runtime.lock.json +2766 -14533
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
- package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
- package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
- package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
- package/dist/clients/conversation/conversation.d.ts +0 -65
- package/dist/clients/conversation/conversation.js +0 -318
- package/dist/clients/conversation/frames.d.ts +0 -30
- package/dist/clients/conversation/frames.js +0 -52
- package/dist/clients/conversation/region.d.ts +0 -51
- package/dist/clients/conversation/region.js +0 -265
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
- package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
- package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
- package/dist/clients/inbox/review/columns.d.ts +0 -22
- package/dist/clients/inbox/review/columns.js +0 -40
- package/dist/clients/inbox/review/composition.d.ts +0 -60
- package/dist/clients/inbox/review/composition.js +0 -278
- package/dist/clients/inbox/review/document-region.d.ts +0 -120
- package/dist/clients/surfaces/region.d.ts +0 -16
- package/dist/clients/web/__tests__/push-engine.test.js +0 -158
- package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
- package/dist/clients/web/__tests__/push-registry.test.js +0 -177
- package/dist/clients/web/dev-server.d.ts +0 -7
- package/dist/clients/web/dev-server.js +0 -46
- package/dist/clients/web/events.d.ts +0 -19
- package/dist/clients/web/events.js +0 -163
- package/dist/clients/web/push-engine.d.ts +0 -44
- package/dist/clients/web/push-engine.js +0 -125
- package/dist/clients/web/push-registry.d.ts +0 -85
- package/dist/clients/web/push-registry.js +0 -373
- package/dist/clients/web/server.d.ts +0 -19
- package/dist/clients/web/server.js +0 -661
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
- package/dist/clients/web/web-client/shared/protocol.js +0 -8
- package/dist/clients/web/web-cmd.d.ts +0 -2
- package/dist/clients/web/web-cmd.js +0 -141
- package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
- package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
- package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
- package/dist/commands/__tests__/canvas-config.test.js +0 -107
- package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
- package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
- package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
- package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
- package/dist/commands/__tests__/search-contents.test.js +0 -52
- package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/lint.test.js +0 -15
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
- package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
- package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
- package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
- package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
- package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
- package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
- package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
- package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
- package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
- package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
- package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
- package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
- package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
- package/dist/core/__tests__/finalization-migration.test.js +0 -38
- package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
- package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
- package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
- package/dist/core/__tests__/fork.test.d.ts +0 -1
- package/dist/core/__tests__/fork.test.js +0 -108
- package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
- package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
- package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
- package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
- package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
- package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
- package/dist/core/__tests__/full/cascade-close.test.js +0 -240
- package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/detach-focus.test.js +0 -126
- package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
- package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
- package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
- package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
- package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
- package/dist/core/__tests__/memory-index-render.test.js +0 -60
- package/dist/core/__tests__/model-routes.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes.test.js +0 -41
- package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-identity.test.js +0 -61
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
- package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
- package/dist/core/__tests__/prune-to-limit.test.js +0 -126
- package/dist/core/__tests__/reset.test.d.ts +0 -1
- package/dist/core/__tests__/reset.test.js +0 -69
- package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
- package/dist/core/__tests__/steer-note.test.d.ts +0 -1
- package/dist/core/__tests__/steer-note.test.js +0 -41
- package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
- package/dist/core/__tests__/subcommand-tier.test.js +0 -99
- package/dist/core/__tests__/subscription-delivery.test.js +0 -211
- package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
- package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
- package/dist/core/__tests__/tmux-surface.test.js +0 -484
- package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
- package/dist/core/__tests__/wake-bearings.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
- package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
- package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
- package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
- package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
- package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
- package/dist/core/canvas/remote-event-stream.d.ts +0 -24
- package/dist/core/canvas/remote-event-stream.js +0 -94
- package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
- package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
- package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
- package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
- package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
- package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
- package/dist/core/human/__tests__/visible-paths.test.js +0 -28
- package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
- package/dist/core/review/__tests__/project.test.d.ts +0 -1
- package/dist/core/review/__tests__/project.test.js +0 -71
- package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
- package/dist/core/runtime/tmux.js +0 -1314
- package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
- package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/inbox.test.js +0 -489
- package/dist/web-client/apple-touch-icon.png +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
- package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
- package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
- package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
- package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
- package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
- package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
- package/dist/web-client/icon-192.png +0 -0
- package/dist/web-client/icon-512.png +0 -0
- package/dist/web-client/icon-maskable-512.png +0 -0
- package/dist/web-client/index.html +0 -17
- package/dist/web-client/manifest.webmanifest +0 -1
- package/dist/web-client/sw.js +0 -1
- /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
- /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
- /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
- /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
- /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
- /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
- /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
- /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
- /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
- /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
- /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
- /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
- /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
- /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
- /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
- /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
- /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
- /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
- /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
- /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
- /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import type { SurfaceRegion } from '../../surfaces/region.js';
|
|
2
|
-
import { type CommentAuthority } from './comments-client.js';
|
|
3
|
-
import type { LiveSource } from './live-source.js';
|
|
4
|
-
/** What the composed owner supplies a region that cannot own the pane itself.
|
|
5
|
-
*
|
|
6
|
-
* `submit` exists because the approved leader table keeps `space s` on the
|
|
7
|
-
* document region while the review lifecycle adapter belongs to the composed
|
|
8
|
-
* owner: the region reports the intent, the owner runs `reviewClient.submit`. */
|
|
9
|
-
export interface CompositionServices {
|
|
10
|
-
notice(text: string): void;
|
|
11
|
-
suspendForChild(): () => void;
|
|
12
|
-
requestClose(): void;
|
|
13
|
-
submit(): void;
|
|
14
|
-
}
|
|
15
|
-
export interface DocumentRegionOptions {
|
|
16
|
-
reviewId: string;
|
|
17
|
-
absFile: string;
|
|
18
|
-
cwd: string;
|
|
19
|
-
source: LiveSource;
|
|
20
|
-
comments: CommentAuthority;
|
|
21
|
-
services: CompositionServices;
|
|
22
|
-
}
|
|
23
|
-
/** The reviewed document as a composed region: existing review rendering and
|
|
24
|
-
* navigation over a live file, with comments projected from the daemon and
|
|
25
|
-
* ranges remapped by this terminal as the file changes. */
|
|
26
|
-
export declare class DocumentRegion implements SurfaceRegion {
|
|
27
|
-
private readonly absFile;
|
|
28
|
-
private readonly fileLabel;
|
|
29
|
-
private readonly kind;
|
|
30
|
-
private readonly source;
|
|
31
|
-
private readonly comments;
|
|
32
|
-
private readonly services;
|
|
33
|
-
private readonly unsubscribeComments;
|
|
34
|
-
private readonly ready;
|
|
35
|
-
private cols;
|
|
36
|
-
private rows;
|
|
37
|
-
private focused;
|
|
38
|
-
private closed;
|
|
39
|
-
private spaceArmed;
|
|
40
|
-
private state;
|
|
41
|
-
private cache;
|
|
42
|
-
/** Every non-deleted comment the daemon currently projects, newest last. */
|
|
43
|
-
private projection;
|
|
44
|
-
private status;
|
|
45
|
-
/** Region-local error/summary state — never a host notice (D1). */
|
|
46
|
-
private problem;
|
|
47
|
-
private composeAnchorLost;
|
|
48
|
-
private dirty;
|
|
49
|
-
/** Serializes base-hash transitions so B→C cannot overtake A→B. */
|
|
50
|
-
private remapChain;
|
|
51
|
-
constructor(opts: DocumentRegionOptions);
|
|
52
|
-
/** Resolves once the daemon coordinate base has been aligned to the file on
|
|
53
|
-
* disk. The owner may await it so the first painted frame already carries
|
|
54
|
-
* current ranges; painting earlier shows only a preparing line, never a
|
|
55
|
-
* comment at a coordinate the daemon has not accepted. */
|
|
56
|
-
open(): Promise<void>;
|
|
57
|
-
hasUnsentCompose(): boolean;
|
|
58
|
-
setViewport(cols: number, rows: number): void;
|
|
59
|
-
render(): string[];
|
|
60
|
-
handleInput(data: string): boolean;
|
|
61
|
-
handleWheel(direction: 'up' | 'down', lines: number): boolean;
|
|
62
|
-
setFocused(value: boolean): void;
|
|
63
|
-
summary(): string;
|
|
64
|
-
onDirty(fn: () => void): void;
|
|
65
|
-
/** Releases this region's render cache and stops every projected repaint.
|
|
66
|
-
* This region closes the source it was handed; that close stops its watcher. */
|
|
67
|
-
close(): void;
|
|
68
|
-
/** Bring the daemon's comment coordinates onto the bytes now on disk, then
|
|
69
|
-
* build the first state from what the daemon accepted. The zero-comment case
|
|
70
|
-
* still submits its batch: the base digest itself is what advances, and a
|
|
71
|
-
* later create against current bytes is rejected until it does. */
|
|
72
|
-
private align;
|
|
73
|
-
private movedSince;
|
|
74
|
-
/** Re-derive this region from the daemon's own coordinate base. The only
|
|
75
|
-
* honest recovery once a batch is rejected: the local map that produced it
|
|
76
|
-
* is no longer a true description of what the daemon holds. */
|
|
77
|
-
private realign;
|
|
78
|
-
private buildState;
|
|
79
|
-
private onSourceChanged;
|
|
80
|
-
/** One transaction covering every non-deleted comment. A rejection is stated
|
|
81
|
-
* in this region's own footer and the projection is re-read from the
|
|
82
|
-
* authority, which is the only thing that can still be true afterwards. */
|
|
83
|
-
private submitBatch;
|
|
84
|
-
private refreshProjection;
|
|
85
|
-
private mutate;
|
|
86
|
-
private handleComposeKey;
|
|
87
|
-
private handleLeaderKey;
|
|
88
|
-
private handleListKey;
|
|
89
|
-
private handleViewKey;
|
|
90
|
-
/** The reviewed file is the deliverable: the person's own editor writes it,
|
|
91
|
-
* this region never does. The source is re-read the moment the editor exits
|
|
92
|
-
* rather than waiting for the watcher's coalescing window. */
|
|
93
|
-
private editInEditor;
|
|
94
|
-
/** The composition owns cursor focus; its focused document region contributes
|
|
95
|
-
* exactly one whole marker at the same visual location the document already
|
|
96
|
-
* calls active. There is deliberately no synthetic fallback row: a marker is
|
|
97
|
-
* only valid when it belongs to a rendered anchor or the compose/list cursor. */
|
|
98
|
-
private markCursorLocation;
|
|
99
|
-
/** The frame paints source rows after its three-line header. Scroll indicators
|
|
100
|
-
* replace their source rows, so they are never cursor targets. */
|
|
101
|
-
private activeAnchorFrameRow;
|
|
102
|
-
private reflow;
|
|
103
|
-
private document;
|
|
104
|
-
private bodyHeight;
|
|
105
|
-
private composeWidth;
|
|
106
|
-
private gutterWidth;
|
|
107
|
-
/** The region's own footer line: its error, then its stale verdict. */
|
|
108
|
-
private footerLine;
|
|
109
|
-
private renderPlaceholder;
|
|
110
|
-
/** `frame.ts` renders the ordinary list. Detached anchors need stronger
|
|
111
|
-
* treatment: their own leading group plus the original range and snippet,
|
|
112
|
-
* because no document marker can lead a person back to them. */
|
|
113
|
-
private renderGroupedList;
|
|
114
|
-
/** The compose header states a lost anchor where the person is already
|
|
115
|
-
* looking, leaving the footer's compose keys intact. */
|
|
116
|
-
private statedComposeAnchor;
|
|
117
|
-
private commentListRow;
|
|
118
|
-
private topVisibleSourceLine;
|
|
119
|
-
private repaint;
|
|
120
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface SurfaceRegion {
|
|
2
|
-
/** Geometry is PUSHED. A region never reads terminal or process geometry. */
|
|
3
|
-
setViewport(cols: number, rows: number): void;
|
|
4
|
-
/** Exactly `rows` lines, each ≤ `cols` display cells. */
|
|
5
|
-
render(): string[];
|
|
6
|
-
/** True when the chunk was consumed. Unconsumed chunks are DROPPED, never re-offered. */
|
|
7
|
-
handleInput(data: string): boolean;
|
|
8
|
-
handleWheel(direction: 'up' | 'down', lines: number): boolean;
|
|
9
|
-
/** Only a focused region may emit CURSOR_MARKER. */
|
|
10
|
-
setFocused(value: boolean): void;
|
|
11
|
-
/** One line of state for the composition's status row. */
|
|
12
|
-
summary(): string;
|
|
13
|
-
/** The region's ONLY repaint channel. */
|
|
14
|
-
onDirty(fn: () => void): void;
|
|
15
|
-
close(): void;
|
|
16
|
-
}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { test } from 'node:test';
|
|
6
|
-
import { PushDiffEngine } from '../push-engine.js';
|
|
7
|
-
import { PushLastSeenStore, PushRegistryStore } from '../push-registry.js';
|
|
8
|
-
function tmpDir() {
|
|
9
|
-
return mkdtempSync(join(tmpdir(), 'crtr-push-engine-'));
|
|
10
|
-
}
|
|
11
|
-
function makeStores(dir) {
|
|
12
|
-
return {
|
|
13
|
-
registry: new PushRegistryStore(join(dir, 'registry.json')),
|
|
14
|
-
lastSeen: new PushLastSeenStore(join(dir, 'last-seen.json')),
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
function fakeSubscription(id, authScope = 'local') {
|
|
18
|
-
return {
|
|
19
|
-
id,
|
|
20
|
-
endpoint: `https://fcm.googleapis.com/fcm/send/${id}`,
|
|
21
|
-
keys: { p256dh: 'p'.repeat(32), auth: 'a'.repeat(16) },
|
|
22
|
-
authScope,
|
|
23
|
-
createdAt: 0,
|
|
24
|
-
lastSeenAt: 0,
|
|
25
|
-
prefs: { doneNotifications: true },
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
function buildHarness(dir, opts = {}) {
|
|
29
|
-
const { registry, lastSeen } = makeStores(dir);
|
|
30
|
-
const sent = [];
|
|
31
|
-
const sentTo = [];
|
|
32
|
-
const nodes = [];
|
|
33
|
-
const clock = { now: 1_000_000 };
|
|
34
|
-
const defaultSend = async (record, payload) => {
|
|
35
|
-
sent.push(payload);
|
|
36
|
-
sentTo.push(record.endpoint);
|
|
37
|
-
return 'sent';
|
|
38
|
-
};
|
|
39
|
-
const engine = new PushDiffEngine({
|
|
40
|
-
registry,
|
|
41
|
-
lastSeen,
|
|
42
|
-
readCanvasNodes: () => nodes,
|
|
43
|
-
sendPush: opts.sendPush ?? defaultSend,
|
|
44
|
-
isTargetScope: opts.isTargetScope ?? (() => true),
|
|
45
|
-
now: () => clock.now,
|
|
46
|
-
rateWindowMs: opts.rateWindowMs,
|
|
47
|
-
});
|
|
48
|
-
return { engine, sent, sentTo, registry, lastSeen, nodes, clock };
|
|
49
|
-
}
|
|
50
|
-
function seedRegistryWithOneSubscription(registry) {
|
|
51
|
-
registry.upsert(fakeSubscription('sub-1'));
|
|
52
|
-
}
|
|
53
|
-
test('seed() sends nothing regardless of current state', async () => {
|
|
54
|
-
const dir = tmpDir();
|
|
55
|
-
try {
|
|
56
|
-
const h = buildHarness(dir);
|
|
57
|
-
seedRegistryWithOneSubscription(h.registry);
|
|
58
|
-
h.nodes.push({ node_id: 'root-1', parent: null, status: 'done', attention_count: 0 });
|
|
59
|
-
await h.engine.seed();
|
|
60
|
-
assert.equal(h.sent.length, 0);
|
|
61
|
-
assert.deepEqual(h.lastSeen.snapshot().roots['root-1'], { status: 'done', attention_count: 0 });
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
rmSync(dir, { recursive: true, force: true });
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
test('active -> done emits exactly one done push, and a repeat pass does not duplicate', async () => {
|
|
68
|
-
const dir = tmpDir();
|
|
69
|
-
try {
|
|
70
|
-
const h = buildHarness(dir);
|
|
71
|
-
seedRegistryWithOneSubscription(h.registry);
|
|
72
|
-
h.nodes.push({ node_id: 'root-1', parent: null, status: 'active', attention_count: 0 });
|
|
73
|
-
await h.engine.seed();
|
|
74
|
-
h.nodes[0].status = 'done';
|
|
75
|
-
await h.engine.onNodesInvalidation();
|
|
76
|
-
assert.equal(h.sent.length, 1);
|
|
77
|
-
assert.equal(h.sent[0].kind, 'done');
|
|
78
|
-
assert.equal(h.sent[0].conversationId, 'root-1');
|
|
79
|
-
await h.engine.onNodesInvalidation();
|
|
80
|
-
assert.equal(h.sent.length, 1);
|
|
81
|
-
}
|
|
82
|
-
finally {
|
|
83
|
-
rmSync(dir, { recursive: true, force: true });
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
test('push targeting is scope-filtered', async () => {
|
|
87
|
-
const dir = tmpDir();
|
|
88
|
-
try {
|
|
89
|
-
const h = buildHarness(dir, { isTargetScope: (scope) => scope === 'token:abc' });
|
|
90
|
-
h.registry.upsert(fakeSubscription('sub-local', 'local'));
|
|
91
|
-
h.registry.upsert(fakeSubscription('sub-token', 'token:abc'));
|
|
92
|
-
h.nodes.push({ node_id: 'root-1', parent: null, status: 'active', attention_count: 0 });
|
|
93
|
-
await h.engine.seed();
|
|
94
|
-
h.nodes[0].status = 'done';
|
|
95
|
-
await h.engine.onNodesInvalidation();
|
|
96
|
-
assert.equal(h.sent.length, 1);
|
|
97
|
-
assert.deepEqual(h.sentTo, ['https://fcm.googleapis.com/fcm/send/sub-token']);
|
|
98
|
-
}
|
|
99
|
-
finally {
|
|
100
|
-
rmSync(dir, { recursive: true, force: true });
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
test('a transient send failure does not advance last-seen and is retried next pass', async () => {
|
|
104
|
-
const dir = tmpDir();
|
|
105
|
-
try {
|
|
106
|
-
let call = 0;
|
|
107
|
-
const attempts = [];
|
|
108
|
-
const h = buildHarness(dir, {
|
|
109
|
-
rateWindowMs: 30_000,
|
|
110
|
-
sendPush: async (_record, payload) => {
|
|
111
|
-
attempts.push(payload);
|
|
112
|
-
call += 1;
|
|
113
|
-
return call === 1 ? 'error' : 'sent';
|
|
114
|
-
},
|
|
115
|
-
});
|
|
116
|
-
seedRegistryWithOneSubscription(h.registry);
|
|
117
|
-
h.nodes.push({ node_id: 'root-1', parent: null, status: 'active', attention_count: 0 });
|
|
118
|
-
await h.engine.seed();
|
|
119
|
-
h.nodes[0].status = 'done';
|
|
120
|
-
await h.engine.onNodesInvalidation();
|
|
121
|
-
assert.equal(attempts.length, 1);
|
|
122
|
-
assert.equal(h.lastSeen.snapshot().roots['root-1'].status, 'active');
|
|
123
|
-
h.clock.now += 60_000;
|
|
124
|
-
await h.engine.onNodesInvalidation();
|
|
125
|
-
assert.equal(attempts.length, 2);
|
|
126
|
-
assert.equal(h.lastSeen.snapshot().roots['root-1'].status, 'done');
|
|
127
|
-
}
|
|
128
|
-
finally {
|
|
129
|
-
rmSync(dir, { recursive: true, force: true });
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
test('a transient failure on one subscription does not re-send to an already-delivered subscription', async () => {
|
|
133
|
-
const dir = tmpDir();
|
|
134
|
-
try {
|
|
135
|
-
const attemptsBySub = new Map();
|
|
136
|
-
const h = buildHarness(dir, {
|
|
137
|
-
rateWindowMs: 30_000,
|
|
138
|
-
sendPush: async (record) => {
|
|
139
|
-
const attempts = (attemptsBySub.get(record.endpoint) ?? 0) + 1;
|
|
140
|
-
attemptsBySub.set(record.endpoint, attempts);
|
|
141
|
-
return record.endpoint.includes('sub-fail') && attempts === 1 ? 'error' : 'sent';
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
h.registry.upsert(fakeSubscription('sub-ok'));
|
|
145
|
-
h.registry.upsert(fakeSubscription('sub-fail'));
|
|
146
|
-
h.nodes.push({ node_id: 'root-1', parent: null, status: 'active', attention_count: 0 });
|
|
147
|
-
await h.engine.seed();
|
|
148
|
-
h.nodes[0].status = 'done';
|
|
149
|
-
await h.engine.onNodesInvalidation();
|
|
150
|
-
h.clock.now += 60_000;
|
|
151
|
-
await h.engine.onNodesInvalidation();
|
|
152
|
-
assert.equal(attemptsBySub.get('https://fcm.googleapis.com/fcm/send/sub-ok'), 1);
|
|
153
|
-
assert.equal(attemptsBySub.get('https://fcm.googleapis.com/fcm/send/sub-fail'), 2);
|
|
154
|
-
}
|
|
155
|
-
finally {
|
|
156
|
-
rmSync(dir, { recursive: true, force: true });
|
|
157
|
-
}
|
|
158
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
|
-
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { test } from 'node:test';
|
|
7
|
-
import { PushRegistryStore, PushRequestError, isAllowedPushEndpoint, parsePushDeleteBody, parsePushSubscriptionBody, pushBodyMaxBytes, subscriptionIdForEndpoint, } from '../push-registry.js';
|
|
8
|
-
function tmpDir() {
|
|
9
|
-
return mkdtempSync(join(tmpdir(), 'crtr-push-registry-'));
|
|
10
|
-
}
|
|
11
|
-
// A real, allowlisted vendor push-service endpoint shape (Chromium/FCM) —
|
|
12
|
-
// endpoints must resolve to one of the small set of known browser-vendor push
|
|
13
|
-
// services; arbitrary hosts (including this suite's old `push.example.com`
|
|
14
|
-
// placeholder) are no longer accepted.
|
|
15
|
-
const VALID_ENDPOINT = 'https://fcm.googleapis.com/fcm/send/abc123';
|
|
16
|
-
const VALID_P256DH = 'p'.repeat(64);
|
|
17
|
-
const VALID_AUTH = 'a'.repeat(22);
|
|
18
|
-
function validBody(overrides = {}) {
|
|
19
|
-
return JSON.stringify({
|
|
20
|
-
endpoint: VALID_ENDPOINT,
|
|
21
|
-
keys: { p256dh: VALID_P256DH, auth: VALID_AUTH },
|
|
22
|
-
...overrides,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
test('a well-formed subscription body parses and persists behind a scoped, non-secret authScope', () => {
|
|
26
|
-
const dir = tmpDir();
|
|
27
|
-
try {
|
|
28
|
-
const record = parsePushSubscriptionBody(validBody(), 'token:deadbeef');
|
|
29
|
-
assert.equal(record.endpoint, VALID_ENDPOINT);
|
|
30
|
-
assert.equal(record.authScope, 'token:deadbeef');
|
|
31
|
-
assert.equal(record.id, subscriptionIdForEndpoint(VALID_ENDPOINT));
|
|
32
|
-
assert.equal(record.prefs.doneNotifications, true);
|
|
33
|
-
const registry = new PushRegistryStore(join(dir, 'registry.json'));
|
|
34
|
-
registry.upsert(record);
|
|
35
|
-
assert.equal(registry.listByScope('token:deadbeef').length, 1);
|
|
36
|
-
// The persisted file never carries a raw bearer token \u2014 only the derived
|
|
37
|
-
// scope string, which is exactly what was passed in above.
|
|
38
|
-
const onDisk = readFileSync(join(dir, 'registry.json'), 'utf8');
|
|
39
|
-
assert.ok(onDisk.includes('token:deadbeef'));
|
|
40
|
-
assert.ok(!onDisk.toLowerCase().includes('bearer'));
|
|
41
|
-
}
|
|
42
|
-
finally {
|
|
43
|
-
rmSync(dir, { recursive: true, force: true });
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
test('the registry persists only the derived scope digest, never the raw token pre-image', () => {
|
|
47
|
-
const dir = tmpDir();
|
|
48
|
-
try {
|
|
49
|
-
// Mirror scopeForToken (server.ts): scope = 'token:' + sha256(raw).base64url[:16].
|
|
50
|
-
const raw = 'SUPERSECRET-TOKEN-VALUE';
|
|
51
|
-
const scope = `token:${createHash('sha256').update(raw).digest('base64url').slice(0, 16)}`;
|
|
52
|
-
const record = parsePushSubscriptionBody(validBody(), scope);
|
|
53
|
-
const registry = new PushRegistryStore(join(dir, 'registry.json'));
|
|
54
|
-
registry.upsert(record);
|
|
55
|
-
const onDisk = readFileSync(join(dir, 'registry.json'), 'utf8');
|
|
56
|
-
assert.ok(onDisk.includes(scope));
|
|
57
|
-
assert.ok(!onDisk.includes(raw));
|
|
58
|
-
}
|
|
59
|
-
finally {
|
|
60
|
-
rmSync(dir, { recursive: true, force: true });
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
test('rejects IPv6 and v4-mapped private/localhost endpoints before persistence', () => {
|
|
64
|
-
for (const endpoint of [
|
|
65
|
-
'https://[::1]/x',
|
|
66
|
-
'https://[fc00::1]/x',
|
|
67
|
-
'https://[fe80::1]/x',
|
|
68
|
-
'https://[::ffff:127.0.0.1]/x',
|
|
69
|
-
]) {
|
|
70
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), PushRequestError, endpoint);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
test('the endpoint host must be an allowlisted push service — an arbitrary host is rejected even over https', () => {
|
|
74
|
-
for (const endpoint of [
|
|
75
|
-
'https://push.example.com/abc123', // not a recognized push-service host
|
|
76
|
-
'https://evil.attacker.example/abc123',
|
|
77
|
-
'https://fcm.googleapis.com.attacker.example/abc123', // suffix-spoof attempt
|
|
78
|
-
'https://notgooglapis.com/fcm/send/abc123',
|
|
79
|
-
]) {
|
|
80
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), PushRequestError, endpoint);
|
|
81
|
-
assert.equal(isAllowedPushEndpoint(endpoint), false, endpoint);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
test('a trailing DNS root dot never bypasses the allowlist/localhost check', () => {
|
|
85
|
-
for (const endpoint of ['https://localhost./x', 'https://foo.localhost./x', 'https://fcm.googleapis.com./fcm/send/abc']) {
|
|
86
|
-
// The last one is a real allowlisted host WITH a trailing dot: it must
|
|
87
|
-
// canonicalize to the same allowed match, not be rejected as a foreign
|
|
88
|
-
// host, and localhost-with-trailing-dot must still be rejected.
|
|
89
|
-
if (endpoint.includes('localhost')) {
|
|
90
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), PushRequestError, endpoint);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
assert.doesNotThrow(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), endpoint);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
test('the private/reserved IP ranges the old blocklist missed are moot under the allowlist — no IP literal is ever allowed', () => {
|
|
98
|
-
for (const endpoint of [
|
|
99
|
-
'https://0.0.0.0/x', // 0.0.0.0/8
|
|
100
|
-
'https://100.64.0.1/x', // CGNAT 100.64.0.0/10
|
|
101
|
-
'https://192.0.0.1/x', // 192.0.0.0/24
|
|
102
|
-
'https://198.18.0.1/x', // 198.18.0.0/15
|
|
103
|
-
'https://240.0.0.1/x', // 240.0.0.0/4
|
|
104
|
-
'https://224.0.0.1/x', // multicast
|
|
105
|
-
'https://[::]/x', // IPv6 unspecified
|
|
106
|
-
'https://[fe90::1]/x', // fe80::/10, beyond the fe80* prefix
|
|
107
|
-
'https://[ff02::1]/x', // IPv6 multicast
|
|
108
|
-
'https://8.8.8.8/x', // a genuinely PUBLIC IP — still not allowlisted
|
|
109
|
-
]) {
|
|
110
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), PushRequestError, endpoint);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
test('every real browser-vendor push-service endpoint shape is allowlisted, including a subdomain form', () => {
|
|
114
|
-
for (const endpoint of [
|
|
115
|
-
'https://fcm.googleapis.com/fcm/send/abc123',
|
|
116
|
-
'https://android.googleapis.com/gcm/send/abc123',
|
|
117
|
-
'https://updates.push.services.mozilla.com/wpush/v2/abc123',
|
|
118
|
-
'https://web.push.apple.com/abc123',
|
|
119
|
-
'https://notify.windows.com/w/abc123',
|
|
120
|
-
'https://sub.notify.windows.com/w/abc123',
|
|
121
|
-
'https://wns.windows.com/w/abc123',
|
|
122
|
-
'https://sub.wns.windows.com/w/abc123',
|
|
123
|
-
]) {
|
|
124
|
-
assert.equal(isAllowedPushEndpoint(endpoint), true, endpoint);
|
|
125
|
-
assert.doesNotThrow(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), endpoint);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
test('deleteByEndpoint is scoped: a caller can only remove a subscription it owns', () => {
|
|
129
|
-
const dir = tmpDir();
|
|
130
|
-
try {
|
|
131
|
-
const registry = new PushRegistryStore(join(dir, 'registry.json'));
|
|
132
|
-
registry.upsert(parsePushSubscriptionBody(validBody(), 'scope-A'));
|
|
133
|
-
assert.equal(registry.deleteByEndpoint(VALID_ENDPOINT, 'scope-B'), false);
|
|
134
|
-
assert.equal(registry.listByScope('scope-A').length, 1);
|
|
135
|
-
assert.equal(registry.deleteByEndpoint(VALID_ENDPOINT, 'scope-A'), true);
|
|
136
|
-
assert.equal(registry.listByScope('scope-A').length, 0);
|
|
137
|
-
}
|
|
138
|
-
finally {
|
|
139
|
-
rmSync(dir, { recursive: true, force: true });
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
test('rejects a malformed body shape (unknown keys, missing fields)', () => {
|
|
143
|
-
assert.throws(() => parsePushSubscriptionBody(JSON.stringify({ endpoint: VALID_ENDPOINT }), 'local'), PushRequestError);
|
|
144
|
-
assert.throws(() => parsePushSubscriptionBody(JSON.stringify({ endpoint: VALID_ENDPOINT, keys: { p256dh: VALID_P256DH, auth: VALID_AUTH }, extra: 'nope' }), 'local'), PushRequestError);
|
|
145
|
-
assert.throws(() => parsePushSubscriptionBody('not json', 'local'), PushRequestError);
|
|
146
|
-
});
|
|
147
|
-
test('rejects an oversized body before persistence', () => {
|
|
148
|
-
const oversized = validBody({ prefs: { doneNotifications: true, pad: 'x'.repeat(pushBodyMaxBytes()) } });
|
|
149
|
-
assert.throws(() => parsePushSubscriptionBody(oversized, 'local'), PushRequestError);
|
|
150
|
-
});
|
|
151
|
-
test('rejects private/localhost/file/http endpoints before persistence', () => {
|
|
152
|
-
for (const endpoint of [
|
|
153
|
-
'http://push.example.com/abc', // not https
|
|
154
|
-
'https://localhost/abc',
|
|
155
|
-
'https://127.0.0.1/abc',
|
|
156
|
-
'https://10.0.0.5/abc',
|
|
157
|
-
'https://192.168.1.5/abc',
|
|
158
|
-
'file:///etc/passwd',
|
|
159
|
-
'not-a-url',
|
|
160
|
-
]) {
|
|
161
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ endpoint }), 'local'), PushRequestError, endpoint);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
test('rejects malformed base64url subscription keys', () => {
|
|
165
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ keys: { p256dh: 'not base64url!!', auth: VALID_AUTH } }), 'local'), PushRequestError);
|
|
166
|
-
assert.throws(() => parsePushSubscriptionBody(validBody({ keys: { p256dh: VALID_P256DH, auth: 'short' } }), 'local'), PushRequestError);
|
|
167
|
-
});
|
|
168
|
-
test('DELETE body parses down to just the endpoint', () => {
|
|
169
|
-
const { endpoint } = parsePushDeleteBody(JSON.stringify({ endpoint: VALID_ENDPOINT }));
|
|
170
|
-
assert.equal(endpoint, VALID_ENDPOINT);
|
|
171
|
-
assert.throws(() => parsePushDeleteBody(JSON.stringify({ endpoint: 'https://localhost/x' })), PushRequestError);
|
|
172
|
-
});
|
|
173
|
-
test('the id is a stable hash of the normalized endpoint, independent of scope', () => {
|
|
174
|
-
const a = parsePushSubscriptionBody(validBody(), 'local');
|
|
175
|
-
const b = parsePushSubscriptionBody(validBody(), 'token:other');
|
|
176
|
-
assert.equal(a.id, b.id);
|
|
177
|
-
});
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Server as HttpServer } from 'node:http';
|
|
2
|
-
import type { ViteDevServer } from 'vite';
|
|
3
|
-
/** Create a Vite dev server in middleware mode, HMR bound to `httpServer`.
|
|
4
|
-
* It loads the shell's Vite config rather than duplicating its plugins: that
|
|
5
|
-
* config supplies the PWA virtual-module resolver as well as the production
|
|
6
|
-
* build settings. Lazily imports vite so the shipped path never loads it. */
|
|
7
|
-
export declare function createDevServer(httpServer: HttpServer): Promise<ViteDevServer>;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// dev-server.ts — `crtr web serve --dev` Vite middleware mode.
|
|
2
|
-
//
|
|
3
|
-
// The shipped server serves a prebuilt static shell bundle from dist/web-client/
|
|
4
|
-
// (§11). In --dev a contributor iterating on the shell gets HMR instead: a Vite
|
|
5
|
-
// dev server in MIDDLEWARE mode mounted on the SAME HTTP
|
|
6
|
-
// server as the crtrd proxy + attach tunnel. This is the one place Vite runs at
|
|
7
|
-
// runtime — the mainstream "Vite middleware in dev, static dist in prod" split.
|
|
8
|
-
//
|
|
9
|
-
// The crtrd REST proxy (/v1/*), the SSE lane (GET /__crtr/events) and the attach
|
|
10
|
-
// tunnel are owned by server.ts and checked BEFORE Vite's middlewares; this
|
|
11
|
-
// module only supplies the asset/HMR middleware. Vite's HMR WebSocket shares
|
|
12
|
-
// the HTTP server (server.hmr.server) — server.ts's upgrade handler tunnels
|
|
13
|
-
// `/node/<id>` to crtrd and leaves every other upgrade for Vite.
|
|
14
|
-
import { resolve, dirname, join } from 'node:path';
|
|
15
|
-
import { fileURLToPath } from 'node:url';
|
|
16
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
17
|
-
/** The shell SPA Vite root — the in-tree shell project (`src/clients/web/web-client/`).
|
|
18
|
-
* --dev is a from-source contributor loop, so this resolves against the source
|
|
19
|
-
* tree (HERE is `dist/clients/web` when built, `src/clients/web` under tsx);
|
|
20
|
-
* walk to the package root and into src. */
|
|
21
|
-
function resolveShellRoot(packageRoot) {
|
|
22
|
-
return join(packageRoot, 'src', 'clients', 'web', 'web-client');
|
|
23
|
-
}
|
|
24
|
-
/** Create a Vite dev server in middleware mode, HMR bound to `httpServer`.
|
|
25
|
-
* It loads the shell's Vite config rather than duplicating its plugins: that
|
|
26
|
-
* config supplies the PWA virtual-module resolver as well as the production
|
|
27
|
-
* build settings. Lazily imports vite so the shipped path never loads it. */
|
|
28
|
-
export async function createDevServer(httpServer) {
|
|
29
|
-
const packageRoot = resolve(HERE, '../../..');
|
|
30
|
-
const shellRoot = resolveShellRoot(packageRoot);
|
|
31
|
-
const { createServer } = await import('vite');
|
|
32
|
-
return createServer({
|
|
33
|
-
configFile: join(shellRoot, 'vite.config.ts'),
|
|
34
|
-
// The integrated middleware already owns /node, /v1, and /__crtr. The
|
|
35
|
-
// shell config uses this mode to omit its standalone-server proxies.
|
|
36
|
-
mode: 'middleware',
|
|
37
|
-
server: {
|
|
38
|
-
middlewareMode: true,
|
|
39
|
-
// Share our HTTP server for HMR; server.ts's upgrade handler hands every
|
|
40
|
-
// non-`/node/<id>` upgrade to Vite (the vite-hmr WebSocket).
|
|
41
|
-
hmr: { server: httpServer },
|
|
42
|
-
fs: { allow: [shellRoot, packageRoot] },
|
|
43
|
-
},
|
|
44
|
-
logLevel: 'warn',
|
|
45
|
-
});
|
|
46
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ServerResponse } from 'node:http';
|
|
2
|
-
export type ChangeKind = 'nodes' | 'inbox';
|
|
3
|
-
export interface EventHub {
|
|
4
|
-
/** Register an SSE client: writes the event-stream headers, streams events
|
|
5
|
-
* until the connection closes, and self-removes on close. */
|
|
6
|
-
addClient: (res: ServerResponse) => void;
|
|
7
|
-
/** Internal, in-process subscription to the same invalidations SSE clients
|
|
8
|
-
* receive — for a server-side consumer (the push diff engine) that needs
|
|
9
|
-
* the trigger without opening an HTTP/SSE connection to itself. Returns an
|
|
10
|
-
* unsubscribe function. */
|
|
11
|
-
subscribe: (listener: (kind: ChangeKind) => void) => () => void;
|
|
12
|
-
/** Tear down watchers + heartbeat and end all open streams. */
|
|
13
|
-
close: () => void;
|
|
14
|
-
}
|
|
15
|
-
/** Start the change-event hub: open the two fs watchers once, fan their
|
|
16
|
-
* debounced invalidations out to every connected SSE client. Watchers run for
|
|
17
|
-
* the server's lifetime (cheap — two inotify/FSEvents registrations), not
|
|
18
|
-
* per-client, so N browsers share one watch. */
|
|
19
|
-
export declare function startEventHub(): EventHub;
|