@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
|
@@ -1,81 +1,81 @@
|
|
|
1
|
+
// The inbox controller against a real daemon: every row, page body, progress
|
|
2
|
+
// autosave and settlement crosses the human/inbox routes, so this fixture binds
|
|
3
|
+
// the daemon's own route tables rather than re-implementing their projections.
|
|
1
4
|
import assert from 'node:assert/strict';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { InboxController } from '../../controller.js';
|
|
5
|
+
import { startHumanDaemon } from '../../../__tests__/helpers/human-daemon.js';
|
|
6
|
+
const daemon = await startHumanDaemon('crtr-inbox-controller');
|
|
7
|
+
// Imported after the isolated home is in place, so nothing resolves the
|
|
8
|
+
// developer's own canvas at module load.
|
|
9
|
+
const { cliClient } = await import('#commands/api-client');
|
|
10
|
+
const { InboxController } = await import('../../controller.js');
|
|
9
11
|
const key = (part = {}) => ({ ctrl: false, meta: false, upArrow: false, downArrow: false, leftArrow: false, rightArrow: false, wordLeft: false, wordRight: false, home: false, end: false, pageUp: false, pageDown: false, del: false, return: false, newline: false, escape: false, tab: false, backspace: false, ...part });
|
|
10
12
|
function fakeHost() {
|
|
11
13
|
const handle = { close() { }, invalidate() { }, onClose() { } };
|
|
12
14
|
return { capabilities: { remote: false, canFocusNode: false, selfPane: undefined }, mount: () => handle, notice() { }, suspendForChild: () => () => { }, focusNode: async () => false, pickReviewFile: async () => null };
|
|
13
15
|
}
|
|
14
|
-
const controller = (
|
|
15
|
-
async function waitFor(predicate, message) { const end = Date.now() +
|
|
16
|
+
const controller = (cols, rows) => new InboxController({ host: fakeHost(), onDirty() { }, onClosed() { }, cols, rows });
|
|
17
|
+
async function waitFor(predicate, message) { const end = Date.now() + 5000; for (;;) {
|
|
18
|
+
if (await predicate())
|
|
19
|
+
return;
|
|
16
20
|
if (Date.now() > end)
|
|
17
21
|
throw new Error(message);
|
|
18
22
|
await new Promise((r) => setTimeout(r, 10));
|
|
19
23
|
} }
|
|
20
|
-
const
|
|
21
|
-
const sources = mkdtempSync(join(tmpdir(), 'crtr-page-sources-'));
|
|
22
|
-
process.env['CRTR_HOME'] = temp;
|
|
23
|
-
let received;
|
|
24
|
-
async function startDaemon() {
|
|
25
|
-
const server = createServer(async (req, res) => {
|
|
26
|
-
if (!req.url?.endsWith('/resolve')) {
|
|
27
|
-
res.statusCode = 404;
|
|
28
|
-
res.end();
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
const body = await new Promise((resolve) => { let text = ''; req.on('data', (c) => { text += c; }); req.on('end', () => resolve(text)); });
|
|
32
|
-
const nodeId = req.url.split('/').at(-2);
|
|
33
|
-
received = JSON.parse(body).responses;
|
|
34
|
-
takeoverAndCompletePage(ticketDir(nodeId), received, { host: 'daemon', pid: 1 });
|
|
35
|
-
res.end(JSON.stringify({ delivered: true, kind: 'page' }));
|
|
36
|
-
});
|
|
37
|
-
await new Promise((resolve) => server.listen(join(temp, 'crtrd.sock'), resolve));
|
|
38
|
-
return server;
|
|
39
|
-
}
|
|
40
|
-
const source = (name, body) => { const path = join(sources, name); writeFileSync(path, body); return path; };
|
|
41
|
-
const ask = source('ask.tsx', 'export default () => (\n <Page title="Restored page" subtitle="Pick one">\n <UserQuestion id="choice" label="Restore?" body="Pick one to continue." mode="single" options={[{ id: "yes", label: "Yes" }, { id: "no", label: "No" }]} />\n </Page>\n);\n');
|
|
42
|
-
const rich = source('rich.tsx', 'export default () => (\n <Page title="Rich page" subtitle="Browser content">\n <Chart kind="bar" x="day" y={[{ field: "count" }]} />\n </Page>\n);\n');
|
|
24
|
+
const client = cliClient();
|
|
43
25
|
// A ticket reaches the inbox and settles only with a response lifecycle; a page
|
|
44
26
|
// carrying neither is a passive display that never opens here.
|
|
45
|
-
const
|
|
46
|
-
const
|
|
27
|
+
const delivery = { placement: 'inline', inbox: true, reply: false };
|
|
28
|
+
const createPage = (source) => client.createHumanRequest({ page: { dialect: 'jsx', source }, delivery, creator_cwd: daemon.home });
|
|
29
|
+
const ticketIdOf = async (requestId) => {
|
|
30
|
+
const { tickets } = await client.listHumanInbox();
|
|
31
|
+
const row = tickets.find((ticket) => ticket.request_id === requestId);
|
|
32
|
+
if (row === undefined)
|
|
33
|
+
throw new Error(`request is not listed in the inbox: ${requestId}`);
|
|
34
|
+
return row.ticket_id;
|
|
35
|
+
};
|
|
36
|
+
const ask = 'export default () => (\n <Page title="Restored page" subtitle="Pick one">\n <UserQuestion id="choice" label="Restore?" body="Pick one to continue." mode="single" options={[{ id: "yes", label: "Yes" }, { id: "no", label: "No" }]} />\n </Page>\n);\n';
|
|
37
|
+
const rich = 'export default () => (\n <Page title="Rich page" subtitle="Browser content">\n <Chart kind="bar" x="day" y={[{ field: "count" }]} />\n </Page>\n);\n';
|
|
47
38
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
active.handleKey('n', key());
|
|
54
|
-
active.handleKey('', key({ return: true }));
|
|
55
|
-
await waitFor(() => existsSync(join(ticket.dir, 'response.json')), 'restored page responses cross the daemon seam');
|
|
56
|
-
assert.deepEqual(received, { choice: { selectedOptionIds: ['yes'], comments: [] } }, 'progress.json is restored into the response map');
|
|
57
|
-
active.close();
|
|
58
|
-
submitPage({ dir: ticketDir('rich-page'), sourceFile: rich, delivery: inboxDelivery });
|
|
59
|
-
const preview = controller({ cols: 100, rows: 24 });
|
|
39
|
+
// A page opens with the manifest-backed terminal projection of its content.
|
|
40
|
+
const richRequest = await createPage(rich);
|
|
41
|
+
const preview = controller(100, 24);
|
|
42
|
+
await waitFor(() => preview.snapshot().items.length === 1, 'the rich page reaches the inbox list');
|
|
43
|
+
preview.selectDir(richRequest.request_dir);
|
|
60
44
|
assert.match(preview.render().join('\n'), /Rich page/, 'a pending page is listed before it is opened');
|
|
61
|
-
preview.activate();
|
|
45
|
+
await preview.activate();
|
|
62
46
|
assert.match(preview.render().join('\n'), /chart — bar: day vs count/, 'a page uses the manifest-backed terminal projection');
|
|
63
47
|
preview.close();
|
|
64
48
|
// The list preview shows what the page says, because `s` settles the selected
|
|
65
|
-
// ticket from this screen without ever opening it.
|
|
66
|
-
|
|
67
|
-
const
|
|
49
|
+
// ticket from this screen without ever opening it. The body is a round trip,
|
|
50
|
+
// so the first frame schedules it and a later frame carries it.
|
|
51
|
+
const previewRequest = await createPage(ask);
|
|
52
|
+
const listing = controller(100, 40);
|
|
53
|
+
await waitFor(() => listing.snapshot().items.length === 2, 'both pending pages reach the inbox list');
|
|
54
|
+
listing.selectDir(previewRequest.request_dir);
|
|
55
|
+
await waitFor(() => listing.render().join('\n').includes('Pick one to continue'), 'the preview carries the question body');
|
|
68
56
|
const shown = listing.render().join('\n');
|
|
69
|
-
assert.match(shown, /Pick one to continue/, 'the preview carries the question body');
|
|
70
57
|
assert.match(shown, /Yes/, 'the preview carries the options the reader would pick from');
|
|
71
58
|
assert.doesNotMatch(shown, /\d+ components?\b/, 'the component count no longer stands in for the content');
|
|
72
59
|
listing.close();
|
|
60
|
+
// Autosaved progress is restored into the page the reader opens, and the
|
|
61
|
+
// answer it submits crosses the daemon's settlement route.
|
|
62
|
+
const request = await createPage(ask);
|
|
63
|
+
await client.postInboxProgress(await ticketIdOf(request.request_id), { choice: { selectedOptionIds: ['yes'], comments: [] } });
|
|
64
|
+
const active = controller(100, 24);
|
|
65
|
+
await waitFor(() => active.snapshot().items.length === 3, 'the created page reaches the inbox list');
|
|
66
|
+
active.selectDir(request.request_dir);
|
|
67
|
+
await active.activate();
|
|
68
|
+
assert.equal(active.snapshot().screen, 'detail', 'page ticket opens in the page panel');
|
|
69
|
+
assert.match(active.render().join('\n'), /✓|\[✓\]/, 'the autosaved answer is restored into the open page');
|
|
70
|
+
active.handleKey('n', key());
|
|
71
|
+
active.handleKey('', key({ return: true }));
|
|
72
|
+
await waitFor(async () => (await client.getHumanRequest(request.request_id)).state !== 'pending', 'restored page responses cross the daemon seam');
|
|
73
|
+
const settled = await client.getHumanRequest(request.request_id);
|
|
74
|
+
assert.equal(settled.page?.result?.kind, 'page', 'the page settled with an answer');
|
|
75
|
+
assert.deepEqual(settled.page?.result?.kind === 'page' ? settled.page.result.responses : undefined, { choice: { selectedOptionIds: ['yes'], comments: [] } }, 'saved progress is restored into the response map');
|
|
76
|
+
active.close();
|
|
73
77
|
}
|
|
74
78
|
finally {
|
|
75
|
-
|
|
76
|
-
await new Promise((resolve) => server.close(() => resolve()));
|
|
77
|
-
rmSync(temp, { recursive: true, force: true });
|
|
78
|
-
rmSync(sources, { recursive: true, force: true });
|
|
79
|
-
delete process.env['CRTR_HOME'];
|
|
79
|
+
await daemon.dispose();
|
|
80
80
|
}
|
|
81
81
|
console.log('inbox controller tests passed');
|
|
@@ -1,53 +1,66 @@
|
|
|
1
|
-
// A page
|
|
1
|
+
// A page request that settles out-of-band (answered from another surface, or a
|
|
2
2
|
// row this inbox failed to drop) must not read as "being edited by another
|
|
3
|
-
// inbox" when the reader presses Enter: its
|
|
4
|
-
// row is stale and this activation must report the settlement and drop it.
|
|
3
|
+
// inbox" when the reader presses Enter: its request row is already settled, so
|
|
4
|
+
// the row is stale and this activation must report the settlement and drop it.
|
|
5
5
|
import assert from 'node:assert/strict';
|
|
6
|
-
import { existsSync
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { startHumanDaemon } from '../../../__tests__/helpers/human-daemon.js';
|
|
8
|
+
const daemon = await startHumanDaemon('crtr-stale-row');
|
|
9
|
+
// Imported after the isolated home is in place, so nothing resolves the
|
|
10
|
+
// developer's own canvas at module load.
|
|
11
|
+
const { cliClient } = await import('#commands/api-client');
|
|
12
|
+
const { withCanvasWrite } = await import('#core/canvas/db');
|
|
13
|
+
const { settleRequestLocked } = await import('#core/human/requests');
|
|
14
|
+
const { claimPath } = await import('#core/human/convention');
|
|
15
|
+
const { InboxController } = await import('../../controller.js');
|
|
13
16
|
const key = (part = {}) => ({ ctrl: false, meta: false, upArrow: false, downArrow: false, leftArrow: false, rightArrow: false, wordLeft: false, wordRight: false, home: false, end: false, pageUp: false, pageDown: false, del: false, return: false, newline: false, escape: false, tab: false, backspace: false, ...part });
|
|
14
17
|
function fakeHost() {
|
|
15
18
|
const handle = { close() { }, invalidate() { }, onClose() { } };
|
|
16
19
|
return { capabilities: { remote: false, canFocusNode: false, selfPane: undefined }, mount: () => handle, notice() { }, suspendForChild: () => () => { }, focusNode: async () => false, pickReviewFile: async () => null };
|
|
17
20
|
}
|
|
18
21
|
const status = (c) => c.status;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const inboxDelivery = { placement: 'inline', inbox: true, reply: true };
|
|
22
|
+
async function waitFor(predicate, message) { const end = Date.now() + 5000; while (!predicate()) {
|
|
23
|
+
if (Date.now() > end)
|
|
24
|
+
throw new Error(message);
|
|
25
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
26
|
+
} }
|
|
25
27
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
const client = cliClient();
|
|
29
|
+
const request = await client.createHumanRequest({
|
|
30
|
+
page: { dialect: 'jsx', source: 'export default () => (\n <Page title="Stale row page" subtitle="Pick one">\n <UserQuestion id="choice" label="Restore?" body="Pick one." mode="single" options={[{ id: "yes", label: "Yes" }, { id: "no", label: "No" }]} />\n </Page>\n);\n' },
|
|
31
|
+
delivery: { placement: 'inline', inbox: true, reply: false },
|
|
32
|
+
creator_cwd: daemon.home,
|
|
33
|
+
});
|
|
34
|
+
// Seed the controller's in-memory list while the request is open.
|
|
35
|
+
const controller = new InboxController({ host: fakeHost(), onDirty() { }, onClosed() { }, cols: 100, rows: 24 });
|
|
36
|
+
await waitFor(() => controller.snapshot().items.length === 1, 'pending page is listed');
|
|
37
|
+
// Settle it in the canvas without letting the controller rescan: this is the
|
|
38
|
+
// stale-row state the bug leaves behind, and it stands for a settlement some
|
|
39
|
+
// other surface performed.
|
|
40
|
+
const settledAt = new Date().toISOString();
|
|
41
|
+
const settled = withCanvasWrite((db) => settleRequestLocked(db, {
|
|
42
|
+
request_id: request.request_id,
|
|
43
|
+
outcome: 'answered',
|
|
44
|
+
result_json: JSON.stringify({ schema: 'crtr.page-response/v1', kind: 'page', responses: { choice: { selectedOptionIds: ['yes'], comments: [] } }, summary: 'page submitted', completedAt: settledAt }),
|
|
45
|
+
settled_at: settledAt,
|
|
46
|
+
}));
|
|
47
|
+
assert.notEqual(settled, null, 'the out-of-band settlement wins the terminal transition');
|
|
48
|
+
assert.equal((await client.getHumanRequest(request.request_id)).state, 'answered', 'the request row is terminal');
|
|
49
|
+
assert.equal(existsSync(claimPath(request.request_dir)), false, 'settlement leaves no claim behind');
|
|
37
50
|
assert.equal(controller.snapshot().items.length, 1, 'the in-memory row is still stale');
|
|
38
51
|
// Pressing Enter on the stale row must report the settlement and drop it,
|
|
39
|
-
// never claim it is edited by another inbox.
|
|
52
|
+
// never claim it is edited by another inbox. A claim would still succeed on
|
|
53
|
+
// the directory, so the settled row is recognized from its request record.
|
|
40
54
|
controller.handleKey('', key({ return: true }));
|
|
55
|
+
await waitFor(() => controller.snapshot().items.length === 0, 'the stale row drops on activation');
|
|
41
56
|
const reported = status(controller) ?? '';
|
|
42
57
|
assert.match(reported, /already resolved/, `stale-row activation reports the settlement, got: ${JSON.stringify(reported)}`);
|
|
43
58
|
assert.doesNotMatch(reported, /being edited/, 'a settled row is never "edited by another inbox"');
|
|
44
|
-
assert.equal(controller.snapshot().items.length, 0, 'the stale row drops on activation');
|
|
45
59
|
assert.equal(controller.snapshot().screen, 'list', 'a settled row never opens the detail pane');
|
|
60
|
+
assert.equal(existsSync(claimPath(request.request_dir)), false, 'a stale row is never claimed');
|
|
46
61
|
controller.close();
|
|
47
62
|
console.log('stale-row regression passed');
|
|
48
63
|
}
|
|
49
64
|
finally {
|
|
50
|
-
|
|
51
|
-
rmSync(sources, { recursive: true, force: true });
|
|
52
|
-
delete process.env['CRTR_HOME'];
|
|
65
|
+
await daemon.dispose();
|
|
53
66
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { TicketSummary } from '../../core/human/types.js';
|
|
2
1
|
import type { Key } from './tui/keys.js';
|
|
3
2
|
import type { SurfaceHost } from '../surfaces/host.js';
|
|
3
|
+
import type { InboxRow } from './dto-adapt.js';
|
|
4
4
|
export interface InboxControllerOptions {
|
|
5
5
|
host: SurfaceHost;
|
|
6
6
|
/** Called whenever the rendered frame may have changed. */
|
|
@@ -9,8 +9,8 @@ export interface InboxControllerOptions {
|
|
|
9
9
|
onClosed: () => void;
|
|
10
10
|
cols?: number;
|
|
11
11
|
rows?: number;
|
|
12
|
-
scan?: () =>
|
|
13
|
-
/** Replaces the default
|
|
12
|
+
scan?: () => Promise<InboxRow[]>;
|
|
13
|
+
/** Replaces the default rescan after inbox activity. */
|
|
14
14
|
onInboxActivity?: () => void;
|
|
15
15
|
/** Ticket dir to seat the selection on at construction, when present. */
|
|
16
16
|
initialSelection?: string;
|
|
@@ -39,19 +39,31 @@ export declare class InboxController {
|
|
|
39
39
|
private heartbeat;
|
|
40
40
|
private started;
|
|
41
41
|
private closed;
|
|
42
|
-
/** The selected page's
|
|
43
|
-
*
|
|
42
|
+
/** The selected page's projection, kept across frames because fetching it is
|
|
43
|
+
* a round trip. `view` is held so a width change re-wraps without one. */
|
|
44
44
|
private preview;
|
|
45
|
+
/** A preview read that failed, so the panel says so instead of staying blank. */
|
|
46
|
+
private previewFailed;
|
|
47
|
+
/** In-flight preview fetch, keyed by dir: one request per selection at a time. */
|
|
48
|
+
private previewFetching;
|
|
49
|
+
/** Set by `invalidate`: the held preview may no longer be the current revision. */
|
|
50
|
+
private previewStale;
|
|
51
|
+
/** The revision the open detail was loaded from, so a replacement published
|
|
52
|
+
* while the reader has the page open reloads it. */
|
|
53
|
+
private openRevision;
|
|
45
54
|
constructor(options: InboxControllerOptions);
|
|
46
55
|
snapshot(): {
|
|
47
|
-
items:
|
|
56
|
+
items: InboxRow[];
|
|
48
57
|
selectedDir?: string;
|
|
49
58
|
screen: Screen;
|
|
50
59
|
inputBuffer?: string;
|
|
51
60
|
};
|
|
52
|
-
rescan(): void
|
|
61
|
+
rescan(): Promise<void>;
|
|
53
62
|
start(): void;
|
|
54
|
-
|
|
63
|
+
/** Inbox activity is the one signal a replacement always emits, and it is
|
|
64
|
+
* emitted after the new revision is selected — so an open page reloads here
|
|
65
|
+
* rather than from a file watch that cannot see a directory swap. */
|
|
66
|
+
invalidate(): Promise<void>;
|
|
55
67
|
resize(cols: number, rows: number): void;
|
|
56
68
|
render(): string[];
|
|
57
69
|
handleKey(input: string, key: Key): void;
|
|
@@ -60,12 +72,15 @@ export declare class InboxController {
|
|
|
60
72
|
* row without a fast action says so rather than opening the page: the key
|
|
61
73
|
* means one thing, and the page is what Enter is for. */
|
|
62
74
|
private sendFastAction;
|
|
75
|
+
/** A review and a page are two different durable records; the inbox dismisses
|
|
76
|
+
* whichever one the selected row actually is. */
|
|
63
77
|
private cancelFromInbox;
|
|
64
|
-
activate(): void
|
|
78
|
+
activate(): Promise<void>;
|
|
65
79
|
private activateReview;
|
|
66
80
|
/** Seat the selection on a ticket dir, when present in the current list. */
|
|
67
81
|
selectDir(dir: string): void;
|
|
68
|
-
|
|
82
|
+
/** Re-read the open page and reload it only when its revision actually moved. */
|
|
83
|
+
reloadSelectedPage(): Promise<void>;
|
|
69
84
|
close(): void;
|
|
70
85
|
private complete;
|
|
71
86
|
/** Edit the active buffer while the host releases the terminal to $EDITOR. */
|
|
@@ -75,12 +90,22 @@ export declare class InboxController {
|
|
|
75
90
|
private detailSize;
|
|
76
91
|
private detailLines;
|
|
77
92
|
private focusAvailable;
|
|
78
|
-
/** Ask the host to bring the
|
|
93
|
+
/** Ask the host to bring the requesting node's viewer into view — the
|
|
94
|
+
* conversation that raised this ask. */
|
|
79
95
|
private focusSelectedSource;
|
|
80
|
-
/** What the selected page actually says
|
|
81
|
-
*
|
|
82
|
-
*
|
|
96
|
+
/** What the selected page actually says. Rendering is synchronous and the
|
|
97
|
+
* page is a round trip, so the projection is held and a miss schedules the
|
|
98
|
+
* fetch, marking the frame dirty when it lands. A width change re-wraps the
|
|
99
|
+
* held projection without another read. */
|
|
83
100
|
private pagePreviewBody;
|
|
101
|
+
/** One in-flight preview read at a time. A revision that did not move keeps
|
|
102
|
+
* the held projection, so activity on an unrelated ticket costs no re-wrap. */
|
|
103
|
+
private schedulePreview;
|
|
104
|
+
/** The request record is the settlement authority: a settled page publishes
|
|
105
|
+
* no file, so a claim would still succeed on its directory. An unreachable
|
|
106
|
+
* daemon reads as "not known to be settled" — the settle attempt that
|
|
107
|
+
* follows is the one that fails loudly. */
|
|
108
|
+
private requestOrNull;
|
|
84
109
|
/** The read-only preview beside the list. It shows the page's own content,
|
|
85
110
|
* because `s` settles the selected ticket from here without ever opening
|
|
86
111
|
* it — a reader must not answer something they were never shown. */
|
|
@@ -88,6 +113,9 @@ export declare class InboxController {
|
|
|
88
113
|
private withStatus;
|
|
89
114
|
private markDirty;
|
|
90
115
|
private watchRoots;
|
|
116
|
+
/** The request directory still carries the claim and progress files other
|
|
117
|
+
* inboxes write. Its page content lives in the daemon-selected revision,
|
|
118
|
+
* which `invalidate` re-reads over the API. */
|
|
91
119
|
private watchSelected;
|
|
92
120
|
}
|
|
93
121
|
export {};
|