@north-light/crouter 0.3.311 → 0.3.313
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +27 -30
- package/dist/api/client.js +80 -67
- package/dist/api/dto/broker-ops.d.ts +10 -20
- package/dist/api/dto/canvas.d.ts +1 -10
- package/dist/api/dto/health.d.ts +113 -0
- package/dist/api/dto/human-requests.d.ts +14 -3
- package/dist/api/dto/human.d.ts +2 -48
- package/dist/api/dto/human.js +3 -2
- package/dist/api/dto/inbox.d.ts +14 -0
- package/dist/api/dto/mail.d.ts +43 -0
- package/dist/api/dto/nodes.d.ts +11 -8
- package/dist/api/dto/recovery.d.ts +96 -0
- package/dist/api/dto/reviews.d.ts +2 -2
- package/dist/api/routes.d.ts +9 -6
- package/dist/api/routes.js +11 -11
- package/dist/build-root.d.ts +4 -0
- package/dist/build-root.js +11 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/cli.js +10 -1
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
- package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
- package/dist/clients/attach/chrome/inbox-strip.js +17 -9
- package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
- package/dist/clients/attach/chrome/ticket-panel.js +77 -46
- package/dist/clients/attach/overlays/graph.js +6 -9
- package/dist/clients/attach/render/chat-view.d.ts +5 -4
- package/dist/clients/attach/render/chat-view.js +22 -13
- package/dist/clients/attach/render/page-block.d.ts +11 -7
- package/dist/clients/attach/render/page-block.js +64 -55
- package/dist/clients/attach/viewer.js +746 -735
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
- package/dist/clients/inbox/controller.d.ts +42 -14
- package/dist/clients/inbox/controller.js +240 -124
- package/dist/clients/inbox/dto-adapt.d.ts +28 -0
- package/dist/clients/inbox/dto-adapt.js +93 -0
- package/dist/clients/inbox/page-adapter.d.ts +5 -4
- package/dist/clients/inbox/page-adapter.js +12 -12
- package/dist/clients/inbox/resolve.d.ts +10 -5
- package/dist/clients/inbox/resolve.js +13 -12
- package/dist/clients/inbox/review/review-client.d.ts +0 -1
- package/dist/clients/inbox/review/review-client.js +0 -4
- package/dist/clients/inbox/review-adapter.d.ts +2 -1
- package/dist/clients/inbox/review-adapter.js +3 -5
- package/dist/clients/inbox/surface.d.ts +2 -2
- package/dist/clients/inbox/surface.js +19 -8
- package/dist/clients/inbox/tui.d.ts +3 -3
- package/dist/commands/__tests__/human.test.js +31 -15
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
- package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
- package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
- package/dist/commands/api-client.d.ts +5 -4
- package/dist/commands/api-client.js +13 -7
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas-roster.js +1 -1
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/human/feedback.js +20 -17
- package/dist/commands/human/prompts.js +45 -36
- package/dist/commands/human/queue.js +73 -123
- package/dist/commands/human/review.js +6 -16
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
- package/dist/commands/node-inspect-artifacts.js +1 -1
- package/dist/commands/node-lifecycle-revive.d.ts +2 -2
- package/dist/commands/node-lifecycle-revive.js +9 -19
- package/dist/commands/pkg/plugin-manage.js +0 -1
- package/dist/commands/profile/show.js +4 -12
- package/dist/commands/surface-tmux-spread.js +1 -5
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
- package/dist/commands/sys/branch.d.ts +2 -0
- package/dist/commands/sys/branch.js +19 -0
- package/dist/commands/sys/config.js +106 -33
- package/dist/commands/sys/daemon.d.ts +2 -0
- package/dist/commands/sys/daemon.js +130 -7
- package/dist/commands/sys/doctor.js +5 -15
- package/dist/commands/sys/migrate.js +21 -92
- package/dist/commands/sys/setup-settings-runner.js +4 -2
- package/dist/commands/sys.js +2 -15
- package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
- package/dist/core/__tests__/boot.test.js +32 -25
- package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
- package/dist/core/__tests__/canvas.test.js +18 -47
- package/dist/core/__tests__/child-death-wake.test.js +29 -7
- package/dist/core/__tests__/cli-help-contract.test.js +2 -0
- package/dist/core/__tests__/close.test.js +29 -10
- package/dist/core/__tests__/collectible.test.js +2 -1
- package/dist/core/__tests__/config-change-delta.test.js +2 -0
- package/dist/core/__tests__/context-intro.test.js +17 -5
- package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
- package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
- package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
- package/dist/core/__tests__/daemon-boot.test.js +51 -14
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
- package/dist/core/__tests__/focuses.test.js +10 -5
- package/dist/core/__tests__/helpers/harness.js +50 -18
- package/dist/core/__tests__/history-inbox.test.js +12 -16
- package/dist/core/__tests__/human-action-delivery.test.js +48 -28
- package/dist/core/__tests__/human-actions.test.js +7 -3
- package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
- package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +312 -1
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
- package/dist/core/__tests__/integration/revive.test.js +67 -21
- package/dist/core/__tests__/integration/spawn-root.test.js +62 -19
- package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
- package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
- package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
- package/dist/core/__tests__/kickoff.test.js +36 -39
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
- package/dist/core/__tests__/lifecycle.test.js +2 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
- package/dist/core/__tests__/migration.test.js +145 -31
- package/dist/core/__tests__/model-pin-durability.test.js +4 -1
- package/dist/core/__tests__/model-routes-config.test.js +13 -5
- package/dist/core/__tests__/node-outcome.test.js +93 -26
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +4 -3
- package/dist/core/__tests__/on-read-dedup-resume.test.js +8 -7
- package/dist/core/__tests__/on-read-nested-store.test.js +8 -7
- package/dist/core/__tests__/passive-subscription.test.js +50 -157
- package/dist/core/__tests__/plugin-kinds.test.js +6 -4
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
- package/dist/core/__tests__/plugin-page-components.test.js +6 -4
- package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +35 -32
- package/dist/core/__tests__/prune.test.js +11 -5
- package/dist/core/__tests__/push-final-guard.test.js +14 -7
- package/dist/core/__tests__/relaunch-root.test.js +30 -2
- package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
- package/dist/core/__tests__/repository-root-identity.test.js +4 -0
- package/dist/core/__tests__/review-model-floor.test.js +6 -3
- package/dist/core/__tests__/revive-all.test.js +13 -3
- package/dist/core/__tests__/revive-capacity.test.js +26 -4
- package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
- package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +5 -4
- package/dist/core/__tests__/stop-guard.test.js +2 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +19 -5
- package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
- package/dist/core/broker-client/transport-socket.d.ts +1 -0
- package/dist/core/broker-client/transport-socket.js +13 -5
- package/dist/core/canvas/__tests__/attention.test.js +29 -35
- package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
- package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
- package/dist/core/canvas/attention.d.ts +2 -5
- package/dist/core/canvas/attention.js +15 -64
- package/dist/core/canvas/boot.d.ts +6 -7
- package/dist/core/canvas/boot.js +5 -9
- package/dist/core/canvas/canvas.d.ts +13 -109
- package/dist/core/canvas/canvas.js +140 -401
- package/dist/core/canvas/crons.d.ts +2 -0
- package/dist/core/canvas/crons.js +16 -15
- package/dist/core/canvas/daemon-owner.js +10 -0
- package/dist/core/canvas/db.d.ts +2 -2
- package/dist/core/canvas/db.js +2 -18
- package/dist/core/canvas/deliveries.d.ts +104 -0
- package/dist/core/canvas/deliveries.js +354 -0
- package/dist/core/canvas/executions.d.ts +29 -0
- package/dist/core/canvas/executions.js +68 -0
- package/dist/core/canvas/history.js +35 -35
- package/dist/core/canvas/index.d.ts +3 -1
- package/dist/core/canvas/index.js +3 -1
- package/dist/core/canvas/migrations.js +20 -12
- package/dist/core/canvas/nav-model.js +1 -3
- package/dist/core/canvas/nav-render.d.ts +4 -4
- package/dist/core/canvas/nav-render.js +11 -21
- package/dist/core/canvas/node-sql-migration.d.ts +3 -0
- package/dist/core/canvas/node-sql-migration.js +261 -0
- package/dist/core/canvas/paths.d.ts +2 -16
- package/dist/core/canvas/paths.js +2 -31
- package/dist/core/canvas/recovery.d.ts +76 -0
- package/dist/core/canvas/recovery.js +588 -0
- package/dist/core/canvas/remote-canvas-source.js +4 -0
- package/dist/core/canvas/render-source.d.ts +16 -27
- package/dist/core/canvas/render-source.js +16 -45
- package/dist/core/canvas/sessions.d.ts +33 -0
- package/dist/core/canvas/sessions.js +78 -0
- package/dist/core/canvas/types.d.ts +33 -33
- package/dist/core/canvas/types.js +2 -5
- package/dist/core/canvas/waits.d.ts +18 -0
- package/dist/core/canvas/waits.js +70 -0
- package/dist/core/canvas/worktrees.d.ts +40 -0
- package/dist/core/canvas/worktrees.js +93 -0
- package/dist/core/command-hooks/artifact.d.ts +6 -0
- package/dist/core/command-hooks/artifact.js +22 -6
- package/dist/core/command-hooks/discovery.d.ts +2 -0
- package/dist/core/command-hooks/discovery.js +2 -0
- package/dist/core/command-hooks/lifecycle-catalog.d.ts +20 -2
- package/dist/core/command-hooks/lifecycle-catalog.js +7 -2
- package/dist/core/command-hooks/lifecycle-create.d.ts +4 -0
- package/dist/core/command-hooks/lifecycle-create.js +51 -0
- package/dist/core/command-hooks/schema.d.ts +2 -2
- package/dist/core/command-hooks/schema.js +5 -4
- package/dist/core/command-hooks/transport/exec-invoke.js +3 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +18 -8
- package/dist/core/command-hooks/transport/exec-lifecycle.js +89 -30
- package/dist/core/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- package/dist/core/errors.d.ts +1 -0
- package/dist/core/errors.js +4 -0
- package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
- package/dist/core/feed/feed.d.ts +0 -6
- package/dist/core/feed/feed.js +68 -56
- package/dist/core/feed/inbox.d.ts +7 -81
- package/dist/core/feed/inbox.js +46 -378
- package/dist/core/feed/messages.d.ts +58 -0
- package/dist/core/feed/messages.js +217 -0
- package/dist/core/fs-utils.d.ts +4 -0
- package/dist/core/fs-utils.js +21 -1
- package/dist/core/human/answer.d.ts +1 -1
- package/dist/core/human/answer.js +1 -1
- package/dist/core/human/claim.d.ts +1 -1
- package/dist/core/human/claim.js +2 -4
- package/dist/core/human/component-docs.js +1 -1
- package/dist/core/human/feedback-companion.js +4 -3
- package/dist/core/human/feedback.d.ts +5 -8
- package/dist/core/human/feedback.js +57 -85
- package/dist/core/human/page-authoring.d.ts +30 -0
- package/dist/core/human/page-authoring.js +19 -0
- package/dist/core/human/requests.d.ts +136 -0
- package/dist/core/human/requests.js +515 -0
- package/dist/core/human/root.d.ts +0 -7
- package/dist/core/human/root.js +0 -17
- package/dist/core/human/scan.d.ts +2 -7
- package/dist/core/human/scan.js +48 -132
- package/dist/core/human/summary.d.ts +1 -1
- package/dist/core/human/summary.js +1 -1
- package/dist/core/human/tickets.d.ts +23 -83
- package/dist/core/human/tickets.js +92 -243
- package/dist/core/human/types.d.ts +5 -1
- package/dist/core/installed-plugins.js +8 -3
- package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
- package/dist/core/locked-file.d.ts +6 -3
- package/dist/core/locked-file.js +36 -9
- package/dist/core/memory/extensions.js +2 -0
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +2 -0
- package/dist/core/profiles/default-binding.d.ts +0 -4
- package/dist/core/profiles/default-binding.js +12 -58
- package/dist/core/profiles/env-store.js +8 -3
- package/dist/core/profiles/manifest.d.ts +2 -37
- package/dist/core/profiles/manifest.js +35 -161
- package/dist/core/profiles/select.js +3 -0
- package/dist/core/review/__tests__/capture-origin.test.js +13 -2
- package/dist/core/review/__tests__/comments.test.js +28 -10
- package/dist/core/review/__tests__/remap.test.js +28 -10
- package/dist/core/review/__tests__/stage-identity.test.js +17 -7
- package/dist/core/review/birth.d.ts +1 -1
- package/dist/core/review/birth.js +34 -5
- package/dist/core/review/comments.js +1 -1
- package/dist/core/review/companion.d.ts +1 -1
- package/dist/core/review/companion.js +2 -2
- package/dist/core/review/document.js +1 -1
- package/dist/core/review/project.d.ts +5 -1
- package/dist/core/review/project.js +14 -36
- package/dist/core/review/realize.d.ts +3 -6
- package/dist/core/review/realize.js +51 -168
- package/dist/core/review/remap.js +1 -1
- package/dist/core/review/stage.d.ts +3 -2
- package/dist/core/review/stage.js +2 -3
- package/dist/core/review/store.d.ts +3 -21
- package/dist/core/review/store.js +140 -186
- package/dist/core/review/types.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
- package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
- package/dist/core/runtime/broker/auth-reload.js +9 -10
- package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
- package/dist/core/runtime/broker/daemon-ops.js +42 -9
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +11 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
- package/dist/core/runtime/broker/fault-retry.js +142 -95
- package/dist/core/runtime/broker/inbox.d.ts +4 -32
- package/dist/core/runtime/broker/inbox.js +4 -92
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +21 -12
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -13
- package/dist/core/runtime/broker.js +28 -22
- package/dist/core/runtime/close.d.ts +3 -9
- package/dist/core/runtime/close.js +16 -27
- package/dist/core/runtime/fault.d.ts +3 -93
- package/dist/core/runtime/fault.js +9 -419
- package/dist/core/runtime/kickoff.d.ts +3 -6
- package/dist/core/runtime/kickoff.js +12 -18
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +40 -7
- package/dist/core/runtime/nodes.d.ts +5 -1
- package/dist/core/runtime/nodes.js +26 -11
- package/dist/core/runtime/placement.js +2 -2
- package/dist/core/runtime/recycle.js +24 -14
- package/dist/core/runtime/reset.js +26 -7
- package/dist/core/runtime/revive.js +226 -217
- package/dist/core/runtime/spawn.d.ts +4 -1
- package/dist/core/runtime/spawn.js +43 -5
- package/dist/core/runtime/warm-pool.d.ts +2 -2
- package/dist/core/runtime/warm-pool.js +23 -3
- package/dist/core/scoped-state/db.d.ts +7 -0
- package/dist/core/scoped-state/db.js +92 -0
- package/dist/core/scoped-state/migrate.d.ts +11 -0
- package/dist/core/scoped-state/migrate.js +198 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +12 -0
- package/dist/core/scoped-state/profiles.js +62 -0
- package/dist/core/scoped-state/providers.d.ts +16 -0
- package/dist/core/scoped-state/providers.js +8 -0
- package/dist/core/scoped-state/schema.d.ts +3 -0
- package/dist/core/scoped-state/schema.js +26 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +82 -0
- package/dist/core/subscription-state.d.ts +29 -48
- package/dist/core/subscription-state.js +176 -712
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +2 -2
- package/dist/core/worktree-sweep.js +11 -16
- package/dist/core/worktree.js +6 -12
- package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
- package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
- package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
- package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +41 -17
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
- package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
- package/dist/daemon/api/__tests__/model-config.test.js +8 -8
- package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +6 -3
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
- package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +29 -43
- package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
- package/dist/daemon/api/bridge.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +6 -7
- package/dist/daemon/api/handlers/broker-ops.js +47 -84
- package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
- package/dist/daemon/api/handlers/broker-recovery.js +251 -0
- package/dist/daemon/api/handlers/canvas.js +2 -44
- package/dist/daemon/api/handlers/daemon.js +41 -0
- package/dist/daemon/api/handlers/feedback-comments.js +2 -2
- package/dist/daemon/api/handlers/health.js +10 -5
- package/dist/daemon/api/handlers/human-requests.js +168 -188
- package/dist/daemon/api/handlers/human.js +3 -148
- package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
- package/dist/daemon/api/handlers/inbox-page.js +89 -0
- package/dist/daemon/api/handlers/inbox.js +21 -120
- package/dist/daemon/api/handlers/messages.d.ts +1 -0
- package/dist/daemon/api/handlers/messages.js +73 -15
- package/dist/daemon/api/handlers/node-outcomes.js +58 -13
- package/dist/daemon/api/handlers/nodes.d.ts +1 -0
- package/dist/daemon/api/handlers/nodes.js +41 -42
- package/dist/daemon/api/handlers/reviews.js +4 -29
- package/dist/daemon/api/map.d.ts +25 -3
- package/dist/daemon/api/map.js +84 -14
- package/dist/daemon/api/server.js +68 -9
- package/dist/daemon/control.d.ts +18 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +8 -5
- package/dist/daemon/cron/settle.js +37 -13
- package/dist/daemon/cron/sinks.d.ts +18 -1
- package/dist/daemon/cron/sinks.js +47 -93
- package/dist/daemon/crtrd-cli.js +4 -19
- package/dist/daemon/crtrd.d.ts +2 -0
- package/dist/daemon/crtrd.js +206 -81
- package/dist/daemon/fleet.js +5 -6
- package/dist/daemon/human/finish.d.ts +12 -24
- package/dist/daemon/human/finish.js +88 -285
- package/dist/daemon/human/settle.d.ts +40 -0
- package/dist/daemon/human/settle.js +89 -0
- package/dist/daemon/human/sweep.d.ts +20 -5
- package/dist/daemon/human/sweep.js +56 -60
- package/dist/daemon/manage.d.ts +21 -16
- package/dist/daemon/manage.js +85 -51
- package/dist/daemon/messaging/node-message.d.ts +1 -1
- package/dist/daemon/messaging/node-message.js +9 -12
- package/dist/daemon/park-activity.js +3 -3
- package/dist/daemon/reconcilers/bash-deadline.js +6 -7
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +41 -19
- package/dist/daemon/reconcilers/controller-death.js +6 -18
- package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/delivery-lane.js +130 -0
- package/dist/daemon/reconcilers/live-obligation.js +3 -3
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
- package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
- package/dist/daemon/review/companion.js +5 -11
- package/dist/daemon/review/deliver.d.ts +1 -5
- package/dist/daemon/review/deliver.js +3 -52
- package/dist/daemon/review/finish.d.ts +2 -27
- package/dist/daemon/review/finish.js +79 -263
- package/dist/daemon/review/sweep.d.ts +3 -10
- package/dist/daemon/review/sweep.js +13 -131
- package/dist/daemon/startup-policy.d.ts +0 -5
- package/dist/daemon/startup-policy.js +0 -5
- package/dist/hook-authoring.d.ts +28 -2
- package/dist/hook-authoring.js +53 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
- package/dist/migrations/__tests__/activation.test.js +9 -6
- package/dist/migrations/activation.d.ts +3 -2
- package/dist/migrations/activation.js +2 -4
- package/dist/migrations/corpus.d.ts +2 -5
- package/dist/migrations/corpus.js +9 -20
- package/dist/migrations/runner.d.ts +3 -1
- package/dist/migrations/runner.js +6 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
- package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
- package/dist/pi-extensions/canvas-passive-context.js +85 -37
- package/dist/pi-extensions/canvas-stophook.js +47 -31
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.js +3 -0
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/dist/clients/attach/__tests__/page-block.test.js +0 -54
- package/dist/clients/inbox/review-visibility.d.ts +0 -5
- package/dist/clients/inbox/review-visibility.js +0 -19
- package/dist/commands/canvas-rebuild-index.d.ts +0 -2
- package/dist/commands/canvas-rebuild-index.js +0 -46
- package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
- package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
- package/dist/core/__tests__/human-deliver.test.js +0 -256
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
- package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
- package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
- package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
- package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-store.test.js +0 -144
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
- package/dist/core/canvas/human-deliveries.d.ts +0 -39
- package/dist/core/canvas/human-deliveries.js +0 -75
- package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
- package/dist/core/canvas/node-outcome-deliveries.js +0 -159
- package/dist/core/feed/passive.d.ts +0 -3
- package/dist/core/feed/passive.js +0 -53
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
- package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
- package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-tickets.test.js +0 -161
- package/dist/core/review/ticket-filter.d.ts +0 -17
- package/dist/core/review/ticket-filter.js +0 -21
- package/dist/core/runtime/broker/passive.d.ts +0 -17
- package/dist/core/runtime/broker/passive.js +0 -44
- package/dist/core/runtime/busy.d.ts +0 -46
- package/dist/core/runtime/busy.js +0 -150
- package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
- package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
- package/dist/daemon/human/deliver-action.d.ts +0 -3
- package/dist/daemon/human/deliver-action.js +0 -9
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
- package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
- package/dist/daemon/startup-block-marker.d.ts +0 -25
- package/dist/daemon/startup-block-marker.js +0 -99
- /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
- /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
- /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
|
@@ -24,15 +24,14 @@ import { envNodeId } from '../shared/env.js';
|
|
|
24
24
|
import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
|
|
25
25
|
import { join } from 'node:path';
|
|
26
26
|
import { contextDir, jobDir } from '../core/canvas/paths.js';
|
|
27
|
-
import {
|
|
28
|
-
import { clearFault } from '../core/runtime/fault.js';
|
|
27
|
+
import { mutateBrokerFault, recordBrokerTurn } from '../core/runtime/broker/daemon-ops.js';
|
|
29
28
|
import { clearStopSignals, consumeStopSignals } from '../core/runtime/stop-signals.js';
|
|
30
29
|
import { bindBrokerSession, brokerExtensionState, relaunchBrokerRoot, settleBroker } from '../core/runtime/broker/daemon-ops.js';
|
|
31
30
|
import { emitEvent } from '../core/events/emit.js';
|
|
32
31
|
import { activeBackgroundBashJobs } from '../core/bash-jobs.js';
|
|
33
32
|
import { CONTEXT_NUDGE_CUSTOM_TYPE, formatCard } from '../shared/generated-context.js';
|
|
34
33
|
import { isReviewBoundary } from '../core/runtime/session-visibility.js';
|
|
35
|
-
import { runRefreshAbort } from '../core/runtime/broker/extension-abort.js';
|
|
34
|
+
import { clearRefusedTurn, refuseTurn, runRefreshAbort } from '../core/runtime/broker/extension-abort.js';
|
|
36
35
|
import { announceMessageOrigin } from '../core/runtime/stamp/channel.js';
|
|
37
36
|
/** Condense a tool call into one short line for the activity cue. Picks the most
|
|
38
37
|
* identifying arg (command / path / pattern / description), collapses whitespace,
|
|
@@ -283,15 +282,7 @@ export function registerCanvasStophook(pi) {
|
|
|
283
282
|
catch { /* Pi shutdown is local best-effort */ }
|
|
284
283
|
}
|
|
285
284
|
};
|
|
286
|
-
//
|
|
287
|
-
// times per second while streaming, and touchBusy is a disk write — rate-limit
|
|
288
|
-
// it to at most once per HEARTBEAT_THROTTLE_MS. The daemon's wedge grace is
|
|
289
|
-
// measured in minutes, so this throttle costs it nothing. Also clears any
|
|
290
|
-
// stale `daemon→node` wedge fault at the same throttled cadence: a sign of
|
|
291
|
-
// life should both refresh the heartbeat marker AND clear a stale wedge
|
|
292
|
-
// notice as one coherent act, same as every coarser progress site below
|
|
293
|
-
// (tool execution, turn_end, agent_settled) already does. clearFault is
|
|
294
|
-
// a cheap no-op when no fault exists, so this stays safe to call every time.
|
|
285
|
+
// Streaming updates are rate-limited because daemon wedge grace is measured in minutes.
|
|
295
286
|
const HEARTBEAT_THROTTLE_MS = 3_000;
|
|
296
287
|
let lastHeartbeatAt = 0;
|
|
297
288
|
const heartbeat = () => {
|
|
@@ -299,8 +290,10 @@ export function registerCanvasStophook(pi) {
|
|
|
299
290
|
if (now - lastHeartbeatAt < HEARTBEAT_THROTTLE_MS)
|
|
300
291
|
return;
|
|
301
292
|
lastHeartbeatAt = now;
|
|
302
|
-
|
|
303
|
-
|
|
293
|
+
void Promise.all([
|
|
294
|
+
recordBrokerTurn(nodeId, { event: 'progress' }),
|
|
295
|
+
mutateBrokerFault(nodeId, { op: 'clear', link: 'daemon→node' }),
|
|
296
|
+
]).catch((error) => emitDaemonOperationFailure('turn_progress', error));
|
|
304
297
|
};
|
|
305
298
|
// session_start — capture pi's session id, and detect `/new`.
|
|
306
299
|
//
|
|
@@ -385,13 +378,19 @@ export function registerCanvasStophook(pi) {
|
|
|
385
378
|
// agent_start — pi entered a turn. Mark the node mid-turn (busy) so a
|
|
386
379
|
// focus-away while it is genuinely working backstages it (Invariant F2)
|
|
387
380
|
// rather than reaping it. Cleared only after the whole run settles.
|
|
388
|
-
pi.on('agent_start', () => {
|
|
389
|
-
// A
|
|
390
|
-
//
|
|
381
|
+
pi.on('agent_start', async (_event, ctx) => {
|
|
382
|
+
// A turn may not enter Pi until crtrd has fenced and recorded it. Otherwise
|
|
383
|
+
// a broker that lost daemon ownership can run work with no durable turn.
|
|
391
384
|
try {
|
|
392
|
-
|
|
385
|
+
const result = await recordBrokerTurn(nodeId, { event: 'started' });
|
|
386
|
+
if (!result.applied)
|
|
387
|
+
throw new Error('daemon refused turn open');
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
emitDaemonOperationFailure('turn_open', error);
|
|
391
|
+
ctx?.ui?.notify?.('Turn refused: the broker no longer owns this node.', 'error');
|
|
392
|
+
refuseTurn(() => ctx?.abort?.());
|
|
393
393
|
}
|
|
394
|
-
catch { /* best-effort */ }
|
|
395
394
|
});
|
|
396
395
|
// input — a new user-directed run is beginning. This is the ONLY place stop
|
|
397
396
|
// signals are cleared: `agent_start` re-fires for pi's automatic retries and
|
|
@@ -403,6 +402,7 @@ export function registerCanvasStophook(pi) {
|
|
|
403
402
|
// of this same broker is discarded here, when the next prompt arrives (the pid
|
|
404
403
|
// stamp only rules out a PRIOR broker's markers, not this broker's own).
|
|
405
404
|
pi.on('input', () => {
|
|
405
|
+
clearRefusedTurn();
|
|
406
406
|
try {
|
|
407
407
|
clearStopSignals(nodeId);
|
|
408
408
|
}
|
|
@@ -415,8 +415,7 @@ export function registerCanvasStophook(pi) {
|
|
|
415
415
|
try {
|
|
416
416
|
lastActivity = summarizeActivity(String(event?.toolName ?? ''), event?.args);
|
|
417
417
|
flushTelemetry(jobDirPath, totalIn, totalOut, model, lastContext, lastActivity);
|
|
418
|
-
|
|
419
|
-
clearFault(nodeId, { link: 'daemon→node' }); // a tool actually starting clears any prior wedge notice
|
|
418
|
+
heartbeat(); // a fresh tool starting is a sign of life
|
|
420
419
|
}
|
|
421
420
|
catch { /* best-effort */ }
|
|
422
421
|
});
|
|
@@ -458,8 +457,7 @@ export function registerCanvasStophook(pi) {
|
|
|
458
457
|
// refreshes on its first tool — the desired outcome.)
|
|
459
458
|
pi.on('tool_execution_end', async (_event, ctx) => {
|
|
460
459
|
try {
|
|
461
|
-
|
|
462
|
-
clearFault(nodeId, { link: 'daemon→node' }); // a tool that was "stuck" just returned — the wedge notice was resolved
|
|
460
|
+
heartbeat(); // a tool that returned is a sign of life
|
|
463
461
|
if ((await brokerExtensionState(nodeId)).node.intent === 'refresh') {
|
|
464
462
|
// Stop this turn immediately so the large context does not keep running.
|
|
465
463
|
// The broker clears Pi's queued steering/follow-up messages inside this
|
|
@@ -479,7 +477,12 @@ export function registerCanvasStophook(pi) {
|
|
|
479
477
|
// finish transition, focus teardown, presence clear, and fault clear. Other
|
|
480
478
|
// session swaps keep the same node and need no durable settlement.
|
|
481
479
|
pi.on('session_shutdown', async (event, ctx) => {
|
|
482
|
-
|
|
480
|
+
try {
|
|
481
|
+
await recordBrokerTurn(nodeId, { event: 'closed', end_reason: 'teardown-aborted' });
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
emitDaemonOperationFailure('turn_close_teardown', error);
|
|
485
|
+
}
|
|
483
486
|
if (event?.reason !== 'quit')
|
|
484
487
|
return;
|
|
485
488
|
try {
|
|
@@ -526,9 +529,16 @@ export function registerCanvasStophook(pi) {
|
|
|
526
529
|
lastContext = contextTokens;
|
|
527
530
|
// Fire-and-forget: flushTelemetry uses synchronous fs writes and never throws.
|
|
528
531
|
flushTelemetry(jobDirPath, totalIn, totalOut, model, contextTokens, lastActivity);
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
+
heartbeat(); // reaching turn_end proves this turn was not wedged
|
|
533
|
+
try {
|
|
534
|
+
await Promise.all([
|
|
535
|
+
mutateBrokerFault(nodeId, { op: 'clear', link: 'daemon→node' }),
|
|
536
|
+
mutateBrokerFault(nodeId, { op: 'clear', link: 'pi→provider' }),
|
|
537
|
+
]);
|
|
538
|
+
}
|
|
539
|
+
catch (error) {
|
|
540
|
+
emitDaemonOperationFailure('turn_end_fault_clear', error);
|
|
541
|
+
}
|
|
532
542
|
// Will the agent run CONTINUE past this turn? Deterministic at turn_end:
|
|
533
543
|
// the loop keeps going exactly when this assistant message carried tool
|
|
534
544
|
// calls and the run wasn't aborted/errored (those end unconditionally,
|
|
@@ -598,10 +608,16 @@ export function registerCanvasStophook(pi) {
|
|
|
598
608
|
pi.on('agent_settled', async (_event, ctx) => {
|
|
599
609
|
const event = stagedAgentEnd;
|
|
600
610
|
stagedAgentEnd = null;
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
//
|
|
604
|
-
|
|
611
|
+
// crtrd owns the durable turn close, fault marker, stop policy, lifecycle
|
|
612
|
+
// transition, focus, and mail decision even when Pi had no stageable final
|
|
613
|
+
// agent_end payload.
|
|
614
|
+
try {
|
|
615
|
+
await recordBrokerTurn(nodeId, { event: 'closed', end_reason: 'settled' });
|
|
616
|
+
}
|
|
617
|
+
catch (error) {
|
|
618
|
+
emitDaemonOperationFailure('turn_close', error);
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
605
621
|
const messages = Array.isArray(event?.messages) ? event.messages : [];
|
|
606
622
|
const last = lastAssistantMessage(messages);
|
|
607
623
|
const stopReason = typeof last?.stopReason === 'string' ? last.stopReason : '';
|
package/dist/shared/env.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** The current node's id (`CRTR_NODE_ID`), or undefined outside a node. */
|
|
2
2
|
export declare function envNodeId(): string | undefined;
|
|
3
|
+
export declare function envExecutionId(): string | undefined;
|
|
3
4
|
/** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
|
|
4
5
|
export declare function envProfileId(): string | undefined;
|
|
5
6
|
/** The current node's working directory (`CRTR_NODE_CWD`), or undefined. */
|
package/dist/shared/env.js
CHANGED
|
@@ -26,6 +26,9 @@
|
|
|
26
26
|
export function envNodeId() {
|
|
27
27
|
return process.env['CRTR_NODE_ID'];
|
|
28
28
|
}
|
|
29
|
+
export function envExecutionId() {
|
|
30
|
+
return process.env['CRTR_EXECUTION_ID'];
|
|
31
|
+
}
|
|
29
32
|
/** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
|
|
30
33
|
export function envProfileId() {
|
|
31
34
|
return process.env['CRTR_PROFILE_ID'];
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.313",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.313",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"workspaces": [
|
|
@@ -5206,17 +5206,17 @@
|
|
|
5206
5206
|
},
|
|
5207
5207
|
"packages/crouter-api": {
|
|
5208
5208
|
"name": "@north-light/crouter-api",
|
|
5209
|
-
"version": "0.3.
|
|
5209
|
+
"version": "0.3.313",
|
|
5210
5210
|
"license": "UNLICENSED"
|
|
5211
5211
|
},
|
|
5212
5212
|
"packages/crouter-env-docker": {
|
|
5213
5213
|
"name": "@north-light/crouter-env-docker",
|
|
5214
|
-
"version": "0.3.
|
|
5214
|
+
"version": "0.3.313",
|
|
5215
5215
|
"license": "UNLICENSED"
|
|
5216
5216
|
},
|
|
5217
5217
|
"packages/crouter-sdk": {
|
|
5218
5218
|
"name": "@north-light/crouter-sdk",
|
|
5219
|
-
"version": "0.3.
|
|
5219
|
+
"version": "0.3.313",
|
|
5220
5220
|
"license": "UNLICENSED",
|
|
5221
5221
|
"dependencies": {
|
|
5222
5222
|
"@north-light/crouter-api": "^0.3.295"
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { mkdtempSync, utimesSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import test from 'node:test';
|
|
6
|
-
import { atomicWriteJson, pageManifestPath, pagePath } from '../../../core/human/convention.js';
|
|
7
|
-
import { derivePageManifestFromDocument } from '../../../core/human/page.js';
|
|
8
|
-
import { sanitize } from '../../inbox/tui/ansi.js';
|
|
9
|
-
import { PageBlockComponent } from '../render/page-block.js';
|
|
10
|
-
function proposal(intro) {
|
|
11
|
-
return `const DOCS = ['Local stack', 'Guest home', 'Data and dependencies', 'Troubleshooting'];
|
|
12
|
-
function Proposal({ docs }) {
|
|
13
|
-
return (
|
|
14
|
-
<Card>
|
|
15
|
-
<p>Move the <code>{docs.length}</code> operational areas behind focused pointers.</p>
|
|
16
|
-
<ul>{docs.map((doc) => <li key={doc}><strong>{doc}</strong> reference</li>)}</ul>
|
|
17
|
-
</Card>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
export default function DevMemorySplit() {
|
|
21
|
-
return (
|
|
22
|
-
<Page title="Northlight dev memory" subtitle="Choose the documentation shape">
|
|
23
|
-
<p>${intro}</p>
|
|
24
|
-
<Proposal docs={DOCS} />
|
|
25
|
-
<UserQuestion id="decision" label="Approve the split?" body="The current file is 4,189 words." mode="single" options={[{ id: 'approve', label: 'Approve' }, { id: 'keep', label: 'Keep one file' }]} />
|
|
26
|
-
</Page>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
`;
|
|
30
|
-
}
|
|
31
|
-
test('an inline page renders dynamic display JSX beside its manifest question and refreshes source-only revisions', () => {
|
|
32
|
-
const dir = mkdtempSync(join(tmpdir(), 'crtr-page-block-'));
|
|
33
|
-
const source = proposal('The current guide mixes routing and operational detail.');
|
|
34
|
-
const manifest = derivePageManifestFromDocument(source);
|
|
35
|
-
writeFileSync(pagePath(dir), source);
|
|
36
|
-
atomicWriteJson(pageManifestPath(dir), manifest);
|
|
37
|
-
const block = new PageBlockComponent('dev-memory', dir, () => 'open it');
|
|
38
|
-
const rendered = sanitize(block.render(88).join('\n'));
|
|
39
|
-
assert.match(rendered, /The current guide mixes routing and operational detail\./);
|
|
40
|
-
assert.match(rendered, /Move the 4 operational areas behind focused pointers\./);
|
|
41
|
-
assert.match(rendered, /Local stack.*reference/);
|
|
42
|
-
assert.match(rendered, /Troubleshooting.*reference/);
|
|
43
|
-
assert.match(rendered, /Approve the split\?/);
|
|
44
|
-
assert.match(rendered, /The current file is 4,189 words\./);
|
|
45
|
-
assert.match(rendered, /Keep one file/);
|
|
46
|
-
const revised = proposal('The replacement keeps the intent router short.');
|
|
47
|
-
writeFileSync(pagePath(dir), revised);
|
|
48
|
-
const future = new Date(Date.now() + 2_000);
|
|
49
|
-
utimesSync(pagePath(dir), future, future);
|
|
50
|
-
assert.equal(block.refresh(), true);
|
|
51
|
-
const refreshed = sanitize(block.render(88).join('\n'));
|
|
52
|
-
assert.match(refreshed, /The replacement keeps the intent router short\./);
|
|
53
|
-
assert.doesNotMatch(refreshed, /mixes routing and operational detail/);
|
|
54
|
-
});
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { TicketSummary } from '../../core/human/types.js';
|
|
2
|
-
/** Match the daemon's opaque inbox id: canonical tickets root, NUL, bridge id. */
|
|
3
|
-
export declare function opaqueTicketId(canonicalTicketsRoot: string, bridgeNodeId: string): string;
|
|
4
|
-
/** Retain local page rows and only daemon-visible review rows. */
|
|
5
|
-
export declare function filterVisibleReviewTickets(tickets: readonly TicketSummary[], visibleIds: ReadonlySet<string>): TicketSummary[];
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { realpathSync } from 'node:fs';
|
|
3
|
-
import { basename } from 'node:path';
|
|
4
|
-
import { ticketsRoot } from '../../core/human/root.js';
|
|
5
|
-
/** Match the daemon's opaque inbox id: canonical tickets root, NUL, bridge id. */
|
|
6
|
-
export function opaqueTicketId(canonicalTicketsRoot, bridgeNodeId) {
|
|
7
|
-
return createHash('sha256').update(`${canonicalTicketsRoot}\0${bridgeNodeId}`, 'utf8').digest('hex');
|
|
8
|
-
}
|
|
9
|
-
/** Retain local page rows and only daemon-visible review rows. */
|
|
10
|
-
export function filterVisibleReviewTickets(tickets, visibleIds) {
|
|
11
|
-
let canonicalTicketsRoot;
|
|
12
|
-
try {
|
|
13
|
-
canonicalTicketsRoot = realpathSync(ticketsRoot());
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return tickets.filter((ticket) => ticket.kind !== 'review');
|
|
17
|
-
}
|
|
18
|
-
return tickets.filter((ticket) => ticket.kind !== 'review' || visibleIds.has(opaqueTicketId(canonicalTicketsRoot, basename(ticket.dir))));
|
|
19
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// `crtr canvas rebuild-index` — re-derive the node-table index from on-disk metas.
|
|
2
|
-
//
|
|
3
|
-
// canvas.db's node rows are a derived index over `nodes/<id>/meta.json`. When the
|
|
4
|
-
// db is absent or stale relative to the metas — most concretely a remote/guest
|
|
5
|
-
// deployment's recreate-from-template, where node data lives on a durable Volume
|
|
6
|
-
// but canvas.db lives on local disk that the recreate wipes — this verb rebuilds
|
|
7
|
-
// the rows (identity columns) from the surviving metas via `rebuildIndex()`, so a
|
|
8
|
-
// subsequent `node lifecycle revive` finds its node again.
|
|
9
|
-
//
|
|
10
|
-
// Fails loud if metas are present but the rebuild yields zero rows: a silent
|
|
11
|
-
// empty db there means the revive would no-op against nothing.
|
|
12
|
-
//
|
|
13
|
-
// Exported as a leaf; `crtr canvas` (canvas.ts) mounts it.
|
|
14
|
-
import { defineLeaf } from '../core/command.js';
|
|
15
|
-
import { cliClient, rethrowAsCliError } from './api-client.js';
|
|
16
|
-
export const canvasRebuildIndexLeaf = defineLeaf({
|
|
17
|
-
name: 'rebuild-index',
|
|
18
|
-
description: 're-derive node rows in canvas.db from on-disk nodes/<id>/meta.json',
|
|
19
|
-
whenToUse: 'canvas.db is missing or stale relative to the on-disk node metas and you need its node rows re-derived — most concretely after a remote/guest deployment\'s recreate-from-template, where node data survives on a durable Volume but canvas.db (local disk) was wiped, so a `node lifecycle revive` would otherwise find no row. Identity columns are rebuilt from each meta; runtime columns (status/intent/pi_pid/window/tmux) take their quiescent defaults, and subscribes_to edges are left intact',
|
|
20
|
-
help: {
|
|
21
|
-
name: 'canvas rebuild-index',
|
|
22
|
-
summary: 're-derive canvas.db node rows from on-disk metas; fails loud if metas exist but yield no rows',
|
|
23
|
-
params: [],
|
|
24
|
-
output: [
|
|
25
|
-
{ name: 'metas', type: 'integer', required: true, constraint: 'How many `nodes/<id>/meta.json` files were found on disk.' },
|
|
26
|
-
{ name: 'rows', type: 'integer', required: true, constraint: 'How many node rows exist in canvas.db after the rebuild.' },
|
|
27
|
-
],
|
|
28
|
-
outputKind: 'object',
|
|
29
|
-
effects: [
|
|
30
|
-
'Upserts a node row for every on-disk meta (identity columns only); runtime columns take schema defaults on freshly created rows.',
|
|
31
|
-
'Leaves subscribes_to edges intact; re-derives spawned_by provenance edges from each meta.',
|
|
32
|
-
'Throws (non-zero exit) if metas are present but the rebuild produced zero rows.',
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
run: async () => {
|
|
36
|
-
// The rebuild + the fail-loud “metas exist but 0 rows” guard run server-side
|
|
37
|
-
// (crtrd owns canvas.db and the on-disk metas under the same CRTR_HOME).
|
|
38
|
-
try {
|
|
39
|
-
const res = await cliClient().rebuildIndex();
|
|
40
|
-
return { metas: res.metas, rows: res.rows };
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
rethrowAsCliError(err);
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
});
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// Run with: node --import tsx/esm --test src/core/__tests__/human-cancel-guard.test.ts
|
|
2
|
-
//
|
|
3
|
-
// N2 — humanCancel on a ticket the store has already settled must short-circuit to
|
|
4
|
-
// {canceled:false, reason:'already_resolved'} rather than throwing. A second cancel
|
|
5
|
-
// is the ordinary race (the human submits while the agent retracts), so the client
|
|
6
|
-
// guard in queue.ts turns the daemon's 409 into an idempotent no-op.
|
|
7
|
-
import { test, before, after, beforeEach, afterEach } from 'node:test';
|
|
8
|
-
import assert from 'node:assert/strict';
|
|
9
|
-
import { mkdtempSync, mkdirSync, rmSync, existsSync } from 'node:fs';
|
|
10
|
-
import { tmpdir } from 'node:os';
|
|
11
|
-
import { join } from 'node:path';
|
|
12
|
-
import { createNode } from '../canvas/canvas.js';
|
|
13
|
-
import { closeDb } from '../canvas/db.js';
|
|
14
|
-
import { nodeDir } from '../canvas/paths.js';
|
|
15
|
-
import { atomicWriteJson, bindTicketReplyRoute, pageManifestPath } from '../human/convention.js';
|
|
16
|
-
import { cancelTicket, readTicketResult } from '../human/tickets.js';
|
|
17
|
-
import { humanCancel } from '../../commands/human/queue.js';
|
|
18
|
-
import { createApiServer } from '../../daemon/api/server.js';
|
|
19
|
-
import { apiSocketPath } from '../canvas/paths.js';
|
|
20
|
-
// `humanCancel` is a thin CLI forwarder since the crtrd-API re-plumb: its
|
|
21
|
-
// already-canceled short-circuit guard runs client-side after fetching the node
|
|
22
|
-
// through `cliClient().getNode`. Stand up a real in-process `createApiServer()`
|
|
23
|
-
// bound to the isolated CRTR_HOME's socket so that fetch resolves against the
|
|
24
|
-
// genuine daemon seam (never an autostarted subprocess, never a mock client).
|
|
25
|
-
let server;
|
|
26
|
-
async function waitForSocket(path) {
|
|
27
|
-
for (let i = 0; i < 200; i++) {
|
|
28
|
-
if (existsSync(path))
|
|
29
|
-
return;
|
|
30
|
-
await new Promise((r) => setTimeout(r, 25));
|
|
31
|
-
}
|
|
32
|
-
throw new Error(`api socket never bound at ${path}`);
|
|
33
|
-
}
|
|
34
|
-
let home;
|
|
35
|
-
function node(id) {
|
|
36
|
-
return {
|
|
37
|
-
node_id: id,
|
|
38
|
-
name: id,
|
|
39
|
-
created: new Date().toISOString(),
|
|
40
|
-
cwd: '/tmp/work',
|
|
41
|
-
kind: 'human',
|
|
42
|
-
mode: 'base',
|
|
43
|
-
lifecycle: 'terminal',
|
|
44
|
-
status: 'active',
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
/** Publish a reply-bearing page ticket in the bridge node's directory, exactly as
|
|
48
|
-
* `human send` does: reply route first, then the page manifest. */
|
|
49
|
-
function publishTicket(id, slots = []) {
|
|
50
|
-
const dir = nodeDir(id);
|
|
51
|
-
mkdirSync(dir, { recursive: true });
|
|
52
|
-
bindTicketReplyRoute(dir, id);
|
|
53
|
-
atomicWriteJson(pageManifestPath(dir), {
|
|
54
|
-
schema: 'crtr.page/v2',
|
|
55
|
-
dialect: 'jsx',
|
|
56
|
-
title: id,
|
|
57
|
-
subtitle: 'Acknowledge this ticket so the request can proceed.',
|
|
58
|
-
delivery: { placement: 'inline', inbox: true, reply: true },
|
|
59
|
-
document: 'page.tsx',
|
|
60
|
-
steps: 1,
|
|
61
|
-
slots,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
before(() => {
|
|
65
|
-
home = mkdtempSync(join(tmpdir(), 'crtr-humancancel-'));
|
|
66
|
-
process.env['CRTR_HOME'] = home;
|
|
67
|
-
});
|
|
68
|
-
beforeEach(async () => {
|
|
69
|
-
closeDb();
|
|
70
|
-
rmSync(home, { recursive: true, force: true });
|
|
71
|
-
mkdirSync(home, { recursive: true });
|
|
72
|
-
server = createApiServer();
|
|
73
|
-
await waitForSocket(apiSocketPath());
|
|
74
|
-
});
|
|
75
|
-
afterEach(async () => {
|
|
76
|
-
await server?.close();
|
|
77
|
-
});
|
|
78
|
-
after(() => {
|
|
79
|
-
closeDb();
|
|
80
|
-
rmSync(home, { recursive: true, force: true });
|
|
81
|
-
delete process.env['CRTR_HOME'];
|
|
82
|
-
});
|
|
83
|
-
test('cancel accepts newer page config and treats an already-canceled ticket as a no-op', async () => {
|
|
84
|
-
const newerId = 'newerPage';
|
|
85
|
-
createNode(node(newerId));
|
|
86
|
-
publishTicket(newerId, [{
|
|
87
|
-
id: 'decision',
|
|
88
|
-
kind: 'options',
|
|
89
|
-
step: 0,
|
|
90
|
-
config: {
|
|
91
|
-
label: 'Decision',
|
|
92
|
-
body: 'Choose one.',
|
|
93
|
-
options: [{ id: 'yes', label: 'Yes' }],
|
|
94
|
-
mode: 'single',
|
|
95
|
-
futureField: true,
|
|
96
|
-
},
|
|
97
|
-
}]);
|
|
98
|
-
const canceled = (await humanCancel.run({ ticket_id: newerId }));
|
|
99
|
-
assert.equal(canceled['canceled'], true);
|
|
100
|
-
assert.equal(canceled['ticket_id'], newerId);
|
|
101
|
-
assert.equal(readTicketResult(nodeDir(newerId))?.kind, 'canceled');
|
|
102
|
-
const settledId = 'canceledJob';
|
|
103
|
-
createNode(node(settledId));
|
|
104
|
-
publishTicket(settledId);
|
|
105
|
-
cancelTicket(nodeDir(settledId), { actor: 'human' });
|
|
106
|
-
const settled = (await humanCancel.run({ ticket_id: settledId }));
|
|
107
|
-
assert.equal(settled['canceled'], false);
|
|
108
|
-
assert.equal(settled['reason'], 'already_resolved');
|
|
109
|
-
assert.equal(settled['ticket_id'], settledId);
|
|
110
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|