@north-light/crouter 0.3.312 → 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 +13 -1
- 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 +16 -3
- 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 +51 -8
- 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 +2 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
- 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 +4 -1
- 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 +2 -1
- 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 +18 -4
- 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/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- 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 +3 -2
- 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/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/placement.js +2 -2
- package/dist/core/runtime/recycle.js +8 -2
- package/dist/core/runtime/reset.js +22 -6
- package/dist/core/runtime/revive.js +226 -218
- package/dist/core/runtime/spawn.js +14 -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 +39 -15
- 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 +4 -1
- 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 +27 -41
- 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 -151
- 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.js +7 -13
- 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/index.d.ts +2 -1
- 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
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// dto-adapt.ts — the one place daemon human DTOs become the shapes the inbox
|
|
2
|
+
// and the attach viewer render. Pure: no I/O, no canvas state, no second read.
|
|
3
|
+
//
|
|
4
|
+
// The viewer surfaces used to build these shapes by scanning canvas SQL
|
|
5
|
+
// themselves. They now read the daemon's projections, so every field below
|
|
6
|
+
// comes from one already-consistent snapshot rather than from a field-by-field
|
|
7
|
+
// re-derivation each surface had to keep in step.
|
|
8
|
+
import { validatePageManifest } from '../../core/human/page-schema.js';
|
|
9
|
+
/** The wire response map and the renderer's differ in one place: an anchor is a
|
|
10
|
+
* flat optional-field object on the wire and a discriminated union in core.
|
|
11
|
+
* Nothing here re-validates, because the responses a page renders are the ones
|
|
12
|
+
* the daemon already accepted against the same manifest — the read path this
|
|
13
|
+
* replaced did not validate them either, and an in-flight partial autosave is
|
|
14
|
+
* deliberately allowed to be incomplete. */
|
|
15
|
+
function responsesFromDTO(responses) {
|
|
16
|
+
return responses;
|
|
17
|
+
}
|
|
18
|
+
function pageRowFromDTO(dto) {
|
|
19
|
+
return {
|
|
20
|
+
dir: dto.request_dir,
|
|
21
|
+
id: dto.request_id,
|
|
22
|
+
inboxTicketId: dto.ticket_id,
|
|
23
|
+
kind: 'page',
|
|
24
|
+
title: dto.title,
|
|
25
|
+
subtitle: dto.subtitle ?? '',
|
|
26
|
+
dialect: dto.dialect,
|
|
27
|
+
placement: dto.placement,
|
|
28
|
+
inbox: dto.inbox,
|
|
29
|
+
steps: dto.steps,
|
|
30
|
+
slotKinds: dto.slot_kinds,
|
|
31
|
+
awaitsResponse: dto.awaits_response,
|
|
32
|
+
source: dto.source,
|
|
33
|
+
emittedAt: dto.emitted_at,
|
|
34
|
+
recommendedOptions: (dto.recommended_options ?? []).map((option) => ({
|
|
35
|
+
slotId: option.slot_id,
|
|
36
|
+
optionId: option.option_id,
|
|
37
|
+
label: option.label,
|
|
38
|
+
})),
|
|
39
|
+
...(dto.fast_action === undefined
|
|
40
|
+
? {}
|
|
41
|
+
: { fastAction: { kind: dto.fast_action.kind, responses: responsesFromDTO(dto.fast_action.responses) } }),
|
|
42
|
+
state: dto.state,
|
|
43
|
+
...(dto.answer_digest === undefined ? {} : { answerDigest: dto.answer_digest }),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function reviewRowFromDTO(dto) {
|
|
47
|
+
return {
|
|
48
|
+
dir: dto.request_dir,
|
|
49
|
+
id: dto.request_id,
|
|
50
|
+
inboxTicketId: dto.ticket_id,
|
|
51
|
+
kind: 'review',
|
|
52
|
+
title: dto.title,
|
|
53
|
+
subtitle: dto.subtitle,
|
|
54
|
+
blockedSince: dto.blocked_since,
|
|
55
|
+
source: dto.source,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export function inboxRowFromDTO(dto) {
|
|
59
|
+
return dto.kind === 'page' ? pageRowFromDTO(dto) : reviewRowFromDTO(dto);
|
|
60
|
+
}
|
|
61
|
+
export function pageViewFromDTO(dto) {
|
|
62
|
+
return {
|
|
63
|
+
// The manifest is parsed, not cast: a page whose manifest no longer
|
|
64
|
+
// validates must fail loudly here rather than reach the renderer.
|
|
65
|
+
manifest: validatePageManifest(dto.page),
|
|
66
|
+
document: dto.source_document,
|
|
67
|
+
progress: dto.progress === null ? null : responsesFromDTO(dto.progress.responses),
|
|
68
|
+
state: dto.state,
|
|
69
|
+
revision: dto.revision,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** The stored one-line answer digest, or undefined when the page was not
|
|
73
|
+
* answered. A canceled page carries no digest by construction. */
|
|
74
|
+
export function answerDigestOf(dto) {
|
|
75
|
+
const result = dto.result;
|
|
76
|
+
if (result === null || result.kind !== 'page')
|
|
77
|
+
return undefined;
|
|
78
|
+
return result.summary.replace(/\s+/g, ' ').trim();
|
|
79
|
+
}
|
|
80
|
+
/** What a surface says when a settled request refuses a second settlement. */
|
|
81
|
+
export function settledStatusOf(dto) {
|
|
82
|
+
const result = dto.result;
|
|
83
|
+
if (result !== null && result.kind === 'canceled')
|
|
84
|
+
return 'ticket was already canceled';
|
|
85
|
+
if (result !== null && result.kind === 'page')
|
|
86
|
+
return 'ticket was already resolved: page submitted';
|
|
87
|
+
return 'ticket was already resolved';
|
|
88
|
+
}
|
|
89
|
+
/** The row sort every inbox surface shares: newest first, request id breaking ties. */
|
|
90
|
+
export function byNewestFirst(a, b) {
|
|
91
|
+
const time = (row) => row.kind === 'page' ? row.emittedAt : row.blockedSince;
|
|
92
|
+
return time(b).localeCompare(time(a)) || a.id.localeCompare(b.id);
|
|
93
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ProductPageComponents } from '../../types.js';
|
|
2
2
|
import type { PageResponses } from '../../core/human/page-schema.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { InboxPageView } from './dto-adapt.js';
|
|
4
4
|
import type { Key } from './tui/keys.js';
|
|
5
5
|
export interface PageAdapterOptions {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/** The opaque inbox ticket id autosave posts against. */
|
|
7
|
+
ticketId: string;
|
|
8
|
+
page: InboxPageView;
|
|
8
9
|
productKinds: ProductPageComponents;
|
|
9
10
|
cols: number;
|
|
10
11
|
rows: number;
|
|
@@ -27,6 +28,6 @@ export declare class PageAdapter {
|
|
|
27
28
|
setInputBuffer(text: string): void;
|
|
28
29
|
canAcceptHostKeys(): boolean;
|
|
29
30
|
handleKey(input: string, key: Key): void;
|
|
30
|
-
reload(
|
|
31
|
+
reload(page: InboxPageView): void;
|
|
31
32
|
close(): void;
|
|
32
33
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pageAwaitsResponse } from '../../core/human/page-schema.js';
|
|
2
|
-
import {
|
|
2
|
+
import { cliClient } from '../../commands/api-client.js';
|
|
3
3
|
import { mountPanel } from './tui/panel.js';
|
|
4
4
|
/** Embeds the page renderer in a controller-owned rectangle. */
|
|
5
5
|
export class PageAdapter {
|
|
@@ -9,19 +9,19 @@ export class PageAdapter {
|
|
|
9
9
|
manifest;
|
|
10
10
|
constructor(opts) {
|
|
11
11
|
this.opts = opts;
|
|
12
|
-
this.manifest = opts.
|
|
12
|
+
this.manifest = opts.page.manifest;
|
|
13
13
|
this.panel = mountPanel({
|
|
14
|
-
manifest: opts.
|
|
15
|
-
document: opts.
|
|
14
|
+
manifest: opts.page.manifest,
|
|
15
|
+
document: opts.page.document,
|
|
16
16
|
productKinds: opts.productKinds,
|
|
17
|
-
initialResponses: opts.
|
|
17
|
+
initialResponses: opts.page.progress,
|
|
18
18
|
cols: opts.cols,
|
|
19
19
|
rows: opts.rows,
|
|
20
20
|
onProgress: (responses) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
// Autosave is advisory: partial in-flight input may not validate yet,
|
|
22
|
+
// and the answer the person actually submits goes through the respond
|
|
23
|
+
// route, which revalidates. A rejected autosave loses nothing.
|
|
24
|
+
void cliClient().postInboxProgress(opts.ticketId, responses).catch(() => { });
|
|
25
25
|
opts.onProgress?.(responses);
|
|
26
26
|
},
|
|
27
27
|
onComplete: opts.onComplete,
|
|
@@ -46,9 +46,9 @@ export class PageAdapter {
|
|
|
46
46
|
}
|
|
47
47
|
this.panel.handleKey(input, key);
|
|
48
48
|
}
|
|
49
|
-
reload(
|
|
50
|
-
this.manifest =
|
|
51
|
-
this.panel.loadPage(
|
|
49
|
+
reload(page) {
|
|
50
|
+
this.manifest = page.manifest;
|
|
51
|
+
this.panel.loadPage(page.manifest, { document: page.document, initialResponses: page.progress, productKinds: this.opts.productKinds });
|
|
52
52
|
this.opts.onDirty();
|
|
53
53
|
}
|
|
54
54
|
close() { this.panel.unmount(); }
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { PageResponses } from '../../core/human/page-schema.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/** Settle a page request with the person's answer. The request id a scan
|
|
3
|
+
* already carries IS the settlement identity — there is no bridge node to
|
|
4
|
+
* derive one from. An omitted actor is what records a person, not a
|
|
5
|
+
* programmatic writer, as the author of the result. */
|
|
6
|
+
export declare function resolveTicketPage(requestId: string, responses: PageResponses): Promise<void>;
|
|
7
|
+
/** Close a page request from the inbox without answering it. The inbox is the
|
|
8
|
+
* recipient surface, so this is always a dismissal, never the requester
|
|
9
|
+
* withdrawing its own request. */
|
|
10
|
+
export declare function dismissTicketViaDaemon(requestId: string, opts: {
|
|
5
11
|
reason: string;
|
|
6
12
|
actor: string;
|
|
7
|
-
disposition?: 'canceled' | 'dismissed';
|
|
8
13
|
}): Promise<void>;
|
|
9
14
|
export declare function daemonErrorMessage(err: unknown): string;
|
|
10
|
-
export type ResolveFailure = 'unreachable' | '
|
|
15
|
+
export type ResolveFailure = 'unreachable' | 'already_settled' | 'other';
|
|
11
16
|
export declare function resolveFailureKind(err: unknown): ResolveFailure;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { basename } from 'node:path';
|
|
2
1
|
import { ApiError } from '../../api/errors.js';
|
|
3
2
|
import { cliClient } from '../../commands/api-client.js';
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/** Settle a page request with the person's answer. The request id a scan
|
|
4
|
+
* already carries IS the settlement identity — there is no bridge node to
|
|
5
|
+
* derive one from. An omitted actor is what records a person, not a
|
|
6
|
+
* programmatic writer, as the author of the result. */
|
|
7
|
+
export async function resolveTicketPage(requestId, responses) {
|
|
8
|
+
await cliClient().respondHumanRequest(requestId, { responses });
|
|
6
9
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export async function
|
|
11
|
-
await cliClient().
|
|
10
|
+
/** Close a page request from the inbox without answering it. The inbox is the
|
|
11
|
+
* recipient surface, so this is always a dismissal, never the requester
|
|
12
|
+
* withdrawing its own request. */
|
|
13
|
+
export async function dismissTicketViaDaemon(requestId, opts) {
|
|
14
|
+
await cliClient().dismissHumanRequest(requestId, opts);
|
|
12
15
|
}
|
|
13
16
|
function isUnreachable(err) {
|
|
14
17
|
if (err instanceof ApiError)
|
|
@@ -26,9 +29,7 @@ export function daemonErrorMessage(err) {
|
|
|
26
29
|
export function resolveFailureKind(err) {
|
|
27
30
|
if (isUnreachable(err))
|
|
28
31
|
return 'unreachable';
|
|
29
|
-
if (err instanceof ApiError && err.status === 409 && err.code === '
|
|
30
|
-
return '
|
|
31
|
-
if (err instanceof ApiError && err.status === 500 && err.code === 'delivery_failed')
|
|
32
|
-
return 'delivery_failed';
|
|
32
|
+
if (err instanceof ApiError && err.status === 409 && err.code === 'already_settled')
|
|
33
|
+
return 'already_settled';
|
|
33
34
|
return 'other';
|
|
34
35
|
}
|
|
@@ -40,10 +40,6 @@ export function createReviewClient(opts = {}) {
|
|
|
40
40
|
const review = await request(() => cliClient().getReview(reviewId));
|
|
41
41
|
return await resolveReview(review, review.companion_node_id, request);
|
|
42
42
|
},
|
|
43
|
-
async byBridge(bridgeNodeId) {
|
|
44
|
-
const review = await request(() => cliClient().getReviewByBridge(bridgeNodeId));
|
|
45
|
-
return await resolveReview(review, review.companion_node_id, request);
|
|
46
|
-
},
|
|
47
43
|
async createInline(p) {
|
|
48
44
|
const review = await request(() => cliClient().createReview({
|
|
49
45
|
origin_kind: 'inline',
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { SurfaceHost } from '../surfaces/host.js';
|
|
2
2
|
export interface ReviewAdapterOptions {
|
|
3
3
|
host: SurfaceHost;
|
|
4
|
-
|
|
4
|
+
/** The review request's own id — the same id its inbox row carries. */
|
|
5
|
+
reviewId: string;
|
|
5
6
|
}
|
|
6
7
|
/** Resolve a durable review ticket and open it in its own tmux window. */
|
|
7
8
|
export declare class ReviewAdapter {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { basename } from 'node:path';
|
|
2
1
|
import { openReviewWindow } from './review/launch.js';
|
|
3
2
|
import { createReviewClient, ReviewTerminalError, terminalRefusalNotice } from './review/review-client.js';
|
|
4
3
|
/** Resolve a durable review ticket and open it in its own tmux window. */
|
|
@@ -25,20 +24,19 @@ export class ReviewAdapter {
|
|
|
25
24
|
this.opts.host.notice('The review is unavailable in a remote attach — the file and companion live on the host.');
|
|
26
25
|
return;
|
|
27
26
|
}
|
|
28
|
-
const bridgeNodeId = basename(this.opts.dir);
|
|
29
27
|
let review;
|
|
30
28
|
try {
|
|
31
|
-
review = await createReviewClient().
|
|
29
|
+
review = await createReviewClient().byId(this.opts.reviewId);
|
|
32
30
|
}
|
|
33
31
|
catch (error) {
|
|
34
|
-
this.opts.host.notice(
|
|
32
|
+
this.opts.host.notice(noticeForLookupFailure(error));
|
|
35
33
|
return;
|
|
36
34
|
}
|
|
37
35
|
if (!this.stopped)
|
|
38
36
|
openReviewWindow(this.opts.host, review);
|
|
39
37
|
}
|
|
40
38
|
}
|
|
41
|
-
function
|
|
39
|
+
function noticeForLookupFailure(error) {
|
|
42
40
|
if (error instanceof ReviewTerminalError)
|
|
43
41
|
return terminalRefusalNotice(error);
|
|
44
42
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { SurfaceHost } from '../surfaces/host.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { InboxRow } from './dto-adapt.js';
|
|
3
3
|
export interface InboxSurfaceOptions {
|
|
4
4
|
host: SurfaceHost;
|
|
5
5
|
/** Injection seams for tests; production passes none. */
|
|
6
|
-
scan?: () =>
|
|
6
|
+
scan?: () => Promise<InboxRow[]>;
|
|
7
7
|
}
|
|
8
8
|
export interface InboxSurfaceOwner {
|
|
9
9
|
/** Mount when closed and close when open. */
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { InboxController } from './controller.js';
|
|
2
|
-
import {
|
|
2
|
+
import { byNewestFirst, inboxRowFromDTO } from './dto-adapt.js';
|
|
3
3
|
import { cliClient } from '../../commands/api-client.js';
|
|
4
|
-
import { filterVisibleReviewTickets } from './review-visibility.js';
|
|
5
4
|
import { decodeInboxKey } from './tui/keys.js';
|
|
6
5
|
import { clipLine, visibleWidth } from './tui/ansi.js';
|
|
7
6
|
class InboxComponent {
|
|
@@ -46,6 +45,14 @@ function padFrame(lines, cols, rows) {
|
|
|
46
45
|
return clipped + ' '.repeat(Math.max(0, cols - visibleWidth(clipped)));
|
|
47
46
|
});
|
|
48
47
|
}
|
|
48
|
+
/** Reach the row source once before mounting, so a daemon that cannot answer
|
|
49
|
+
* surfaces as a notice instead of an inbox that silently has nothing in it. */
|
|
50
|
+
async function probeRows(opts) {
|
|
51
|
+
if (opts.scan !== undefined)
|
|
52
|
+
return opts.scan();
|
|
53
|
+
const { tickets } = await cliClient().listHumanInbox();
|
|
54
|
+
return tickets.map(inboxRowFromDTO).sort(byNewestFirst);
|
|
55
|
+
}
|
|
49
56
|
export function createInboxSurface(opts) {
|
|
50
57
|
let session;
|
|
51
58
|
const close = () => {
|
|
@@ -62,12 +69,11 @@ export function createInboxSurface(opts) {
|
|
|
62
69
|
const mount = (current) => {
|
|
63
70
|
if (current.closed || session !== current)
|
|
64
71
|
return;
|
|
65
|
-
const localScan = opts.scan ?? scanInbox;
|
|
66
72
|
const nextController = new InboxController({
|
|
67
73
|
host: opts.host,
|
|
68
74
|
onDirty: () => current.handle?.invalidate(),
|
|
69
75
|
onClosed: close,
|
|
70
|
-
scan:
|
|
76
|
+
...(opts.scan === undefined ? {} : { scan: opts.scan }),
|
|
71
77
|
onInboxActivity: () => refresh(current),
|
|
72
78
|
...(current.preselectDir === undefined ? {} : { initialSelection: current.preselectDir }),
|
|
73
79
|
});
|
|
@@ -89,16 +95,22 @@ export function createInboxSurface(opts) {
|
|
|
89
95
|
throw error;
|
|
90
96
|
}
|
|
91
97
|
};
|
|
98
|
+
// The first load decides whether the inbox opens at all — an unreachable
|
|
99
|
+
// daemon is a notice, not an empty surface. Afterwards the controller owns
|
|
100
|
+
// its own rows, so activity only has to tell it to re-read.
|
|
92
101
|
const refresh = (current, initial = false) => {
|
|
102
|
+
if (!initial && current.controller !== undefined) {
|
|
103
|
+
void current.controller.invalidate();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
93
106
|
const generation = ++current.refreshGeneration;
|
|
94
|
-
void
|
|
107
|
+
void probeRows(opts).then(() => {
|
|
95
108
|
if (current.closed || session !== current || generation !== current.refreshGeneration)
|
|
96
109
|
return;
|
|
97
|
-
current.visibleIds = new Set(tickets.map((ticket) => ticket.ticket_id));
|
|
98
110
|
if (current.controller === undefined)
|
|
99
111
|
mount(current);
|
|
100
112
|
else
|
|
101
|
-
current.controller.invalidate();
|
|
113
|
+
void current.controller.invalidate();
|
|
102
114
|
}, (error) => {
|
|
103
115
|
if (!initial || current.closed || session !== current || generation !== current.refreshGeneration)
|
|
104
116
|
return;
|
|
@@ -119,7 +131,6 @@ export function createInboxSurface(opts) {
|
|
|
119
131
|
const current = {
|
|
120
132
|
closed: false,
|
|
121
133
|
refreshGeneration: 0,
|
|
122
|
-
visibleIds: new Set(),
|
|
123
134
|
...(preselectDir === undefined ? {} : { preselectDir }),
|
|
124
135
|
};
|
|
125
136
|
session = current;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InboxRow } from './dto-adapt.js';
|
|
2
2
|
export declare const KIND_ICON: Record<string, string>;
|
|
3
3
|
export declare const KIND_COLOR: Record<string, string>;
|
|
4
4
|
export declare function formatTimeAgo(iso: string): string;
|
|
5
5
|
/** Pure inbox rows; selection and terminal ownership belong to InboxController. */
|
|
6
|
-
export declare function buildInboxLines(items:
|
|
6
|
+
export declare function buildInboxLines(items: InboxRow[], width: number, selectedIndex: number, height?: number): string[];
|
|
7
7
|
/** What the agent suggests, for a row that says so without opening the page. */
|
|
8
|
-
export declare function recommendedLabel(item:
|
|
8
|
+
export declare function recommendedLabel(item: InboxRow): string | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Run with: node --import tsx/esm --test 'src/commands/__tests__/human.test.ts'
|
|
2
2
|
import { test, describe } from 'node:test';
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
|
-
import { mkdirSync, mkdtempSync, rmSync
|
|
4
|
+
import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { Readable } from 'node:stream';
|
|
@@ -13,6 +13,8 @@ import { humanSend as buildHumanSend } from '../human/prompts.js';
|
|
|
13
13
|
const humanSend = buildHumanSend();
|
|
14
14
|
import { registerHuman } from '../human.js';
|
|
15
15
|
import { pageHelpText } from '../human/shared.js';
|
|
16
|
+
import { writeRawConfig } from '../../core/config.js';
|
|
17
|
+
import { initializeFreshScopedStore } from '../../core/scoped-state/migrate.js';
|
|
16
18
|
const nlThreadRegistration = {
|
|
17
19
|
kind: 'nl-thread',
|
|
18
20
|
description: 'message conversation with participants and metadata',
|
|
@@ -37,7 +39,8 @@ function withPageSurface(pageSurface, run) {
|
|
|
37
39
|
const originalHome = process.env['HOME'];
|
|
38
40
|
process.env['HOME'] = home;
|
|
39
41
|
mkdirSync(join(home, '.crouter'), { recursive: true });
|
|
40
|
-
|
|
42
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
43
|
+
writeRawConfig('user', { page_surface: pageSurface });
|
|
41
44
|
try {
|
|
42
45
|
return run();
|
|
43
46
|
}
|
|
@@ -140,17 +143,30 @@ test('human components catalog and contracts teach product registrations', () =>
|
|
|
140
143
|
assert.equal(renderComponentContract('ProductCard', [legacyRegistration]), "`<ProductCard>` — product-registered, wire kind `product-card`\n\nproduct-registered; config is passed through unvalidated (unvalidated: true) — see the product's own docs");
|
|
141
144
|
});
|
|
142
145
|
test('human components show resolves every registry name, families included', async () => {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
assert.
|
|
154
|
-
|
|
155
|
-
|
|
146
|
+
const home = mkdtempSync(join(tmpdir(), 'crtr-human-components-'));
|
|
147
|
+
const originalHome = process.env['HOME'];
|
|
148
|
+
process.env['HOME'] = home;
|
|
149
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
150
|
+
try {
|
|
151
|
+
const show = humanComponents.children.find((child) => child.name === 'show');
|
|
152
|
+
assert.ok(show !== undefined && show.kind === 'leaf');
|
|
153
|
+
const question = await show.run({ component: 'UserQuestion' });
|
|
154
|
+
assert.ok(question !== undefined);
|
|
155
|
+
assert.equal(question['contract'], componentDoc('UserQuestion')?.contract);
|
|
156
|
+
assert.match(String(question['contract']), /wire kind `options`/);
|
|
157
|
+
// A shadcn family member resolves to the family contract that documents it.
|
|
158
|
+
const cardHeader = await show.run({ component: 'CardHeader' });
|
|
159
|
+
assert.equal(cardHeader?.['contract'], componentDoc('Card')?.contract);
|
|
160
|
+
await assert.rejects(() => show.run({ component: 'crtr-options' }), (err) => {
|
|
161
|
+
assert.equal(err.code, 'unknown_component');
|
|
162
|
+
return true;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
if (originalHome === undefined)
|
|
167
|
+
delete process.env['HOME'];
|
|
168
|
+
else
|
|
169
|
+
process.env['HOME'] = originalHome;
|
|
170
|
+
rmSync(home, { recursive: true, force: true });
|
|
171
|
+
}
|
|
156
172
|
});
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
|
-
import { existsSync, mkdtempSync, mkdirSync, rmSync
|
|
2
|
+
import { existsSync, mkdtempSync, mkdirSync, rmSync } from 'node:fs';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { createServer } from 'node:http';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import test from 'node:test';
|
|
8
8
|
import { createNode, subscribe } from '../../../core/canvas/canvas.js';
|
|
9
|
-
import { closeDb } from '../../../core/canvas/db.js';
|
|
9
|
+
import { closeDb, migrate, openDb } from '../../../core/canvas/db.js';
|
|
10
10
|
import { apiSocketPath } from '../../../core/canvas/paths.js';
|
|
11
|
+
import { updateConfig, updateState } from '../../../core/config.js';
|
|
12
|
+
import { closeScopedStores } from '../../../core/scoped-state/db.js';
|
|
13
|
+
import { initializeFreshScopedStore } from '../../../core/scoped-state/migrate.js';
|
|
14
|
+
import { setRelayToken } from '../../../core/secrets.js';
|
|
11
15
|
import { Router } from '../../../daemon/api/router.js';
|
|
12
16
|
import { createApiServer } from '../../../daemon/api/server.js';
|
|
13
17
|
function node(id, parent) {
|
|
@@ -86,13 +90,19 @@ function startMockRemoteCanvas(route) {
|
|
|
86
90
|
test('canvas dashboard renders scoped and full cycles from one node snapshot without per-node API reads', async (t) => {
|
|
87
91
|
const root = mkdtempSync(join(tmpdir(), 'crtr-dashboard-'));
|
|
88
92
|
const home = join(root, 'canvas');
|
|
93
|
+
const userHome = join(root, 'user');
|
|
89
94
|
mkdirSync(home, { recursive: true });
|
|
90
|
-
const
|
|
95
|
+
const previousCanvasHome = process.env['CRTR_HOME'];
|
|
96
|
+
const previousUserHome = process.env['HOME'];
|
|
91
97
|
const originalHandle = Router.prototype.handle;
|
|
92
98
|
const requests = [];
|
|
93
99
|
try {
|
|
94
100
|
process.env['CRTR_HOME'] = home;
|
|
101
|
+
process.env['HOME'] = userHome;
|
|
102
|
+
mkdirSync(join(userHome, '.crouter'), { recursive: true });
|
|
95
103
|
closeDb();
|
|
104
|
+
migrate(openDb());
|
|
105
|
+
initializeFreshScopedStore({ kind: 'user', root: join(userHome, '.crouter') });
|
|
96
106
|
createNode(node('root', null));
|
|
97
107
|
createNode(node('left', 'root'));
|
|
98
108
|
createNode(node('right', 'root'));
|
|
@@ -162,10 +172,15 @@ test('canvas dashboard renders scoped and full cycles from one node snapshot wit
|
|
|
162
172
|
finally {
|
|
163
173
|
Router.prototype.handle = originalHandle;
|
|
164
174
|
closeDb();
|
|
165
|
-
|
|
175
|
+
closeScopedStores();
|
|
176
|
+
if (previousCanvasHome === undefined)
|
|
166
177
|
delete process.env['CRTR_HOME'];
|
|
167
178
|
else
|
|
168
|
-
process.env['CRTR_HOME'] =
|
|
179
|
+
process.env['CRTR_HOME'] = previousCanvasHome;
|
|
180
|
+
if (previousUserHome === undefined)
|
|
181
|
+
delete process.env['HOME'];
|
|
182
|
+
else
|
|
183
|
+
process.env['HOME'] = previousUserHome;
|
|
169
184
|
rmSync(root, { recursive: true, force: true });
|
|
170
185
|
}
|
|
171
186
|
});
|
|
@@ -173,6 +188,7 @@ test('canvas dashboard reads full-forest ticket counts from the selected remote
|
|
|
173
188
|
const root = mkdtempSync(join(tmpdir(), 'crtr-dashboard-remote-'));
|
|
174
189
|
const home = join(root, 'canvas');
|
|
175
190
|
const userHome = join(root, 'user');
|
|
191
|
+
const previousUserHome = process.env['HOME'];
|
|
176
192
|
const remote = await startMockRemoteCanvas((args) => {
|
|
177
193
|
if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'list') {
|
|
178
194
|
return { nodes: [node('root', null), node('child', 'root')] };
|
|
@@ -187,13 +203,17 @@ test('canvas dashboard reads full-forest ticket counts from the selected remote
|
|
|
187
203
|
});
|
|
188
204
|
t.after(() => remote.close());
|
|
189
205
|
try {
|
|
206
|
+
process.env['HOME'] = userHome;
|
|
190
207
|
mkdirSync(join(userHome, '.crouter'), { recursive: true });
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
208
|
+
initializeFreshScopedStore({ kind: 'user', root: join(userHome, '.crouter') });
|
|
209
|
+
updateConfig('user', (config) => {
|
|
210
|
+
config.remoteCanvas.targets['remote'] = { previewEndpoint: remote.url, relayTokenRef: 'remote' };
|
|
211
|
+
});
|
|
212
|
+
updateState('user', (state) => {
|
|
213
|
+
state.activeCanvas = 'remote';
|
|
214
|
+
});
|
|
215
|
+
setRelayToken('remote', 'test-token', 'user');
|
|
216
|
+
const result = await runDashboard(home);
|
|
197
217
|
assert.equal(result.code, 0, result.stderr);
|
|
198
218
|
const output = JSON.parse(result.stdout);
|
|
199
219
|
assert.deepEqual(output.rows.map((row) => ({ node_id: row.node_id, asks: row.asks })), [
|
|
@@ -207,6 +227,11 @@ test('canvas dashboard reads full-forest ticket counts from the selected remote
|
|
|
207
227
|
assert.equal(remote.requests.length, 3, `remote issued ${remote.requests.length} commands: ${remote.requests.map((args) => args.join(' ')).join(' | ')}`);
|
|
208
228
|
}
|
|
209
229
|
finally {
|
|
230
|
+
closeScopedStores();
|
|
231
|
+
if (previousUserHome === undefined)
|
|
232
|
+
delete process.env['HOME'];
|
|
233
|
+
else
|
|
234
|
+
process.env['HOME'] = previousUserHome;
|
|
210
235
|
rmSync(root, { recursive: true, force: true });
|
|
211
236
|
}
|
|
212
237
|
});
|