@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
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { defineBranch, defineLeaf } from '../../core/command.js';
|
|
2
|
-
import { readConfig, updateConfig, persistModelLadders, configPath as coreConfigPath } from '../../core/config.js';
|
|
2
|
+
import { InvalidRawSettingsError, readConfig, readRawSettingsForTarget, replaceRawSettingsForTarget, updateConfig, persistModelLadders, configPath as coreConfigPath } from '../../core/config.js';
|
|
3
3
|
import { usage, notFound } from '../../core/errors.js';
|
|
4
|
-
import {
|
|
4
|
+
import { requireScopeRoot } from '../../core/scope.js';
|
|
5
5
|
import { resolveScope } from './shared.js';
|
|
6
|
+
import { resolveProfileOperand } from '../../core/profiles/manifest.js';
|
|
7
|
+
import { SettingsRevisionConflictError } from '../../core/scoped-state/settings.js';
|
|
8
|
+
import { InputError } from '../../core/io.js';
|
|
6
9
|
import { SCOPE_CONFIG_KEYS, USER_SETTINGS, findUserSetting } from '../../core/user-settings.js';
|
|
7
10
|
// Config helpers (ported from commands/config.ts)
|
|
8
11
|
const CONFIG_TOP_LEVEL_HELP = SCOPE_CONFIG_KEYS.join(', ');
|
|
@@ -90,6 +93,34 @@ function modelLadderPatch(key, rawValue) {
|
|
|
90
93
|
}
|
|
91
94
|
throw usage(`unsupported key path for set: ${key}`);
|
|
92
95
|
}
|
|
96
|
+
function rawSettingsTarget(input) {
|
|
97
|
+
const scope = input['scope'];
|
|
98
|
+
if (scope === 'project') {
|
|
99
|
+
throw usage('project settings remain a JSON file; use `crtr sys config set` or `crtr sys config path --scope project`.');
|
|
100
|
+
}
|
|
101
|
+
const profile = input['profile'];
|
|
102
|
+
if (scope === 'user') {
|
|
103
|
+
if (profile !== undefined)
|
|
104
|
+
throw usage('--profile is available only with --scope profile.');
|
|
105
|
+
return { scope: 'user' };
|
|
106
|
+
}
|
|
107
|
+
if (profile === undefined)
|
|
108
|
+
throw usage('--profile is required with --scope profile.');
|
|
109
|
+
return { scope: 'profile', profileId: resolveProfileOperand(profile).profileId };
|
|
110
|
+
}
|
|
111
|
+
function parseRawSettings(raw) {
|
|
112
|
+
let value;
|
|
113
|
+
try {
|
|
114
|
+
value = JSON.parse(raw);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
throw new InputError({ error: 'invalid_request', message: 'stdin must be valid JSON', field: 'stdin', next: 'Pipe one complete JSON object on stdin.' });
|
|
118
|
+
}
|
|
119
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
120
|
+
throw new InputError({ error: 'invalid_request', message: 'stdin must be a JSON object', field: 'stdin', next: 'Pipe one complete JSON object on stdin.' });
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
93
124
|
function setNestedValue(cfg, key, rawValue, value) {
|
|
94
125
|
const parts = key.split('.');
|
|
95
126
|
const topKey = parts[0];
|
|
@@ -193,7 +224,7 @@ const configSet = defineLeaf({
|
|
|
193
224
|
name: 'sys config set',
|
|
194
225
|
summary: 'write a config value by dotted key',
|
|
195
226
|
params: [
|
|
196
|
-
{ kind: 'positional', name: 'key', type: 'string', required: true, constraint: `Dotted key path. User-scope scalar settings: ${SCALAR_SETTING_HELP}. Also supported: working_gerunds and whip_messages (non-empty JSON string arrays), brokerThresholds.warning and brokerThresholds.automaticReviveCap (user scope; integer >= 1), lifecycle.unattendedParkMs (user scope; integer ms >= 1), modelLadders.defaultProvider, and modelLadders.<anthropic|openai>.<ultra|strong|medium|light>. Keybindings are edited only through sys settings.
|
|
227
|
+
{ kind: 'positional', name: 'key', type: 'string', required: true, constraint: `Dotted key path. User-scope scalar settings: ${SCALAR_SETTING_HELP}. Also supported: working_gerunds and whip_messages (non-empty JSON string arrays), brokerThresholds.warning and brokerThresholds.automaticReviveCap (user scope; integer >= 1), lifecycle.unattendedParkMs (user scope; integer ms >= 1), modelLadders.defaultProvider, and modelLadders.<anthropic|openai>.<ultra|strong|medium|light>. Keybindings are edited only through sys settings. For arbitrary raw user or profile documents, use sys config get-raw and set-raw.` },
|
|
197
228
|
{ kind: 'flag', name: 'value', type: 'string', required: true, constraint: 'value VALUE — string, required. working_gerunds and whip_messages accept JSON arrays; other values are stored as-is if quoted and coerced to number or boolean when unambiguous.' },
|
|
198
229
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Scope to write to. Default: user. Project scope is supported only for modelLadders.' },
|
|
199
230
|
],
|
|
@@ -202,7 +233,7 @@ const configSet = defineLeaf({
|
|
|
202
233
|
{ name: 'scope', type: 'string', required: true, constraint: 'Scope the value was written to.' },
|
|
203
234
|
],
|
|
204
235
|
outputKind: 'object',
|
|
205
|
-
effects: ['Writes the updated value
|
|
236
|
+
effects: ['Writes the updated value through the target scope’s configuration storage.'],
|
|
206
237
|
},
|
|
207
238
|
run: async (input) => {
|
|
208
239
|
const key = input['key'];
|
|
@@ -227,54 +258,96 @@ const configSet = defineLeaf({
|
|
|
227
258
|
return { value: written, scope };
|
|
228
259
|
},
|
|
229
260
|
});
|
|
261
|
+
const configGetRaw = defineLeaf({
|
|
262
|
+
name: 'get-raw',
|
|
263
|
+
description: 'read one raw SQL-backed settings document and revision',
|
|
264
|
+
whenToUse: 'you need the exact stored user or profile settings document before replacing it with set-raw.',
|
|
265
|
+
help: {
|
|
266
|
+
name: 'sys config get-raw',
|
|
267
|
+
summary: 'read one raw user or profile settings document',
|
|
268
|
+
params: [
|
|
269
|
+
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'profile', 'project'], required: true, constraint: 'SQL-backed target: user or profile. project is rejected because its settings remain a JSON file.' },
|
|
270
|
+
{ kind: 'flag', name: 'profile', type: 'string', required: false, constraint: 'Profile id or name to target. Required with --scope profile; rejected with --scope user or project.' },
|
|
271
|
+
],
|
|
272
|
+
output: [
|
|
273
|
+
{ name: 'revision', type: 'string', required: true, constraint: 'Opaque revision token for set-raw. absent means the settings row does not exist.' },
|
|
274
|
+
{ name: 'settings', type: 'object | null', required: true, constraint: 'Exact stored settings document, or null when no row exists.' },
|
|
275
|
+
],
|
|
276
|
+
outputKind: 'object',
|
|
277
|
+
effects: ['None. Read-only.'],
|
|
278
|
+
},
|
|
279
|
+
run: async (input) => readRawSettingsForTarget(rawSettingsTarget(input)),
|
|
280
|
+
});
|
|
281
|
+
const configSetRaw = defineLeaf({
|
|
282
|
+
name: 'set-raw',
|
|
283
|
+
description: 'replace one raw SQL-backed settings document at a revision',
|
|
284
|
+
whenToUse: 'you have a complete user or profile settings document from get-raw and must replace it without losing a concurrent change.',
|
|
285
|
+
help: {
|
|
286
|
+
name: 'sys config set-raw',
|
|
287
|
+
summary: 'atomically replace one raw user or profile settings document',
|
|
288
|
+
params: [
|
|
289
|
+
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'profile', 'project'], required: true, constraint: 'SQL-backed target: user or profile. project is rejected because its settings remain a JSON file.' },
|
|
290
|
+
{ kind: 'flag', name: 'profile', type: 'string', required: false, constraint: 'Profile id or name to target. Required with --scope profile; rejected with --scope user or project.' },
|
|
291
|
+
{ kind: 'flag', name: 'if-revision', type: 'string', required: true, constraint: 'Revision returned by get-raw. Required; use absent only when get-raw reported no settings row.' },
|
|
292
|
+
{ kind: 'stdin', name: 'settings', required: true, allowPositional: false, constraint: 'One complete JSON object. It replaces the document exactly; values are not normalized or merged.' },
|
|
293
|
+
],
|
|
294
|
+
output: [
|
|
295
|
+
{ name: 'revision', type: 'string', required: true, constraint: 'Revision token of the stored document after this operation.' },
|
|
296
|
+
{ name: 'changed', type: 'boolean', required: true, constraint: 'Whether the stored document changed.' },
|
|
297
|
+
],
|
|
298
|
+
outputKind: 'object',
|
|
299
|
+
effects: ['Atomically replaces the SQL-backed settings document only when --if-revision matches its current revision.'],
|
|
300
|
+
},
|
|
301
|
+
run: async (input) => {
|
|
302
|
+
const target = rawSettingsTarget(input);
|
|
303
|
+
const settings = parseRawSettings(input['settings']);
|
|
304
|
+
try {
|
|
305
|
+
return replaceRawSettingsForTarget(target, settings, input['ifRevision']);
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
if (error instanceof SettingsRevisionConflictError) {
|
|
309
|
+
throw new InputError({ error: 'settings_revision_conflict', message: 'settings changed since the supplied revision', field: 'if_revision', next: 'Run `crtr sys config get-raw` again, reapply the intended transformation, and retry with its revision.' });
|
|
310
|
+
}
|
|
311
|
+
if (error instanceof InvalidRawSettingsError) {
|
|
312
|
+
throw new InputError({ error: 'invalid_settings', message: error.message, field: 'stdin', next: 'Correct the document so crouter can merge it into resolved settings, then retry with a fresh revision.' });
|
|
313
|
+
}
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
});
|
|
230
318
|
const configPath = defineLeaf({
|
|
231
319
|
name: 'path',
|
|
232
|
-
description: 'print
|
|
233
|
-
whenToUse: 'you need the
|
|
320
|
+
description: 'print the project config.json path',
|
|
321
|
+
whenToUse: 'you need the project config.json path for inspection or backup. User and profile settings use get-raw and set-raw instead.',
|
|
234
322
|
help: {
|
|
235
323
|
name: 'sys config path',
|
|
236
|
-
summary: 'print
|
|
324
|
+
summary: 'print the project config.json path',
|
|
237
325
|
params: [
|
|
238
|
-
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['
|
|
326
|
+
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['project', 'user', 'profile'], required: false, constraint: 'Project is the only path-backed settings scope. user and profile are rejected because they use SQL-backed get-raw and set-raw. Default: project.' },
|
|
239
327
|
],
|
|
240
328
|
output: [
|
|
241
|
-
{ name: 'paths', type: 'object[]', required: true, constraint: '
|
|
329
|
+
{ name: 'paths', type: 'object[]', required: true, constraint: 'One {scope: "project", path} entry when the current project has a config file; otherwise empty.' },
|
|
242
330
|
],
|
|
243
331
|
outputKind: 'object',
|
|
244
332
|
effects: ['None. Read-only.'],
|
|
245
333
|
},
|
|
246
334
|
run: async (input) => {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (scopeArg === undefined || scopeArg === 'all') {
|
|
251
|
-
scopes = listScopes(undefined);
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
scopes = listScopes(scopeArg);
|
|
335
|
+
const scope = input['scope'];
|
|
336
|
+
if (scope === 'user' || scope === 'profile') {
|
|
337
|
+
throw usage(`${scope} settings are SQL-backed; use \`crtr sys config get-raw --scope ${scope}\` instead.`);
|
|
255
338
|
}
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
const root = scopeRoot(s);
|
|
259
|
-
if (!root)
|
|
260
|
-
return null;
|
|
261
|
-
const p = coreConfigPath(s);
|
|
262
|
-
if (!p)
|
|
263
|
-
return null;
|
|
264
|
-
return { scope: s, path: p };
|
|
265
|
-
})
|
|
266
|
-
.filter((x) => x !== null);
|
|
267
|
-
return { paths };
|
|
339
|
+
const path = coreConfigPath('project');
|
|
340
|
+
return { paths: path === null ? [] : [{ scope: 'project', path }] };
|
|
268
341
|
},
|
|
269
342
|
});
|
|
270
343
|
export const configBranch = defineBranch({
|
|
271
344
|
name: 'config',
|
|
272
345
|
description: 'read and write configuration',
|
|
273
|
-
whenToUse: 'inspecting crtr settings, changing supported scalar values, or locating config.json. Keybinding changes belong in sys settings.',
|
|
346
|
+
whenToUse: 'inspecting crtr settings, changing supported scalar values, replacing complete raw user or profile settings documents, or locating a project config.json. Keybinding changes belong in sys settings.',
|
|
274
347
|
help: {
|
|
275
348
|
name: 'sys config',
|
|
276
|
-
summary: 'read and write crtr configuration, including model ladders
|
|
277
|
-
model: '
|
|
349
|
+
summary: 'read and write crtr configuration, including model ladders and raw SQL-backed user/profile settings',
|
|
350
|
+
model: 'get and set resolve individual settings. get-raw and set-raw read and replace complete user or profile documents with a revision precondition. path applies only to project config.json.',
|
|
278
351
|
},
|
|
279
|
-
children: [configGet, configSet, configPath],
|
|
352
|
+
children: [configGet, configSet, configGetRaw, configSetRaw, configPath],
|
|
280
353
|
});
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
// This subtree starts, checks, and stops the daemon process.
|
|
9
9
|
import { defineLeaf, defineBranch } from '../../core/command.js';
|
|
10
10
|
import { InputError } from '../../core/io.js';
|
|
11
|
-
import {
|
|
11
|
+
import { parseDurationMs } from '../../core/wake.js';
|
|
12
|
+
import { DaemonNotPreparedError, probeDaemonHealth, spawnDaemon, stopDaemonProcess, sweepStrayDaemons } from '../../daemon/manage.js';
|
|
12
13
|
import { isDaemonRunning, readPidfile, isPidAlive } from '../../daemon/pidfile.js';
|
|
13
14
|
import { cliClient } from '../api-client.js';
|
|
15
|
+
import { CrtrClient } from '../../api/index.js';
|
|
16
|
+
import { defineSysBranch } from './branch.js';
|
|
14
17
|
// daemon start
|
|
15
18
|
const daemonStart = defineLeaf({
|
|
16
19
|
name: 'start',
|
|
@@ -19,7 +22,9 @@ const daemonStart = defineLeaf({
|
|
|
19
22
|
help: {
|
|
20
23
|
name: 'sys daemon start',
|
|
21
24
|
summary: 'start the crtrd supervisor daemon in the background (no-op only if its Unix API socket serves)',
|
|
22
|
-
params: [
|
|
25
|
+
params: [
|
|
26
|
+
{ kind: 'flag', name: 'prepare', type: 'bool', required: false, constraint: 'Hold normal daemon work after storage preparation until `sys daemon admit`; omit for ordinary startup.' },
|
|
27
|
+
],
|
|
23
28
|
output: [
|
|
24
29
|
{ name: 'started', type: 'boolean', required: true, constraint: 'True when a new daemon process was spawned; false when one was already running.' },
|
|
25
30
|
{ name: 'pid', type: 'number', required: false, constraint: 'PID of the newly spawned daemon.' },
|
|
@@ -27,6 +32,7 @@ const daemonStart = defineLeaf({
|
|
|
27
32
|
{ name: 'running', type: 'boolean', required: false, constraint: 'True only when a live pidfile owner does not serve its Unix API socket.' },
|
|
28
33
|
{ name: 'serving', type: 'boolean', required: false, constraint: 'False only when a live pidfile owner does not answer /healthz.' },
|
|
29
34
|
{ name: 'probe_error', type: 'string', required: false, constraint: 'The final /healthz probe failure when a live owner missed readiness.' },
|
|
35
|
+
{ name: 'startup_phase', type: 'string', required: false, constraint: 'The observed daemon phase when it was reachable.' },
|
|
30
36
|
],
|
|
31
37
|
outputKind: 'object',
|
|
32
38
|
effects: [
|
|
@@ -34,9 +40,116 @@ const daemonStart = defineLeaf({
|
|
|
34
40
|
'Writes a pidfile at CRTR_PIDFILE if set, otherwise crtrHome()/crtrd.pid.'
|
|
35
41
|
],
|
|
36
42
|
},
|
|
43
|
+
run: async (input) => {
|
|
44
|
+
try {
|
|
45
|
+
const result = await spawnDaemon({ targetPhase: input.prepare === true ? 'prepared' : 'ready' });
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof DaemonNotPreparedError) {
|
|
50
|
+
throw new InputError({
|
|
51
|
+
error: 'daemon_not_prepared',
|
|
52
|
+
message: error.message,
|
|
53
|
+
next: 'Stop the live daemon, then start a new one with `crtr sys daemon start --prepare` before setup.',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
// daemon await / admit
|
|
61
|
+
const DAEMON_AWAIT_POLL_MS = 100;
|
|
62
|
+
async function awaitDaemonPhase(phase, timeoutMs) {
|
|
63
|
+
const startedAt = Date.now();
|
|
64
|
+
const deadline = startedAt + timeoutMs;
|
|
65
|
+
let lastPhase = 'initializing';
|
|
66
|
+
let lastObservation = 'the daemon socket was not reachable';
|
|
67
|
+
while (Date.now() < deadline) {
|
|
68
|
+
try {
|
|
69
|
+
const health = await probeDaemonHealth(Math.min(1_000, Math.max(1, deadline - Date.now())));
|
|
70
|
+
lastPhase = health.startup_phase;
|
|
71
|
+
lastObservation = health.startup_blocked ?? `daemon is ${health.startup_phase}`;
|
|
72
|
+
if (health.startup_phase === 'blocked') {
|
|
73
|
+
throw new InputError({
|
|
74
|
+
error: 'startup_blocked',
|
|
75
|
+
message: health.startup_blocked ?? 'daemon startup is blocked',
|
|
76
|
+
received: health.startup_phase,
|
|
77
|
+
field: 'phase',
|
|
78
|
+
next: 'Repair the reported blocker paths with `crtr sys migrate`, then retry the await.',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (health.startup_phase === phase)
|
|
82
|
+
return { startup_phase: phase, waited_ms: Date.now() - startedAt };
|
|
83
|
+
if (phase === 'prepared' && health.startup_phase === 'ready') {
|
|
84
|
+
throw new InputError({
|
|
85
|
+
error: 'await_missed_phase',
|
|
86
|
+
message: 'daemon is already ready and cannot return to prepared in this process',
|
|
87
|
+
received: health.startup_phase,
|
|
88
|
+
field: 'phase',
|
|
89
|
+
next: 'Start a new daemon with `crtr sys daemon start --prepare` before awaiting prepared.',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (error instanceof InputError)
|
|
95
|
+
throw error;
|
|
96
|
+
lastObservation = error instanceof Error ? error.message : String(error);
|
|
97
|
+
}
|
|
98
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(DAEMON_AWAIT_POLL_MS, Math.max(0, deadline - Date.now()))));
|
|
99
|
+
}
|
|
100
|
+
throw new InputError({
|
|
101
|
+
error: 'await_timeout',
|
|
102
|
+
message: `daemon did not reach ${phase} within ${timeoutMs}ms (last phase: ${lastPhase}; last observation: ${lastObservation})`,
|
|
103
|
+
received: lastPhase,
|
|
104
|
+
field: 'phase',
|
|
105
|
+
next: 'Inspect `crtr sys daemon status` and resolve any reported startup blocker before retrying.',
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const daemonAwait = defineLeaf({
|
|
109
|
+
name: 'await',
|
|
110
|
+
description: 'wait for a daemon startup phase',
|
|
111
|
+
whenToUse: 'a caller started or was given a daemon that must reach prepared or ready before its next step.',
|
|
112
|
+
help: {
|
|
113
|
+
name: 'sys daemon await',
|
|
114
|
+
summary: 'wait for the running daemon to report one startup phase',
|
|
115
|
+
params: [
|
|
116
|
+
{ kind: 'flag', name: 'phase', type: 'enum', choices: ['prepared', 'ready'], required: true, constraint: 'The phase that permits the caller’s next step.' },
|
|
117
|
+
{ kind: 'flag', name: 'timeout', type: 'string', required: false, default: '5m', constraint: 'Maximum wait as a positive duration such as 90s, 5m, or 1h30m.' },
|
|
118
|
+
],
|
|
119
|
+
output: [
|
|
120
|
+
{ name: 'startup_phase', type: 'string', required: true, constraint: 'The requested phase.' },
|
|
121
|
+
{ name: 'waited_ms', type: 'number', required: true, constraint: 'Elapsed wall-clock time before the phase was observed.' },
|
|
122
|
+
],
|
|
123
|
+
outputKind: 'object',
|
|
124
|
+
effects: ['Read-only: polls /healthz until the requested phase is observed or the caller-bounded timeout expires.'],
|
|
125
|
+
},
|
|
126
|
+
run: async (input) => {
|
|
127
|
+
const rawTimeout = input.timeout;
|
|
128
|
+
const timeoutMs = parseDurationMs(rawTimeout);
|
|
129
|
+
if (timeoutMs === null || timeoutMs <= 0) {
|
|
130
|
+
throw new InputError({ error: 'invalid_duration', message: `not a positive duration: ${rawTimeout}`, received: rawTimeout, field: 'timeout', next: 'Use a positive duration such as 90s, 5m, or 1h30m.' });
|
|
131
|
+
}
|
|
132
|
+
return awaitDaemonPhase(input.phase, timeoutMs);
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const daemonAdmit = defineLeaf({
|
|
136
|
+
name: 'admit',
|
|
137
|
+
description: 'admit normal work after daemon preparation',
|
|
138
|
+
whenToUse: 'the caller has completed its setup against a prepared daemon and is ready for normal daemon work to start.',
|
|
139
|
+
help: {
|
|
140
|
+
name: 'sys daemon admit',
|
|
141
|
+
summary: 'ask a prepared daemon to start normal services',
|
|
142
|
+
params: [],
|
|
143
|
+
output: [
|
|
144
|
+
{ name: 'admitted', type: 'boolean', required: true, constraint: 'True only when this request began admission.' },
|
|
145
|
+
{ name: 'already_admitted', type: 'boolean', required: true, constraint: 'True when admission had already begun or completed.' },
|
|
146
|
+
{ name: 'startup_phase', type: 'string', required: true, constraint: 'The phase after admission settles.' },
|
|
147
|
+
],
|
|
148
|
+
outputKind: 'object',
|
|
149
|
+
effects: ['Starts normal daemon services when the daemon is prepared.'],
|
|
150
|
+
},
|
|
37
151
|
run: async (_input) => {
|
|
38
|
-
|
|
39
|
-
return result;
|
|
152
|
+
return await CrtrClient.forLocalSocket({ autostart: false }).admitDaemon();
|
|
40
153
|
},
|
|
41
154
|
});
|
|
42
155
|
// daemon status
|
|
@@ -53,6 +166,7 @@ const daemonStatus = defineLeaf({
|
|
|
53
166
|
{ name: 'serving', type: 'boolean', required: false, constraint: 'True when the live daemon answers /healthz; false when one probe does not.' },
|
|
54
167
|
{ name: 'pid', type: 'number', required: false, constraint: 'PID of the running daemon.' },
|
|
55
168
|
{ name: 'probe_error', type: 'string', required: false, constraint: 'The failed /healthz observation when the live owner did not answer.' },
|
|
169
|
+
{ name: 'startup_phase', type: 'string', required: false, constraint: 'The observed daemon startup phase when the socket answered.' },
|
|
56
170
|
],
|
|
57
171
|
outputKind: 'object',
|
|
58
172
|
effects: ['Read-only: reads the pidfile, probes the pid, and requests /healthz without autostart.'],
|
|
@@ -63,8 +177,13 @@ const daemonStatus = defineLeaf({
|
|
|
63
177
|
if (!running)
|
|
64
178
|
return { running: false };
|
|
65
179
|
try {
|
|
66
|
-
await
|
|
67
|
-
return {
|
|
180
|
+
const health = await probeDaemonHealth();
|
|
181
|
+
return {
|
|
182
|
+
running: true,
|
|
183
|
+
serving: health.ok,
|
|
184
|
+
pid,
|
|
185
|
+
...(health.startup_phase === undefined ? {} : { startup_phase: health.startup_phase }),
|
|
186
|
+
};
|
|
68
187
|
}
|
|
69
188
|
catch (error) {
|
|
70
189
|
return { running: true, serving: false, pid, probe_error: error.message };
|
|
@@ -186,5 +305,9 @@ export const daemonBranch = defineBranch({
|
|
|
186
305
|
summary: 'manage the crtrd canvas supervisor daemon',
|
|
187
306
|
model: 'crtrd is a thin background daemon that polls active+idle nodes and acts on window exit: crashed windows become dead; refresh-yield windows get a fresh respawn. It holds no orchestration logic — just process supervision. These are operator/dev self-management, not something a normal agent turn needs to check. Picking up a newly installed runtime generation is `restart` (a handover the daemon performs on itself); `stop` is the terminal one, and it kills the caller along with the rest of the fleet.',
|
|
188
307
|
},
|
|
189
|
-
children: [daemonStart, daemonRestart, daemonStatus, daemonStop],
|
|
308
|
+
children: [daemonStart, daemonAwait, daemonAdmit, daemonRestart, daemonStatus, daemonStop],
|
|
190
309
|
});
|
|
310
|
+
/** The daemon-only `sys` subtree used before scoped user state is available. */
|
|
311
|
+
export function registerDaemonControlSys() {
|
|
312
|
+
return defineSysBranch([daemonBranch]);
|
|
313
|
+
}
|
|
@@ -8,9 +8,7 @@ import { scopeRoot, listScopes, marketplacesDir, pluginsDir } from '../../core/s
|
|
|
8
8
|
import { readMarketplaceManifest, readPluginManifest } from '../../core/manifest.js';
|
|
9
9
|
import { pathExists, listDirs, removePath } from '../../core/fs-utils.js';
|
|
10
10
|
import { lsRemote } from '../../core/git.js';
|
|
11
|
-
import { isPidAlive } from '../../core/canvas/pid.js';
|
|
12
11
|
import { cliClient } from '../api-client.js';
|
|
13
|
-
import { readFault } from '../../core/runtime/fault.js';
|
|
14
12
|
import { detectNerdFont, nerdFontInstallCommand, NERD_FONT_SELECT_HINT } from '../../core/runtime/nerd-font.js';
|
|
15
13
|
import { detectPackageManager } from './setup-core.js';
|
|
16
14
|
import { validateEffectiveCommandPlugins } from '../../core/command-plugins/discovery.js';
|
|
@@ -406,22 +404,14 @@ async function generationChecks(label, lookup, allowAbsent) {
|
|
|
406
404
|
}
|
|
407
405
|
return results;
|
|
408
406
|
}
|
|
409
|
-
/**
|
|
410
|
-
* daemon
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
* `core/canvas/canvas.ts` — which a pure-client CLI leaf must not pull in. */
|
|
414
|
-
function activeFaultForDisplay(node, fault) {
|
|
415
|
-
if (fault === null)
|
|
416
|
-
return null;
|
|
417
|
-
if (fault.link === 'pi→provider' && fault.retry.by === 'daemon' && fault.retry.disposition === 'auto' && !isPidAlive(node.pi_pid))
|
|
418
|
-
return null;
|
|
419
|
-
return fault;
|
|
420
|
-
}
|
|
407
|
+
/** One failing check per node parked on an active fault. The fault is the
|
|
408
|
+
* daemon's projection on the node summary — the stale-provider overlay (a
|
|
409
|
+
* daemon-owned auto retry whose broker pid is gone) is already applied there,
|
|
410
|
+
* so this leaf needs no local read. */
|
|
421
411
|
async function runFaultChecks() {
|
|
422
412
|
const results = [];
|
|
423
413
|
for (const node of await cliClient().listNodes()) {
|
|
424
|
-
const fault =
|
|
414
|
+
const fault = node.fault ?? null;
|
|
425
415
|
if (fault === null)
|
|
426
416
|
continue;
|
|
427
417
|
const name = `fault:${node.node_id}:${fault.link}`;
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Journaled canvas-db migrations remain in the database's ordered chain.
|
|
3
3
|
import { defineLeaf } from '../../core/command.js';
|
|
4
4
|
import { general, usage } from '../../core/errors.js';
|
|
5
|
+
import { resolve } from 'node:path';
|
|
5
6
|
import { pathExists } from '../../core/fs-utils.js';
|
|
6
|
-
import {
|
|
7
|
+
import { cliClient, rethrowAsCliError } from '../api-client.js';
|
|
7
8
|
export const sysMigrateLeaf = defineLeaf({
|
|
8
9
|
name: 'migrate',
|
|
9
10
|
description: 'converge every profile manifest and writable memory store to the current on-disk format',
|
|
@@ -26,16 +27,17 @@ export const sysMigrateLeaf = defineLeaf({
|
|
|
26
27
|
{ name: 'discovery_roots', type: 'object[]', required: true, constraint: 'The frontier searched: {reason, root, boundary, detail?}. reason is user, profile, profile-project, cwd-ancestor, descendant, node, plugin, builtin, or explicit-dir; boundary is store, ancestors, descendants, plugins, or nodes.' },
|
|
27
28
|
{ name: 'discovered_stores', type: 'object[]', required: true, constraint: 'One row per physical store: {store, scope, namespace, mount_status, writable, reasons, targets, docs}. reasons holds every way the store was reached; targets the target ids that mount it; docs its parseable document count.' },
|
|
28
29
|
{ name: 'discovered_targets', type: 'object[]', required: true, constraint: 'One row per resolution view: {id, kind, origin, cwd, profile_id, node_id, stores}. stores lists store keys in that target\'s precedence order.' },
|
|
29
|
-
{ name: 'node_metadata', type: 'object', required: true, constraint: '{available, nodes, error?} — whether cwd/profile metadata was readable from every durable meta.json whose node store holds documents. Missing or corrupt metadata blocks corpus writes.' },
|
|
30
30
|
{ name: 'repository_namespaces', type: 'object[]', required: true, constraint: 'Repository-root namespace decisions this run makes: {repository_root, repository_key, declaration_path, namespace, source, action}. A nested store inherits this declaration; its reported effective prefix is not a declaration.' },
|
|
31
31
|
{ name: 'store_prefixes', type: 'object[]', required: true, constraint: 'Effective prefix facts for each project store: {store_root, owner_dir, repository_root, owner_relative_path, old_prefix, old_rule, effective_prefix, nested_declaration_action, front_door_action}. A nonempty owner_relative_path always reports front_door_action `none`; a nested effective_prefix is derived, not a declaration.' },
|
|
32
32
|
{ name: 'renames', type: 'object[]', required: true, constraint: 'Canonical identity changes: {store_root, path, from, to}.' },
|
|
33
33
|
{ name: 'references', type: 'object[]', required: true, constraint: 'Rewritten pointers at a changed identity: {store_root, path, kind, from, to}, kind link or memory-read.' },
|
|
34
34
|
{ name: 'dryRun', type: 'boolean', required: true, constraint: 'True when nothing was written (preview only).' },
|
|
35
|
+
{ name: 'resumed', type: 'boolean', required: true, constraint: 'True only when this repair resumed the blocked daemon startup.' },
|
|
36
|
+
{ name: 'resume_error', type: 'string', required: false, constraint: 'Present when corpus repair succeeded but normal daemon startup then failed.' },
|
|
35
37
|
],
|
|
36
38
|
outputKind: 'object',
|
|
37
39
|
effects: [
|
|
38
|
-
'Rewrites old-format `profile.json` manifests in place (atomic, under the same per-profile lock `profile project add/remove` take). A manifest whose structure cannot be converted fails the whole run — no project setting is ever guessed.',
|
|
40
|
+
'The daemon that owns this canvas runs the migration. Rewrites old-format `profile.json` manifests in place (atomic, under the same per-profile lock `profile project add/remove` take). A manifest whose structure cannot be converted fails the whole run — no project setting is ever guessed.',
|
|
39
41
|
'Rewrites old-format memory documents in place (atomic per-file writes) across every writable discovered store: profiles, profile-owned projects, this directory\'s ancestors, nested descendant stores, installed plugin stores, and node stores. Builtin docs are package-owned and never touched.',
|
|
40
42
|
'Applies corpus-wide identity changes in two ordered phases across every writable store, after the global plan comes back blocker-free; a post-write pass re-reads the corpus from disk and verifies it.',
|
|
41
43
|
'Under --dry-run: read-only, writes nothing.',
|
|
@@ -43,7 +45,7 @@ export const sysMigrateLeaf = defineLeaf({
|
|
|
43
45
|
},
|
|
44
46
|
run: async (input) => {
|
|
45
47
|
const dryRun = input.dryRun === true;
|
|
46
|
-
const explicitDirs = input['dir'] ?? [];
|
|
48
|
+
const explicitDirs = (input['dir'] ?? []).map((dir) => resolve(dir));
|
|
47
49
|
const missingDirs = explicitDirs.filter((dir) => !pathExists(dir));
|
|
48
50
|
if (missingDirs.length > 0) {
|
|
49
51
|
throw usage(`--dir path does not exist: ${missingDirs.join(', ')}`, {
|
|
@@ -52,91 +54,18 @@ export const sysMigrateLeaf = defineLeaf({
|
|
|
52
54
|
next: 'Pass the project directory that contains `.crouter/`, or omit --dir to migrate the discovered frontier only.',
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// stays as inspectable as a successful one, and the failure payload adds only
|
|
68
|
-
// the phase and the write inventory that a success cannot have.
|
|
69
|
-
const report = {
|
|
70
|
-
profiles: result.profiles,
|
|
71
|
-
stores: discovery.stores.length,
|
|
72
|
-
changed,
|
|
73
|
-
applied,
|
|
74
|
-
skipped,
|
|
75
|
-
blockers,
|
|
76
|
-
discovery_roots: discovery.roots.map((row) => ({
|
|
77
|
-
reason: row.reason,
|
|
78
|
-
root: row.root,
|
|
79
|
-
boundary: row.boundary,
|
|
80
|
-
...(row.detail === undefined ? {} : { detail: row.detail }),
|
|
81
|
-
})),
|
|
82
|
-
discovered_stores: discovery.stores.map((store) => ({
|
|
83
|
-
store: store.key,
|
|
84
|
-
scope: store.descriptor.scope,
|
|
85
|
-
namespace: store.descriptor.namespace,
|
|
86
|
-
mount_status: store.descriptor.mountStatus,
|
|
87
|
-
writable: store.writable,
|
|
88
|
-
reasons: [...new Set(store.discovery.map((row) => row.reason))],
|
|
89
|
-
targets: store.targets,
|
|
90
|
-
docs: snapshots.get(store.key)?.docs.length ?? 0,
|
|
91
|
-
})),
|
|
92
|
-
discovered_targets: discovery.targets.map((target) => ({
|
|
93
|
-
id: target.id,
|
|
94
|
-
kind: target.kind,
|
|
95
|
-
origin: target.origin,
|
|
96
|
-
cwd: target.target.cwd,
|
|
97
|
-
profile_id: target.target.profileId,
|
|
98
|
-
node_id: target.target.nodeId,
|
|
99
|
-
stores: target.storeKeys,
|
|
100
|
-
})),
|
|
101
|
-
node_metadata: discovery.nodeMetadata,
|
|
102
|
-
repository_namespaces: result.repositories.map((row) => ({
|
|
103
|
-
repository_root: row.repositoryRoot,
|
|
104
|
-
repository_key: row.repositoryKey,
|
|
105
|
-
declaration_path: row.declarationPath,
|
|
106
|
-
namespace: row.namespace,
|
|
107
|
-
source: row.source,
|
|
108
|
-
action: row.action,
|
|
109
|
-
})),
|
|
110
|
-
store_prefixes: result.storePrefixes.map((row) => ({
|
|
111
|
-
store_root: row.storeRoot,
|
|
112
|
-
owner_dir: row.ownerDir,
|
|
113
|
-
repository_root: row.repositoryRoot,
|
|
114
|
-
owner_relative_path: row.ownerRelativePath,
|
|
115
|
-
old_prefix: row.oldPrefix,
|
|
116
|
-
old_rule: row.oldRule,
|
|
117
|
-
effective_prefix: row.effectivePrefix,
|
|
118
|
-
nested_declaration_action: row.nestedDeclarationAction,
|
|
119
|
-
front_door_action: row.frontDoorAction,
|
|
120
|
-
})),
|
|
121
|
-
renames: result.renames.map((row) => ({ store_root: row.storeRoot, path: row.path, from: row.from, to: row.to })),
|
|
122
|
-
references: result.references.map((row) => ({
|
|
123
|
-
store_root: row.storeRoot,
|
|
124
|
-
path: row.path,
|
|
125
|
-
kind: row.kind,
|
|
126
|
-
from: row.from,
|
|
127
|
-
to: row.to,
|
|
128
|
-
})),
|
|
129
|
-
dryRun,
|
|
130
|
-
};
|
|
131
|
-
if (result.blocked) {
|
|
132
|
-
const earlier = applied.filter((row) => row.lane !== 'corpus').flatMap((row) => row.files);
|
|
133
|
-
const corpusPhase = result.corpusPhase;
|
|
134
|
-
const wrote = {
|
|
135
|
-
profile_manifests: result.wrote.profileManifests,
|
|
136
|
-
documents: result.wrote.documents,
|
|
137
|
-
corpus_consumers: result.wrote.corpusConsumers,
|
|
138
|
-
corpus_identities: result.wrote.corpusIdentities,
|
|
139
|
-
};
|
|
57
|
+
let report;
|
|
58
|
+
try {
|
|
59
|
+
report = await cliClient().migrateState({ dry_run: dryRun, dirs: explicitDirs });
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
rethrowAsCliError(error);
|
|
63
|
+
}
|
|
64
|
+
if (report.blocked) {
|
|
65
|
+
const blockers = report.blockers;
|
|
66
|
+
const earlier = report.applied.filter((row) => row.lane !== 'corpus').flatMap((row) => row.files);
|
|
67
|
+
const corpusPhase = report.corpus_phase;
|
|
68
|
+
const wrote = report.wrote;
|
|
140
69
|
const wroteSummary = dryRun
|
|
141
70
|
? '— this was a --dry-run; nothing was written'
|
|
142
71
|
: corpusPhase === 'written'
|
|
@@ -145,7 +74,7 @@ export const sysMigrateLeaf = defineLeaf({
|
|
|
145
74
|
? `before any corpus write — the corpus is unchanged, but ${earlier.length} earlier manifest/document rewrite(s) are already on disk`
|
|
146
75
|
: '— nothing was written';
|
|
147
76
|
throw general(`corpus migration ${corpusPhase === 'written' ? 'verification failed with' : 'blocked by'} ${blockers.length} finding(s) ${wroteSummary}`, {
|
|
148
|
-
received:
|
|
77
|
+
received: report,
|
|
149
78
|
next: corpusPhase === 'written'
|
|
150
79
|
? 'Resolve every verification finding against the files listed in received.wrote.corpus_identities and .corpus_consumers, then re-run `crtr sys migrate` — the lane converges from file truth.'
|
|
151
80
|
: 'Resolve every blocker, then re-run `crtr sys migrate` — the earlier lanes are convergent and re-running them is a no-op.',
|
|
@@ -153,9 +82,9 @@ export const sysMigrateLeaf = defineLeaf({
|
|
|
153
82
|
}
|
|
154
83
|
return {
|
|
155
84
|
...report,
|
|
156
|
-
follow_up: skipped.length > 0
|
|
85
|
+
follow_up: report.skipped.length > 0
|
|
157
86
|
? 'Some files could not be parsed and were left untouched — fix each named file, then re-run `crtr sys migrate`.'
|
|
158
|
-
: changed === 0
|
|
87
|
+
: report.changed === 0
|
|
159
88
|
? 'State already current — nothing to rewrite.'
|
|
160
89
|
: dryRun
|
|
161
90
|
? 'Preview only — re-run without --dry-run to write these changes.'
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ModelRegistry, ModelRuntime } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { piAgentDir } from '../../core/runtime/package-health.js';
|
|
4
4
|
import { PoolCredentialStore } from '../../core/pool-credential-store.js';
|
|
5
|
+
import { initializeFreshScopedStore } from '../../core/scoped-state/migrate.js';
|
|
5
6
|
import { runTuiPage, } from '../../core/tui/page-host.js';
|
|
6
7
|
export async function runSetupSettingsProcess(createSurface, interceptCancel) {
|
|
7
|
-
const agentDir =
|
|
8
|
+
const agentDir = piAgentDir();
|
|
9
|
+
initializeFreshScopedStore({ kind: 'provider', root: agentDir });
|
|
8
10
|
const runtime = await ModelRuntime.create({
|
|
9
11
|
credentials: new PoolCredentialStore(join(agentDir, "auth.json")),
|
|
10
12
|
modelsPath: join(agentDir, "models.json"),
|
package/dist/commands/sys.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// `crtr sys` subtree: configuration, diagnostics, and self-management.
|
|
2
|
-
import {
|
|
2
|
+
import { defineSysBranch } from './sys/branch.js';
|
|
3
3
|
import { configBranch } from './sys/config.js';
|
|
4
4
|
import { daemonBranch } from './sys/daemon.js';
|
|
5
5
|
import { sysDoctorLeaf } from './sys/doctor.js';
|
|
@@ -14,18 +14,5 @@ import { sysSyncBranch } from './sys/sync.js';
|
|
|
14
14
|
import { sysMigrateLeaf } from './sys/migrate.js';
|
|
15
15
|
import { sysUpdateLeaf, sysVersionLeaf } from './sys/update.js';
|
|
16
16
|
export function registerSys() {
|
|
17
|
-
return
|
|
18
|
-
name: 'sys',
|
|
19
|
-
rootEntry: {
|
|
20
|
-
concept: 'crtr configuration, diagnostics, and self-management',
|
|
21
|
-
desc: 'settings, config, setup, doctor, context, sync, migrate, update, version, feedback, logs, support, daemon',
|
|
22
|
-
useWhen: 'managing the crtr installation, inspecting diagnostics, or operating the crtrd supervisor process',
|
|
23
|
-
},
|
|
24
|
-
help: {
|
|
25
|
-
name: 'sys',
|
|
26
|
-
summary: 'crtr system configuration, settings, diagnostics, and self-management',
|
|
27
|
-
model: 'Configuration and settings own durable behavior; diagnostics and support observe it. Setup, migration, sync, and update change installed or generated state, while daemon control owns the supervisor lifecycle.',
|
|
28
|
-
},
|
|
29
|
-
children: [sysSettingsLeaf, configBranch, sysSetupLeaf, sysDoctorLeaf, contextBranch, sysFeedbackLeaf, sysLogsLeaf, sysWorktreesLeaf, supportBranch, sysUpdateLeaf, sysVersionLeaf, sysMigrateLeaf, sysSyncBranch, daemonBranch],
|
|
30
|
-
});
|
|
17
|
+
return defineSysBranch([sysSettingsLeaf, configBranch, sysSetupLeaf, sysDoctorLeaf, contextBranch, sysFeedbackLeaf, sysLogsLeaf, sysWorktreesLeaf, supportBranch, sysUpdateLeaf, sysVersionLeaf, sysMigrateLeaf, sysSyncBranch, daemonBranch]);
|
|
31
18
|
}
|