@north-light/crouter 0.3.311 → 0.3.313
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 +27 -30
- package/dist/api/client.js +80 -67
- package/dist/api/dto/broker-ops.d.ts +10 -20
- package/dist/api/dto/canvas.d.ts +1 -10
- package/dist/api/dto/health.d.ts +113 -0
- package/dist/api/dto/human-requests.d.ts +14 -3
- package/dist/api/dto/human.d.ts +2 -48
- package/dist/api/dto/human.js +3 -2
- package/dist/api/dto/inbox.d.ts +14 -0
- package/dist/api/dto/mail.d.ts +43 -0
- package/dist/api/dto/nodes.d.ts +11 -8
- package/dist/api/dto/recovery.d.ts +96 -0
- package/dist/api/dto/reviews.d.ts +2 -2
- package/dist/api/routes.d.ts +9 -6
- package/dist/api/routes.js +11 -11
- package/dist/build-root.d.ts +4 -0
- package/dist/build-root.js +11 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/cli.js +10 -1
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
- package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
- package/dist/clients/attach/chrome/inbox-strip.js +17 -9
- package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
- package/dist/clients/attach/chrome/ticket-panel.js +77 -46
- package/dist/clients/attach/overlays/graph.js +6 -9
- package/dist/clients/attach/render/chat-view.d.ts +5 -4
- package/dist/clients/attach/render/chat-view.js +22 -13
- package/dist/clients/attach/render/page-block.d.ts +11 -7
- package/dist/clients/attach/render/page-block.js +64 -55
- package/dist/clients/attach/viewer.js +746 -735
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
- package/dist/clients/inbox/controller.d.ts +42 -14
- package/dist/clients/inbox/controller.js +240 -124
- package/dist/clients/inbox/dto-adapt.d.ts +28 -0
- package/dist/clients/inbox/dto-adapt.js +93 -0
- package/dist/clients/inbox/page-adapter.d.ts +5 -4
- package/dist/clients/inbox/page-adapter.js +12 -12
- package/dist/clients/inbox/resolve.d.ts +10 -5
- package/dist/clients/inbox/resolve.js +13 -12
- package/dist/clients/inbox/review/review-client.d.ts +0 -1
- package/dist/clients/inbox/review/review-client.js +0 -4
- package/dist/clients/inbox/review-adapter.d.ts +2 -1
- package/dist/clients/inbox/review-adapter.js +3 -5
- package/dist/clients/inbox/surface.d.ts +2 -2
- package/dist/clients/inbox/surface.js +19 -8
- package/dist/clients/inbox/tui.d.ts +3 -3
- package/dist/commands/__tests__/human.test.js +31 -15
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
- package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
- package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
- package/dist/commands/api-client.d.ts +5 -4
- package/dist/commands/api-client.js +13 -7
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas-roster.js +1 -1
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/human/feedback.js +20 -17
- package/dist/commands/human/prompts.js +45 -36
- package/dist/commands/human/queue.js +73 -123
- package/dist/commands/human/review.js +6 -16
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
- package/dist/commands/node-inspect-artifacts.js +1 -1
- package/dist/commands/node-lifecycle-revive.d.ts +2 -2
- package/dist/commands/node-lifecycle-revive.js +9 -19
- package/dist/commands/pkg/plugin-manage.js +0 -1
- package/dist/commands/profile/show.js +4 -12
- package/dist/commands/surface-tmux-spread.js +1 -5
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
- package/dist/commands/sys/branch.d.ts +2 -0
- package/dist/commands/sys/branch.js +19 -0
- package/dist/commands/sys/config.js +106 -33
- package/dist/commands/sys/daemon.d.ts +2 -0
- package/dist/commands/sys/daemon.js +130 -7
- package/dist/commands/sys/doctor.js +5 -15
- package/dist/commands/sys/migrate.js +21 -92
- package/dist/commands/sys/setup-settings-runner.js +4 -2
- package/dist/commands/sys.js +2 -15
- package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
- package/dist/core/__tests__/boot.test.js +32 -25
- package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
- package/dist/core/__tests__/canvas.test.js +18 -47
- package/dist/core/__tests__/child-death-wake.test.js +29 -7
- package/dist/core/__tests__/cli-help-contract.test.js +2 -0
- package/dist/core/__tests__/close.test.js +29 -10
- package/dist/core/__tests__/collectible.test.js +2 -1
- package/dist/core/__tests__/config-change-delta.test.js +2 -0
- package/dist/core/__tests__/context-intro.test.js +17 -5
- package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
- package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
- package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
- package/dist/core/__tests__/daemon-boot.test.js +51 -14
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
- package/dist/core/__tests__/focuses.test.js +10 -5
- package/dist/core/__tests__/helpers/harness.js +50 -18
- package/dist/core/__tests__/history-inbox.test.js +12 -16
- package/dist/core/__tests__/human-action-delivery.test.js +48 -28
- package/dist/core/__tests__/human-actions.test.js +7 -3
- package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
- package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +312 -1
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
- package/dist/core/__tests__/integration/revive.test.js +67 -21
- package/dist/core/__tests__/integration/spawn-root.test.js +62 -19
- package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
- package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
- package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
- package/dist/core/__tests__/kickoff.test.js +36 -39
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
- package/dist/core/__tests__/lifecycle.test.js +2 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
- package/dist/core/__tests__/migration.test.js +145 -31
- package/dist/core/__tests__/model-pin-durability.test.js +4 -1
- package/dist/core/__tests__/model-routes-config.test.js +13 -5
- package/dist/core/__tests__/node-outcome.test.js +93 -26
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +4 -3
- package/dist/core/__tests__/on-read-dedup-resume.test.js +8 -7
- package/dist/core/__tests__/on-read-nested-store.test.js +8 -7
- package/dist/core/__tests__/passive-subscription.test.js +50 -157
- package/dist/core/__tests__/plugin-kinds.test.js +6 -4
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
- package/dist/core/__tests__/plugin-page-components.test.js +6 -4
- package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +35 -32
- package/dist/core/__tests__/prune.test.js +11 -5
- package/dist/core/__tests__/push-final-guard.test.js +14 -7
- package/dist/core/__tests__/relaunch-root.test.js +30 -2
- package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
- package/dist/core/__tests__/repository-root-identity.test.js +4 -0
- package/dist/core/__tests__/review-model-floor.test.js +6 -3
- package/dist/core/__tests__/revive-all.test.js +13 -3
- package/dist/core/__tests__/revive-capacity.test.js +26 -4
- package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
- package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +5 -4
- package/dist/core/__tests__/stop-guard.test.js +2 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +19 -5
- package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
- package/dist/core/broker-client/transport-socket.d.ts +1 -0
- package/dist/core/broker-client/transport-socket.js +13 -5
- package/dist/core/canvas/__tests__/attention.test.js +29 -35
- package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
- package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
- package/dist/core/canvas/attention.d.ts +2 -5
- package/dist/core/canvas/attention.js +15 -64
- package/dist/core/canvas/boot.d.ts +6 -7
- package/dist/core/canvas/boot.js +5 -9
- package/dist/core/canvas/canvas.d.ts +13 -109
- package/dist/core/canvas/canvas.js +140 -401
- package/dist/core/canvas/crons.d.ts +2 -0
- package/dist/core/canvas/crons.js +16 -15
- package/dist/core/canvas/daemon-owner.js +10 -0
- package/dist/core/canvas/db.d.ts +2 -2
- package/dist/core/canvas/db.js +2 -18
- package/dist/core/canvas/deliveries.d.ts +104 -0
- package/dist/core/canvas/deliveries.js +354 -0
- package/dist/core/canvas/executions.d.ts +29 -0
- package/dist/core/canvas/executions.js +68 -0
- package/dist/core/canvas/history.js +35 -35
- package/dist/core/canvas/index.d.ts +3 -1
- package/dist/core/canvas/index.js +3 -1
- package/dist/core/canvas/migrations.js +20 -12
- package/dist/core/canvas/nav-model.js +1 -3
- package/dist/core/canvas/nav-render.d.ts +4 -4
- package/dist/core/canvas/nav-render.js +11 -21
- package/dist/core/canvas/node-sql-migration.d.ts +3 -0
- package/dist/core/canvas/node-sql-migration.js +261 -0
- package/dist/core/canvas/paths.d.ts +2 -16
- package/dist/core/canvas/paths.js +2 -31
- package/dist/core/canvas/recovery.d.ts +76 -0
- package/dist/core/canvas/recovery.js +588 -0
- package/dist/core/canvas/remote-canvas-source.js +4 -0
- package/dist/core/canvas/render-source.d.ts +16 -27
- package/dist/core/canvas/render-source.js +16 -45
- package/dist/core/canvas/sessions.d.ts +33 -0
- package/dist/core/canvas/sessions.js +78 -0
- package/dist/core/canvas/types.d.ts +33 -33
- package/dist/core/canvas/types.js +2 -5
- package/dist/core/canvas/waits.d.ts +18 -0
- package/dist/core/canvas/waits.js +70 -0
- package/dist/core/canvas/worktrees.d.ts +40 -0
- package/dist/core/canvas/worktrees.js +93 -0
- package/dist/core/command-hooks/artifact.d.ts +6 -0
- package/dist/core/command-hooks/artifact.js +22 -6
- package/dist/core/command-hooks/discovery.d.ts +2 -0
- package/dist/core/command-hooks/discovery.js +2 -0
- package/dist/core/command-hooks/lifecycle-catalog.d.ts +20 -2
- package/dist/core/command-hooks/lifecycle-catalog.js +7 -2
- package/dist/core/command-hooks/lifecycle-create.d.ts +4 -0
- package/dist/core/command-hooks/lifecycle-create.js +51 -0
- package/dist/core/command-hooks/schema.d.ts +2 -2
- package/dist/core/command-hooks/schema.js +5 -4
- package/dist/core/command-hooks/transport/exec-invoke.js +3 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +18 -8
- package/dist/core/command-hooks/transport/exec-lifecycle.js +89 -30
- package/dist/core/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- package/dist/core/errors.d.ts +1 -0
- package/dist/core/errors.js +4 -0
- package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
- package/dist/core/feed/feed.d.ts +0 -6
- package/dist/core/feed/feed.js +68 -56
- package/dist/core/feed/inbox.d.ts +7 -81
- package/dist/core/feed/inbox.js +46 -378
- package/dist/core/feed/messages.d.ts +58 -0
- package/dist/core/feed/messages.js +217 -0
- package/dist/core/fs-utils.d.ts +4 -0
- package/dist/core/fs-utils.js +21 -1
- package/dist/core/human/answer.d.ts +1 -1
- package/dist/core/human/answer.js +1 -1
- package/dist/core/human/claim.d.ts +1 -1
- package/dist/core/human/claim.js +2 -4
- package/dist/core/human/component-docs.js +1 -1
- package/dist/core/human/feedback-companion.js +4 -3
- package/dist/core/human/feedback.d.ts +5 -8
- package/dist/core/human/feedback.js +57 -85
- package/dist/core/human/page-authoring.d.ts +30 -0
- package/dist/core/human/page-authoring.js +19 -0
- package/dist/core/human/requests.d.ts +136 -0
- package/dist/core/human/requests.js +515 -0
- package/dist/core/human/root.d.ts +0 -7
- package/dist/core/human/root.js +0 -17
- package/dist/core/human/scan.d.ts +2 -7
- package/dist/core/human/scan.js +48 -132
- package/dist/core/human/summary.d.ts +1 -1
- package/dist/core/human/summary.js +1 -1
- package/dist/core/human/tickets.d.ts +23 -83
- package/dist/core/human/tickets.js +92 -243
- package/dist/core/human/types.d.ts +5 -1
- package/dist/core/installed-plugins.js +8 -3
- package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
- package/dist/core/locked-file.d.ts +6 -3
- package/dist/core/locked-file.js +36 -9
- package/dist/core/memory/extensions.js +2 -0
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +2 -0
- package/dist/core/profiles/default-binding.d.ts +0 -4
- package/dist/core/profiles/default-binding.js +12 -58
- package/dist/core/profiles/env-store.js +8 -3
- package/dist/core/profiles/manifest.d.ts +2 -37
- package/dist/core/profiles/manifest.js +35 -161
- package/dist/core/profiles/select.js +3 -0
- package/dist/core/review/__tests__/capture-origin.test.js +13 -2
- package/dist/core/review/__tests__/comments.test.js +28 -10
- package/dist/core/review/__tests__/remap.test.js +28 -10
- package/dist/core/review/__tests__/stage-identity.test.js +17 -7
- package/dist/core/review/birth.d.ts +1 -1
- package/dist/core/review/birth.js +34 -5
- package/dist/core/review/comments.js +1 -1
- package/dist/core/review/companion.d.ts +1 -1
- package/dist/core/review/companion.js +2 -2
- package/dist/core/review/document.js +1 -1
- package/dist/core/review/project.d.ts +5 -1
- package/dist/core/review/project.js +14 -36
- package/dist/core/review/realize.d.ts +3 -6
- package/dist/core/review/realize.js +51 -168
- package/dist/core/review/remap.js +1 -1
- package/dist/core/review/stage.d.ts +3 -2
- package/dist/core/review/stage.js +2 -3
- package/dist/core/review/store.d.ts +3 -21
- package/dist/core/review/store.js +140 -186
- package/dist/core/review/types.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
- package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
- package/dist/core/runtime/broker/auth-reload.js +9 -10
- package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
- package/dist/core/runtime/broker/daemon-ops.js +42 -9
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +11 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
- package/dist/core/runtime/broker/fault-retry.js +142 -95
- package/dist/core/runtime/broker/inbox.d.ts +4 -32
- package/dist/core/runtime/broker/inbox.js +4 -92
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +21 -12
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -13
- package/dist/core/runtime/broker.js +28 -22
- package/dist/core/runtime/close.d.ts +3 -9
- package/dist/core/runtime/close.js +16 -27
- package/dist/core/runtime/fault.d.ts +3 -93
- package/dist/core/runtime/fault.js +9 -419
- package/dist/core/runtime/kickoff.d.ts +3 -6
- package/dist/core/runtime/kickoff.js +12 -18
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +40 -7
- package/dist/core/runtime/nodes.d.ts +5 -1
- package/dist/core/runtime/nodes.js +26 -11
- package/dist/core/runtime/placement.js +2 -2
- package/dist/core/runtime/recycle.js +24 -14
- package/dist/core/runtime/reset.js +26 -7
- package/dist/core/runtime/revive.js +226 -217
- package/dist/core/runtime/spawn.d.ts +4 -1
- package/dist/core/runtime/spawn.js +43 -5
- package/dist/core/runtime/warm-pool.d.ts +2 -2
- package/dist/core/runtime/warm-pool.js +23 -3
- package/dist/core/scoped-state/db.d.ts +7 -0
- package/dist/core/scoped-state/db.js +92 -0
- package/dist/core/scoped-state/migrate.d.ts +11 -0
- package/dist/core/scoped-state/migrate.js +198 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +12 -0
- package/dist/core/scoped-state/profiles.js +62 -0
- package/dist/core/scoped-state/providers.d.ts +16 -0
- package/dist/core/scoped-state/providers.js +8 -0
- package/dist/core/scoped-state/schema.d.ts +3 -0
- package/dist/core/scoped-state/schema.js +26 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +82 -0
- package/dist/core/subscription-state.d.ts +29 -48
- package/dist/core/subscription-state.js +176 -712
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +2 -2
- package/dist/core/worktree-sweep.js +11 -16
- package/dist/core/worktree.js +6 -12
- package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
- package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
- package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
- package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +41 -17
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
- package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
- package/dist/daemon/api/__tests__/model-config.test.js +8 -8
- package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +6 -3
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
- package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +29 -43
- package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
- package/dist/daemon/api/bridge.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +6 -7
- package/dist/daemon/api/handlers/broker-ops.js +47 -84
- package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
- package/dist/daemon/api/handlers/broker-recovery.js +251 -0
- package/dist/daemon/api/handlers/canvas.js +2 -44
- package/dist/daemon/api/handlers/daemon.js +41 -0
- package/dist/daemon/api/handlers/feedback-comments.js +2 -2
- package/dist/daemon/api/handlers/health.js +10 -5
- package/dist/daemon/api/handlers/human-requests.js +168 -188
- package/dist/daemon/api/handlers/human.js +3 -148
- package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
- package/dist/daemon/api/handlers/inbox-page.js +89 -0
- package/dist/daemon/api/handlers/inbox.js +21 -120
- package/dist/daemon/api/handlers/messages.d.ts +1 -0
- package/dist/daemon/api/handlers/messages.js +73 -15
- package/dist/daemon/api/handlers/node-outcomes.js +58 -13
- package/dist/daemon/api/handlers/nodes.d.ts +1 -0
- package/dist/daemon/api/handlers/nodes.js +41 -42
- package/dist/daemon/api/handlers/reviews.js +4 -29
- package/dist/daemon/api/map.d.ts +25 -3
- package/dist/daemon/api/map.js +84 -14
- package/dist/daemon/api/server.js +68 -9
- package/dist/daemon/control.d.ts +18 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +8 -5
- package/dist/daemon/cron/settle.js +37 -13
- package/dist/daemon/cron/sinks.d.ts +18 -1
- package/dist/daemon/cron/sinks.js +47 -93
- package/dist/daemon/crtrd-cli.js +4 -19
- package/dist/daemon/crtrd.d.ts +2 -0
- package/dist/daemon/crtrd.js +206 -81
- package/dist/daemon/fleet.js +5 -6
- package/dist/daemon/human/finish.d.ts +12 -24
- package/dist/daemon/human/finish.js +88 -285
- package/dist/daemon/human/settle.d.ts +40 -0
- package/dist/daemon/human/settle.js +89 -0
- package/dist/daemon/human/sweep.d.ts +20 -5
- package/dist/daemon/human/sweep.js +56 -60
- package/dist/daemon/manage.d.ts +21 -16
- package/dist/daemon/manage.js +85 -51
- package/dist/daemon/messaging/node-message.d.ts +1 -1
- package/dist/daemon/messaging/node-message.js +9 -12
- package/dist/daemon/park-activity.js +3 -3
- package/dist/daemon/reconcilers/bash-deadline.js +6 -7
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +41 -19
- package/dist/daemon/reconcilers/controller-death.js +6 -18
- package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/delivery-lane.js +130 -0
- package/dist/daemon/reconcilers/live-obligation.js +3 -3
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
- package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
- package/dist/daemon/review/companion.js +5 -11
- package/dist/daemon/review/deliver.d.ts +1 -5
- package/dist/daemon/review/deliver.js +3 -52
- package/dist/daemon/review/finish.d.ts +2 -27
- package/dist/daemon/review/finish.js +79 -263
- package/dist/daemon/review/sweep.d.ts +3 -10
- package/dist/daemon/review/sweep.js +13 -131
- package/dist/daemon/startup-policy.d.ts +0 -5
- package/dist/daemon/startup-policy.js +0 -5
- package/dist/hook-authoring.d.ts +28 -2
- package/dist/hook-authoring.js +53 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
- package/dist/migrations/__tests__/activation.test.js +9 -6
- package/dist/migrations/activation.d.ts +3 -2
- package/dist/migrations/activation.js +2 -4
- package/dist/migrations/corpus.d.ts +2 -5
- package/dist/migrations/corpus.js +9 -20
- package/dist/migrations/runner.d.ts +3 -1
- package/dist/migrations/runner.js +6 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
- package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
- package/dist/pi-extensions/canvas-passive-context.js +85 -37
- package/dist/pi-extensions/canvas-stophook.js +47 -31
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.js +3 -0
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/dist/clients/attach/__tests__/page-block.test.js +0 -54
- package/dist/clients/inbox/review-visibility.d.ts +0 -5
- package/dist/clients/inbox/review-visibility.js +0 -19
- package/dist/commands/canvas-rebuild-index.d.ts +0 -2
- package/dist/commands/canvas-rebuild-index.js +0 -46
- package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
- package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
- package/dist/core/__tests__/human-deliver.test.js +0 -256
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
- package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
- package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
- package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
- package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-store.test.js +0 -144
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
- package/dist/core/canvas/human-deliveries.d.ts +0 -39
- package/dist/core/canvas/human-deliveries.js +0 -75
- package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
- package/dist/core/canvas/node-outcome-deliveries.js +0 -159
- package/dist/core/feed/passive.d.ts +0 -3
- package/dist/core/feed/passive.js +0 -53
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
- package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
- package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-tickets.test.js +0 -161
- package/dist/core/review/ticket-filter.d.ts +0 -17
- package/dist/core/review/ticket-filter.js +0 -21
- package/dist/core/runtime/broker/passive.d.ts +0 -17
- package/dist/core/runtime/broker/passive.js +0 -44
- package/dist/core/runtime/busy.d.ts +0 -46
- package/dist/core/runtime/busy.js +0 -150
- package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
- package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
- package/dist/daemon/human/deliver-action.d.ts +0 -3
- package/dist/daemon/human/deliver-action.js +0 -9
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
- package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
- package/dist/daemon/startup-block-marker.d.ts +0 -25
- package/dist/daemon/startup-block-marker.js +0 -99
- /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
- /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
- /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
|
@@ -14,7 +14,7 @@ import { tmpdir } from 'node:os';
|
|
|
14
14
|
import { join } from 'node:path';
|
|
15
15
|
import { gitSync } from '../git.js';
|
|
16
16
|
import { getNode } from '../canvas/canvas.js';
|
|
17
|
-
import { closeDb } from '../canvas/db.js';
|
|
17
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
18
18
|
import { spawnNode } from '../runtime/nodes.js';
|
|
19
19
|
import { spawnChild } from '../runtime/spawn.js';
|
|
20
20
|
import { managedWorktreePath } from '../worktree.js';
|
|
@@ -41,6 +41,7 @@ beforeEach(() => {
|
|
|
41
41
|
closeDb();
|
|
42
42
|
rmSync(home, { recursive: true, force: true });
|
|
43
43
|
process.env['CRTR_HOME'] = home;
|
|
44
|
+
migrate(openDb());
|
|
44
45
|
});
|
|
45
46
|
after(async () => {
|
|
46
47
|
closeDb();
|
|
@@ -50,7 +51,7 @@ after(async () => {
|
|
|
50
51
|
});
|
|
51
52
|
test('a --worktree spawn at an already-existing node id throws and leaves NO worktree registered', async () => {
|
|
52
53
|
const nodeId = 'duplicate-id';
|
|
53
|
-
spawnNode({ kind: 'general', cwd: '/tmp/work', nodeId });
|
|
54
|
+
await spawnNode({ kind: 'general', cwd: '/tmp/work', nodeId });
|
|
54
55
|
await assert.rejects(() => spawnChild({ kind: 'general', cwd: repoDir, prompt: '', worktree: true, nodeId }));
|
|
55
56
|
assert.ok(!existsSync(managedWorktreePath(nodeId)), 'the conflicting spawn must not leave a worktree checkout directory');
|
|
56
57
|
assert.equal(gitSync(['show-ref', '--verify', '--quiet', `refs/heads/crtr/${nodeId}`], repoDir).status, 1, 'the conflicting spawn must not leave a registered crtr/<id> branch');
|
|
@@ -59,12 +60,12 @@ test('a --worktree spawn at an already-existing node id throws and leaves NO wor
|
|
|
59
60
|
assert.equal(getNode(nodeId).kind, 'general');
|
|
60
61
|
assert.equal(getNode(nodeId).managed_worktree, undefined);
|
|
61
62
|
});
|
|
62
|
-
test('spawnNode({ nodeId }): a hyphen-less opaque id spawns at the exact given id', () => {
|
|
63
|
+
test('spawnNode({ nodeId }): a hyphen-less opaque id spawns at the exact given id', async () => {
|
|
63
64
|
// Regression for the reviewed opaque-id-contract violation: the old validator
|
|
64
65
|
// required >=2 hyphen segments and rejected a hyphen-less id outright,
|
|
65
66
|
// contradicting the design's "opaque, never parsed for structure" ID scheme
|
|
66
67
|
// that remote and cloud spawns depend on.
|
|
67
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', nodeId: 'remote42' });
|
|
68
|
+
const meta = await spawnNode({ kind: 'general', cwd: '/tmp/work', nodeId: 'remote42' });
|
|
68
69
|
assert.equal(meta.node_id, 'remote42');
|
|
69
70
|
assert.notEqual(getNode('remote42'), null);
|
|
70
71
|
});
|
|
@@ -10,7 +10,7 @@ import { tmpdir } from 'node:os';
|
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { createNode, deliverAndSettleMessageWait, getNode, subscribe, setMessageWait, setStatus } from '../canvas/canvas.js';
|
|
12
12
|
import { armCron, cancelCron, setCronState } from '../canvas/crons.js';
|
|
13
|
-
import { closeDb, openDb } from '../canvas/db.js';
|
|
13
|
+
import { closeDb, openDb, migrate } from '../canvas/db.js';
|
|
14
14
|
import { hasLiveObligation } from '../../daemon/reconcilers/live-obligation.js';
|
|
15
15
|
import { contextDir } from '../canvas/paths.js';
|
|
16
16
|
import { bashJobPaths } from '../bash-jobs.js';
|
|
@@ -61,6 +61,7 @@ before(() => {
|
|
|
61
61
|
beforeEach(() => {
|
|
62
62
|
closeDb();
|
|
63
63
|
rmSync(home, { recursive: true, force: true });
|
|
64
|
+
migrate(openDb());
|
|
64
65
|
});
|
|
65
66
|
after(() => {
|
|
66
67
|
closeDb();
|
|
@@ -6,18 +6,19 @@
|
|
|
6
6
|
// an async writer whose provider returned an incomplete token set.
|
|
7
7
|
import { before, test } from 'node:test';
|
|
8
8
|
import assert from 'node:assert/strict';
|
|
9
|
-
import { mkdtempSync
|
|
9
|
+
import { mkdtempSync } from 'node:fs';
|
|
10
10
|
import { tmpdir } from 'node:os';
|
|
11
11
|
import { join } from 'node:path';
|
|
12
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
12
13
|
const agentDir = mkdtempSync(join(tmpdir(), 'crtr-pool-guard-'));
|
|
13
14
|
process.env['PI_CODING_AGENT_DIR'] = agentDir;
|
|
14
15
|
// Imported dynamically so `PI_CODING_AGENT_DIR` is already set: the pool path is resolved per
|
|
15
16
|
// access, but the import must not race the env write in any future refactor.
|
|
16
17
|
let state;
|
|
17
18
|
before(async () => {
|
|
19
|
+
initializeFreshScopedStore({ kind: 'provider', root: agentDir });
|
|
18
20
|
state = await import('../subscription-state.js');
|
|
19
21
|
});
|
|
20
|
-
const POOL = join(agentDir, 'openai-codex-subscriptions.json');
|
|
21
22
|
async function seed() {
|
|
22
23
|
await state.writeSubscriptionPool('openai-codex', [
|
|
23
24
|
{
|
|
@@ -33,7 +34,7 @@ async function seed() {
|
|
|
33
34
|
]);
|
|
34
35
|
}
|
|
35
36
|
function stored() {
|
|
36
|
-
const pool =
|
|
37
|
+
const pool = state.readSubscriptionPool('openai-codex');
|
|
37
38
|
assert.equal(pool.length, 1, 'the row itself must survive every refused write');
|
|
38
39
|
return pool[0];
|
|
39
40
|
}
|
|
@@ -10,30 +10,44 @@
|
|
|
10
10
|
// Run: node --import tsx/esm --test src/core/__tests__/warm-claim-preference-snapshot.test.ts
|
|
11
11
|
import { test, before, beforeEach, after } from 'node:test';
|
|
12
12
|
import assert from 'node:assert/strict';
|
|
13
|
-
import { mkdtempSync,
|
|
13
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
14
14
|
import { tmpdir } from 'node:os';
|
|
15
15
|
import { join } from 'node:path';
|
|
16
|
-
import { closeDb } from '../canvas/db.js';
|
|
16
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
17
|
+
import { resetScopeCache } from '../scope.js';
|
|
18
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
19
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
17
20
|
import { spawnNode } from '../runtime/nodes.js';
|
|
18
21
|
import { deliverBearingsLive } from '../runtime/deliver-live.js';
|
|
19
22
|
import { loadContextExposureState } from '../substrate/injected-store.js';
|
|
20
23
|
let home;
|
|
24
|
+
const previousHome = process.env['HOME'];
|
|
21
25
|
before(() => {
|
|
22
26
|
home = mkdtempSync(join(tmpdir(), 'crtr-warm-snapshot-'));
|
|
23
|
-
process.env['
|
|
27
|
+
process.env['HOME'] = home;
|
|
28
|
+
process.env['CRTR_HOME'] = join(home, 'canvas');
|
|
24
29
|
});
|
|
25
30
|
beforeEach(() => {
|
|
26
31
|
closeDb();
|
|
32
|
+
closeScopedStores();
|
|
27
33
|
rmSync(home, { recursive: true, force: true });
|
|
28
|
-
|
|
34
|
+
resetScopeCache();
|
|
35
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
36
|
+
migrate(openDb());
|
|
29
37
|
});
|
|
30
38
|
after(() => {
|
|
31
39
|
closeDb();
|
|
40
|
+
closeScopedStores();
|
|
32
41
|
rmSync(home, { recursive: true, force: true });
|
|
33
42
|
delete process.env['CRTR_HOME'];
|
|
43
|
+
if (previousHome === undefined)
|
|
44
|
+
delete process.env['HOME'];
|
|
45
|
+
else
|
|
46
|
+
process.env['HOME'] = previousHome;
|
|
47
|
+
resetScopeCache();
|
|
34
48
|
});
|
|
35
49
|
test('the claim path persists a frozen preference snapshot', async () => {
|
|
36
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
50
|
+
const meta = await spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
37
51
|
assert.equal(loadContextExposureState(meta.node_id).preferenceSnapshot, null, 'a spare mints with nothing frozen');
|
|
38
52
|
await deliverBearingsLive(meta.node_id);
|
|
39
53
|
assert.notEqual(loadContextExposureState(meta.node_id).preferenceSnapshot, null, 'claim freezes the snapshot the persona gate requires');
|
|
@@ -13,7 +13,7 @@ import { mkdtempSync, rmSync } from 'node:fs';
|
|
|
13
13
|
import { tmpdir } from 'node:os';
|
|
14
14
|
import { join } from 'node:path';
|
|
15
15
|
import { createNode, getNode } from '../canvas/canvas.js';
|
|
16
|
-
import { closeDb } from '../canvas/db.js';
|
|
16
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
17
17
|
import { requestYield } from '../runtime/promote.js';
|
|
18
18
|
let home;
|
|
19
19
|
function mkOrchestrator(id) {
|
|
@@ -36,6 +36,7 @@ before(() => {
|
|
|
36
36
|
beforeEach(() => {
|
|
37
37
|
closeDb();
|
|
38
38
|
rmSync(home, { recursive: true, force: true });
|
|
39
|
+
migrate(openDb());
|
|
39
40
|
});
|
|
40
41
|
after(() => {
|
|
41
42
|
closeDb();
|
package/dist/core/bootstrap.js
CHANGED
|
@@ -2,6 +2,7 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { findProjectScopeRoot, resetScopeCache, userScopeRoot } from './scope.js';
|
|
4
4
|
import { ensureScopeInitialized } from './config.js';
|
|
5
|
+
import { initializeFreshScopedStore } from './scoped-state/migrate.js';
|
|
5
6
|
import { CRTR_DIR_NAME } from '../types.js';
|
|
6
7
|
import { envDebug } from '../shared/env.js';
|
|
7
8
|
const SKIP_SUBCOMMANDS = new Set([
|
|
@@ -29,6 +30,7 @@ export function ensureProjectScope(argv) {
|
|
|
29
30
|
return;
|
|
30
31
|
if (shouldSkipForArgv(argv))
|
|
31
32
|
return;
|
|
33
|
+
initializeFreshScopedStore({ kind: 'user', root: userScopeRoot() });
|
|
32
34
|
// Already inside a project scope (here or in an ancestor) — nothing to do.
|
|
33
35
|
if (findProjectScopeRoot() !== null)
|
|
34
36
|
return;
|
|
@@ -1,24 +1,69 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync, mkdtempSync, rmSync } from 'node:fs';
|
|
3
3
|
import test from 'node:test';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { CrtrClient } from '../../../api/client.js';
|
|
5
|
+
import { createNode } from '../../canvas/canvas.js';
|
|
6
|
+
import { closeDb, migrate, openDb } from '../../canvas/db.js';
|
|
7
|
+
import { apiSocketPath } from '../../canvas/paths.js';
|
|
8
|
+
import { readFault } from '../../canvas/recovery.js';
|
|
9
|
+
import { createApiServer } from '../../../daemon/api/server.js';
|
|
6
10
|
import { SocketTransport } from '../transport-socket.js';
|
|
11
|
+
async function waitFor(check, label) {
|
|
12
|
+
for (let i = 0; i < 200; i++) {
|
|
13
|
+
if (check())
|
|
14
|
+
return;
|
|
15
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`timed out waiting for ${label}`);
|
|
18
|
+
}
|
|
19
|
+
async function waitForSocket() {
|
|
20
|
+
const client = CrtrClient.forLocalSocket({ autostart: false });
|
|
21
|
+
await waitFor(() => existsSync(apiSocketPath()), 'the API socket path');
|
|
22
|
+
for (let i = 0; i < 200; i++) {
|
|
23
|
+
try {
|
|
24
|
+
await client.healthz();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new Error('timed out waiting for the API socket');
|
|
32
|
+
}
|
|
33
|
+
function node(nodeId) {
|
|
34
|
+
return {
|
|
35
|
+
node_id: nodeId,
|
|
36
|
+
name: nodeId,
|
|
37
|
+
created: new Date().toISOString(),
|
|
38
|
+
cwd: '/tmp/work',
|
|
39
|
+
kind: 'general',
|
|
40
|
+
mode: 'base',
|
|
41
|
+
lifecycle: 'terminal',
|
|
42
|
+
status: 'active',
|
|
43
|
+
};
|
|
44
|
+
}
|
|
7
45
|
test('a missing dormant broker does not leave a viewer↔broker fault', async () => {
|
|
8
46
|
const previousHome = process.env['CRTR_HOME'];
|
|
9
47
|
const home = mkdtempSync('/tmp/crtr-transport-socket-');
|
|
48
|
+
let server;
|
|
10
49
|
process.env['CRTR_HOME'] = home;
|
|
50
|
+
closeDb();
|
|
51
|
+
migrate(openDb());
|
|
11
52
|
try {
|
|
53
|
+
server = createApiServer();
|
|
54
|
+
await waitForSocket();
|
|
12
55
|
const nodeId = 'dormant-node';
|
|
13
|
-
|
|
56
|
+
createNode(node(nodeId));
|
|
14
57
|
const transport = new SocketTransport(nodeId);
|
|
15
58
|
await assert.rejects(transport.redial());
|
|
16
|
-
|
|
59
|
+
await waitFor(() => readFault(nodeId)?.link === 'viewer↔broker', 'the failed redial fault');
|
|
17
60
|
await assert.rejects(transport.redial({ brokerUnavailableIsExpected: true }));
|
|
18
|
-
|
|
61
|
+
await waitFor(() => readFault(nodeId) === null, 'the expected-unavailable fault clear');
|
|
19
62
|
transport.destroy();
|
|
20
63
|
}
|
|
21
64
|
finally {
|
|
65
|
+
await server?.close();
|
|
66
|
+
closeDb();
|
|
22
67
|
if (previousHome === undefined)
|
|
23
68
|
delete process.env['CRTR_HOME'];
|
|
24
69
|
else
|
|
@@ -20,6 +20,7 @@ export declare class SocketTransport extends EventEmitter implements Transport {
|
|
|
20
20
|
redial(options?: RedialOptions): Promise<void>;
|
|
21
21
|
send(frame: ClientToBroker): void;
|
|
22
22
|
destroy(): void;
|
|
23
|
+
private clearSocketFault;
|
|
23
24
|
private onData;
|
|
24
25
|
private onError;
|
|
25
26
|
private onClose;
|
|
@@ -11,7 +11,8 @@ import { EventEmitter } from 'node:events';
|
|
|
11
11
|
import { createConnection } from 'node:net';
|
|
12
12
|
import { viewSocketPath } from '../canvas/paths.js';
|
|
13
13
|
import { classify } from '../fault-classifier.js';
|
|
14
|
-
import {
|
|
14
|
+
import { clearNodeFault, recordNodeFault } from '../runtime/broker/daemon-ops.js';
|
|
15
|
+
import { emitEvent } from '../events/emit.js';
|
|
15
16
|
import { CLIENT_READ_CAPS, encodeFrame, FrameDecoder, FrameOverflowError, } from '../runtime/broker-protocol.js';
|
|
16
17
|
import { BrokerUnavailableError } from './transport.js';
|
|
17
18
|
export class SocketTransport extends EventEmitter {
|
|
@@ -37,7 +38,7 @@ export class SocketTransport extends EventEmitter {
|
|
|
37
38
|
this.redialFaultRecorded = true;
|
|
38
39
|
}
|
|
39
40
|
const classified = classify('viewer↔broker', err);
|
|
40
|
-
|
|
41
|
+
void recordNodeFault(this.nodeId, {
|
|
41
42
|
link: 'viewer↔broker',
|
|
42
43
|
op,
|
|
43
44
|
kind: classified.kind,
|
|
@@ -45,6 +46,8 @@ export class SocketTransport extends EventEmitter {
|
|
|
45
46
|
? { disposition: 'auto', by: 'client' }
|
|
46
47
|
: { disposition: 'manual' },
|
|
47
48
|
message: err instanceof Error ? err.message : String(err),
|
|
49
|
+
}).catch((error) => {
|
|
50
|
+
emitEvent({ event: 'broker.daemon.operation.failed', level: 'error', node_id: this.nodeId, error, fields: { operation: 'viewer_fault_record' } });
|
|
48
51
|
});
|
|
49
52
|
}
|
|
50
53
|
connect() {
|
|
@@ -52,7 +55,7 @@ export class SocketTransport extends EventEmitter {
|
|
|
52
55
|
this.socket = socket;
|
|
53
56
|
socket.on('connect', () => {
|
|
54
57
|
this.redialFaultRecorded = false;
|
|
55
|
-
|
|
58
|
+
this.clearSocketFault();
|
|
56
59
|
this.emit('connect');
|
|
57
60
|
});
|
|
58
61
|
socket.on('data', (chunk) => this.onData(chunk));
|
|
@@ -68,7 +71,7 @@ export class SocketTransport extends EventEmitter {
|
|
|
68
71
|
this.closeEmitted = false;
|
|
69
72
|
if (options.brokerUnavailableIsExpected) {
|
|
70
73
|
this.redialFaultRecorded = false;
|
|
71
|
-
|
|
74
|
+
this.clearSocketFault();
|
|
72
75
|
}
|
|
73
76
|
return new Promise((resolve, reject) => {
|
|
74
77
|
const socket = createConnection(this.socketPath);
|
|
@@ -79,7 +82,7 @@ export class SocketTransport extends EventEmitter {
|
|
|
79
82
|
return;
|
|
80
83
|
settled = true;
|
|
81
84
|
this.redialFaultRecorded = false;
|
|
82
|
-
|
|
85
|
+
this.clearSocketFault();
|
|
83
86
|
this.emit('connect');
|
|
84
87
|
resolve();
|
|
85
88
|
});
|
|
@@ -127,6 +130,11 @@ export class SocketTransport extends EventEmitter {
|
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
}
|
|
133
|
+
clearSocketFault() {
|
|
134
|
+
void clearNodeFault(this.nodeId, { link: 'viewer↔broker' }).catch((error) => {
|
|
135
|
+
emitEvent({ event: 'broker.daemon.operation.failed', level: 'error', node_id: this.nodeId, error, fields: { operation: 'viewer_fault_clear' } });
|
|
136
|
+
});
|
|
137
|
+
}
|
|
130
138
|
onData(chunk) {
|
|
131
139
|
let frames;
|
|
132
140
|
try {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
// attention.test.ts —
|
|
1
|
+
// attention.test.ts — pending requests are attributed by requester identity.
|
|
2
2
|
import { test, before, beforeEach, after } from 'node:test';
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
|
-
import { mkdtempSync, rmSync
|
|
4
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { createPageRequest } from '../../human/requests.js';
|
|
8
8
|
import { createNode } from '../canvas.js';
|
|
9
9
|
import { closeDb } from '../db.js';
|
|
10
|
-
import { nodeDir } from '../paths.js';
|
|
11
10
|
import { ticketCountsForNodes, pendingTicketsForView, invalidateTicketCounts } from '../attention.js';
|
|
11
|
+
import { migrate, openDb } from '../db.js';
|
|
12
12
|
function meta(id, cwd, extra) {
|
|
13
13
|
return {
|
|
14
14
|
node_id: id,
|
|
@@ -22,26 +22,25 @@ function meta(id, cwd, extra) {
|
|
|
22
22
|
...extra,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
function seedPage(requestId, requesterNodeId) {
|
|
26
|
+
createPageRequest({
|
|
27
|
+
request_id: requestId,
|
|
28
|
+
requester_node_id: requesterNodeId,
|
|
29
|
+
prepared: {
|
|
30
|
+
document: '<html><head><title>Request</title></head><body>Request</body></html>',
|
|
31
|
+
manifest: {
|
|
32
|
+
schema: 'crtr.page/v2',
|
|
33
|
+
dialect: 'html',
|
|
34
|
+
title: requestId,
|
|
35
|
+
subtitle: 'Acknowledge this ticket so the request can proceed.',
|
|
36
|
+
delivery: { placement: 'inline', inbox: true, reply: true },
|
|
37
|
+
document: 'page.html',
|
|
38
|
+
steps: 1,
|
|
39
|
+
slots: [],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
|
-
function bridge(id, parent, cwd) {
|
|
43
|
-
createNode(meta(id, cwd, { kind: 'human', parent }));
|
|
44
|
-
}
|
|
45
44
|
let home;
|
|
46
45
|
let sharedCwd;
|
|
47
46
|
let soloCwd;
|
|
@@ -55,6 +54,7 @@ beforeEach(() => {
|
|
|
55
54
|
closeDb();
|
|
56
55
|
invalidateTicketCounts();
|
|
57
56
|
rmSync(home, { recursive: true, force: true });
|
|
57
|
+
migrate(openDb());
|
|
58
58
|
});
|
|
59
59
|
after(() => {
|
|
60
60
|
closeDb();
|
|
@@ -62,27 +62,21 @@ after(() => {
|
|
|
62
62
|
rmSync(d, { recursive: true, force: true });
|
|
63
63
|
delete process.env['CRTR_HOME'];
|
|
64
64
|
});
|
|
65
|
-
test('ticketCountsForNodes follows
|
|
65
|
+
test('ticketCountsForNodes follows requester identity even when asking nodes share a cwd', () => {
|
|
66
66
|
createNode(meta('a', sharedCwd));
|
|
67
67
|
createNode(meta('b', sharedCwd));
|
|
68
68
|
createNode(meta('c', soloCwd));
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
seedPage('ha1');
|
|
74
|
-
seedPage('ha2');
|
|
75
|
-
seedPage('hb');
|
|
76
|
-
seedPage('hc');
|
|
69
|
+
seedPage('request-a1', 'a');
|
|
70
|
+
seedPage('request-a2', 'a');
|
|
71
|
+
seedPage('request-b', 'b');
|
|
72
|
+
seedPage('request-c', 'c');
|
|
77
73
|
assert.deepEqual(ticketCountsForNodes(['a', 'b', 'c']), { a: 2, b: 1, c: 1 });
|
|
78
74
|
});
|
|
79
75
|
test('pendingTicketsForView returns the asking node rather than a cwd bucket', () => {
|
|
80
76
|
createNode(meta('a', sharedCwd));
|
|
81
77
|
createNode(meta('b', sharedCwd));
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
seedPage('ha');
|
|
85
|
-
seedPage('hb');
|
|
78
|
+
seedPage('request-a', 'a');
|
|
79
|
+
seedPage('request-b', 'b');
|
|
86
80
|
assert.deepEqual(pendingTicketsForView('a').map(({ node_id, count }) => ({ node_id, count })), [
|
|
87
81
|
{ node_id: 'a', count: 1 },
|
|
88
82
|
]);
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
// regression rather than a reader bug, so it is worth pinning.
|
|
9
9
|
import { test, before, beforeEach, after } from 'node:test';
|
|
10
10
|
import assert from 'node:assert/strict';
|
|
11
|
-
import { mkdtempSync, rmSync,
|
|
11
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { createNode } from '../canvas.js';
|
|
15
|
-
import { closeDb } from '../db.js';
|
|
16
|
-
import {
|
|
15
|
+
import { closeDb, migrate, openDb } from '../db.js';
|
|
16
|
+
import { resetSession } from '../sessions.js';
|
|
17
17
|
import { nodeArtifacts, groupCorpus } from '../history.js';
|
|
18
18
|
const NODE = 'test-transcript-node';
|
|
19
19
|
function meta(id, cwd) {
|
|
@@ -45,8 +45,6 @@ function stampEntry(msgTs, origin) {
|
|
|
45
45
|
/** A session file in the real on-disk shape: stamps precede their messages,
|
|
46
46
|
* one inbound turn is unstamped, and an assistant turn sits between them. */
|
|
47
47
|
function seedSession(home) {
|
|
48
|
-
const dir = nodeDir(NODE);
|
|
49
|
-
mkdirSync(dir, { recursive: true });
|
|
50
48
|
const file = join(home, 'session.jsonl');
|
|
51
49
|
writeFileSync(file, [
|
|
52
50
|
JSON.stringify({ type: 'custom', customType: 'crtr-stamp', data: { v: 1, kind: 'session', payload: { node: NODE, crtr: '0.0.0' } } }),
|
|
@@ -57,7 +55,7 @@ function seedSession(home) {
|
|
|
57
55
|
messageEntry('user', 'a delivery', 2000),
|
|
58
56
|
messageEntry('user', 'no stamp for this one', 3000),
|
|
59
57
|
].join('\n'), 'utf8');
|
|
60
|
-
|
|
58
|
+
resetSession(NODE, { sessionId: 'history-transcript-session', transcriptPath: file });
|
|
61
59
|
}
|
|
62
60
|
let home;
|
|
63
61
|
let cwd;
|
|
@@ -68,6 +66,8 @@ before(() => {
|
|
|
68
66
|
});
|
|
69
67
|
beforeEach(() => {
|
|
70
68
|
closeDb();
|
|
69
|
+
rmSync(home, { recursive: true, force: true });
|
|
70
|
+
migrate(openDb());
|
|
71
71
|
});
|
|
72
72
|
after(() => {
|
|
73
73
|
closeDb();
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// render-remote.test.ts — the safe-defaults contract for `render.ts`'s
|
|
2
2
|
// `*FromSource` functions when given a `RemoteCanvasSource`: every field that
|
|
3
|
-
// would require a local disk/SQLite read (
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// the
|
|
3
|
+
// would require a local disk/SQLite read (viewed, ctx tokens, asks, goal,
|
|
4
|
+
// prompts, lastAssistant) must come back suppressed to its safe default
|
|
5
|
+
// instead of touching this process's local state. `hanging`/`streaming` are
|
|
6
|
+
// not suppressed — they are projected by the REMOTE daemon and arrive on the
|
|
7
|
+
// row, so the contract for them is that the row carries the remote fault and
|
|
8
|
+
// never the local one. Reuses the mock-server harness shape from
|
|
9
|
+
// `remote-canvas-source.test.ts`.
|
|
7
10
|
//
|
|
8
11
|
// This is adversarial, not merely a clean-machine assertion: BEFORE calling
|
|
9
12
|
// the render functions, the test seeds real, CONFLICTING local state for the
|
|
@@ -23,10 +26,10 @@ import { atomicWriteJson, pageManifestPath } from '#core/human/convention';
|
|
|
23
26
|
import { RemoteCanvasSource } from '../remote-canvas-source.js';
|
|
24
27
|
import { dashboardRowsAllFromSource, enrichRowsFromSource, loadPreviewFromSource, renderForestFromSource } from '../render-source.js';
|
|
25
28
|
import { createNode } from '../canvas.js';
|
|
26
|
-
import { closeDb } from '../db.js';
|
|
29
|
+
import { closeDb, migrate, openDb } from '../db.js';
|
|
27
30
|
import { openFocusRow } from '../focuses.js';
|
|
28
31
|
import { jobDir, contextDir, nodeDir } from '../paths.js';
|
|
29
|
-
import { recordFault } from '
|
|
32
|
+
import { recordFault } from '../recovery.js';
|
|
30
33
|
function startMockCrtrServer(route) {
|
|
31
34
|
return new Promise((resolve) => {
|
|
32
35
|
const server = createServer((req, res) => {
|
|
@@ -63,8 +66,9 @@ function meta(id, extra) {
|
|
|
63
66
|
...extra,
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
|
-
function row(id) {
|
|
69
|
+
function row(id, fault) {
|
|
67
70
|
return {
|
|
71
|
+
...(fault === undefined ? {} : { fault }),
|
|
68
72
|
node_id: id,
|
|
69
73
|
name: id,
|
|
70
74
|
kind: 'general',
|
|
@@ -97,6 +101,7 @@ beforeEach(() => {
|
|
|
97
101
|
closeDb();
|
|
98
102
|
rmSync(home, { recursive: true, force: true });
|
|
99
103
|
rmSync(nodeDir('poison-ask'), { recursive: true, force: true });
|
|
104
|
+
migrate(openDb());
|
|
100
105
|
});
|
|
101
106
|
after(() => {
|
|
102
107
|
closeDb();
|
|
@@ -146,11 +151,22 @@ function seedPoisonedLocalState() {
|
|
|
146
151
|
].join('\n'));
|
|
147
152
|
return sf;
|
|
148
153
|
}
|
|
154
|
+
/** What the remote daemon projected onto its own row — the only fault a remote
|
|
155
|
+
* row may ever show. */
|
|
156
|
+
const remoteFault = {
|
|
157
|
+
link: 'daemon→node',
|
|
158
|
+
op: 'remote turn',
|
|
159
|
+
kind: 'wedged',
|
|
160
|
+
retry: { disposition: 'manual' },
|
|
161
|
+
message: 'remote daemon fault',
|
|
162
|
+
since: new Date().toISOString(),
|
|
163
|
+
operation_id: '44444444444444444444444444444444',
|
|
164
|
+
};
|
|
149
165
|
test('dashboardRowsAllFromSource / enrichRowsFromSource / loadPreviewFromSource suppress every local-read field to its safe default for a RemoteCanvasSource, even with conflicting local state for the same node id', async (t) => {
|
|
150
166
|
sessionFile = seedPoisonedLocalState();
|
|
151
167
|
const server = await startMockCrtrServer((args) => {
|
|
152
168
|
if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'list') {
|
|
153
|
-
return { body: { nodes: [row('a')] } };
|
|
169
|
+
return { body: { nodes: [row('a', remoteFault)] } };
|
|
154
170
|
}
|
|
155
171
|
if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'show') {
|
|
156
172
|
return {
|
|
@@ -177,7 +193,7 @@ test('dashboardRowsAllFromSource / enrichRowsFromSource / loadPreviewFromSource
|
|
|
177
193
|
const rows = await dashboardRowsAllFromSource(source);
|
|
178
194
|
assert.equal(rows.length, 1);
|
|
179
195
|
const r = rows[0];
|
|
180
|
-
assert.equal(r.hanging,
|
|
196
|
+
assert.equal(r.hanging?.message, 'remote daemon fault', 'the remote row must carry the fault its own daemon projected');
|
|
181
197
|
assert.equal(r.streaming, false);
|
|
182
198
|
assert.equal(r.viewed, false, 'local focus must not leak into a remote row');
|
|
183
199
|
await enrichRowsFromSource(source, rows);
|
|
@@ -3,13 +3,10 @@ export interface TicketEntry {
|
|
|
3
3
|
name: string;
|
|
4
4
|
cwd: string;
|
|
5
5
|
count: number;
|
|
6
|
-
/** Open ticket titles for this node, newest first
|
|
6
|
+
/** Open ticket titles for this node, newest first. */
|
|
7
7
|
subjects: string[];
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
* process (tests, and any in-process home switch) must call this: the cache is
|
|
11
|
-
* keyed only by time, so a stale window would otherwise serve the old home's
|
|
12
|
-
* counts. */
|
|
9
|
+
/** Kept for callers that reset a canvas home in process. SQL has no directory-scan cache to invalidate. */
|
|
13
10
|
export declare function invalidateTicketCounts(): void;
|
|
14
11
|
/** Count pending tickets asked by one node. */
|
|
15
12
|
export declare function countTickets(nodeId: string): number;
|