@north-light/crouter 0.3.312 → 0.3.313
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +27 -30
- package/dist/api/client.js +80 -67
- package/dist/api/dto/broker-ops.d.ts +10 -20
- package/dist/api/dto/canvas.d.ts +1 -10
- package/dist/api/dto/health.d.ts +113 -0
- package/dist/api/dto/human-requests.d.ts +14 -3
- package/dist/api/dto/human.d.ts +2 -48
- package/dist/api/dto/human.js +3 -2
- package/dist/api/dto/inbox.d.ts +14 -0
- package/dist/api/dto/mail.d.ts +43 -0
- package/dist/api/dto/nodes.d.ts +11 -8
- package/dist/api/dto/recovery.d.ts +96 -0
- package/dist/api/dto/reviews.d.ts +2 -2
- package/dist/api/routes.d.ts +9 -6
- package/dist/api/routes.js +11 -11
- package/dist/build-root.d.ts +4 -0
- package/dist/build-root.js +11 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/cli.js +10 -1
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
- package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
- package/dist/clients/attach/chrome/inbox-strip.js +17 -9
- package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
- package/dist/clients/attach/chrome/ticket-panel.js +77 -46
- package/dist/clients/attach/overlays/graph.js +6 -9
- package/dist/clients/attach/render/chat-view.d.ts +5 -4
- package/dist/clients/attach/render/chat-view.js +22 -13
- package/dist/clients/attach/render/page-block.d.ts +11 -7
- package/dist/clients/attach/render/page-block.js +64 -55
- package/dist/clients/attach/viewer.js +746 -735
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
- package/dist/clients/inbox/controller.d.ts +42 -14
- package/dist/clients/inbox/controller.js +240 -124
- package/dist/clients/inbox/dto-adapt.d.ts +28 -0
- package/dist/clients/inbox/dto-adapt.js +93 -0
- package/dist/clients/inbox/page-adapter.d.ts +5 -4
- package/dist/clients/inbox/page-adapter.js +12 -12
- package/dist/clients/inbox/resolve.d.ts +10 -5
- package/dist/clients/inbox/resolve.js +13 -12
- package/dist/clients/inbox/review/review-client.d.ts +0 -1
- package/dist/clients/inbox/review/review-client.js +0 -4
- package/dist/clients/inbox/review-adapter.d.ts +2 -1
- package/dist/clients/inbox/review-adapter.js +3 -5
- package/dist/clients/inbox/surface.d.ts +2 -2
- package/dist/clients/inbox/surface.js +19 -8
- package/dist/clients/inbox/tui.d.ts +3 -3
- package/dist/commands/__tests__/human.test.js +31 -15
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
- package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
- package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
- package/dist/commands/api-client.d.ts +5 -4
- package/dist/commands/api-client.js +13 -7
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas-roster.js +1 -1
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/human/feedback.js +20 -17
- package/dist/commands/human/prompts.js +45 -36
- package/dist/commands/human/queue.js +73 -123
- package/dist/commands/human/review.js +6 -16
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
- package/dist/commands/node-inspect-artifacts.js +1 -1
- package/dist/commands/node-lifecycle-revive.d.ts +2 -2
- package/dist/commands/node-lifecycle-revive.js +9 -19
- package/dist/commands/pkg/plugin-manage.js +0 -1
- package/dist/commands/profile/show.js +4 -12
- package/dist/commands/surface-tmux-spread.js +1 -5
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
- package/dist/commands/sys/branch.d.ts +2 -0
- package/dist/commands/sys/branch.js +19 -0
- package/dist/commands/sys/config.js +106 -33
- package/dist/commands/sys/daemon.d.ts +2 -0
- package/dist/commands/sys/daemon.js +130 -7
- package/dist/commands/sys/doctor.js +5 -15
- package/dist/commands/sys/migrate.js +21 -92
- package/dist/commands/sys/setup-settings-runner.js +4 -2
- package/dist/commands/sys.js +2 -15
- package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
- package/dist/core/__tests__/boot.test.js +32 -25
- package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
- package/dist/core/__tests__/canvas.test.js +18 -47
- package/dist/core/__tests__/child-death-wake.test.js +29 -7
- package/dist/core/__tests__/cli-help-contract.test.js +2 -0
- package/dist/core/__tests__/close.test.js +29 -10
- package/dist/core/__tests__/collectible.test.js +2 -1
- package/dist/core/__tests__/config-change-delta.test.js +2 -0
- package/dist/core/__tests__/context-intro.test.js +13 -1
- package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
- package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
- package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
- package/dist/core/__tests__/daemon-boot.test.js +51 -14
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
- package/dist/core/__tests__/focuses.test.js +10 -5
- package/dist/core/__tests__/helpers/harness.js +50 -18
- package/dist/core/__tests__/history-inbox.test.js +12 -16
- package/dist/core/__tests__/human-action-delivery.test.js +48 -28
- package/dist/core/__tests__/human-actions.test.js +7 -3
- package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
- package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +16 -3
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
- package/dist/core/__tests__/integration/revive.test.js +67 -21
- package/dist/core/__tests__/integration/spawn-root.test.js +51 -8
- package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
- package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
- package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
- package/dist/core/__tests__/kickoff.test.js +36 -39
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
- package/dist/core/__tests__/lifecycle.test.js +2 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
- package/dist/core/__tests__/migration.test.js +145 -31
- package/dist/core/__tests__/model-pin-durability.test.js +4 -1
- package/dist/core/__tests__/model-routes-config.test.js +13 -5
- package/dist/core/__tests__/node-outcome.test.js +93 -26
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
- package/dist/core/__tests__/passive-subscription.test.js +50 -157
- package/dist/core/__tests__/plugin-kinds.test.js +6 -4
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
- package/dist/core/__tests__/plugin-page-components.test.js +6 -4
- package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +4 -1
- package/dist/core/__tests__/prune.test.js +11 -5
- package/dist/core/__tests__/push-final-guard.test.js +14 -7
- package/dist/core/__tests__/relaunch-root.test.js +30 -2
- package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
- package/dist/core/__tests__/repository-root-identity.test.js +4 -0
- package/dist/core/__tests__/review-model-floor.test.js +6 -3
- package/dist/core/__tests__/revive-all.test.js +13 -3
- package/dist/core/__tests__/revive-capacity.test.js +26 -4
- package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
- package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +2 -1
- package/dist/core/__tests__/stop-guard.test.js +2 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +18 -4
- package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
- package/dist/core/broker-client/transport-socket.d.ts +1 -0
- package/dist/core/broker-client/transport-socket.js +13 -5
- package/dist/core/canvas/__tests__/attention.test.js +29 -35
- package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
- package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
- package/dist/core/canvas/attention.d.ts +2 -5
- package/dist/core/canvas/attention.js +15 -64
- package/dist/core/canvas/boot.d.ts +6 -7
- package/dist/core/canvas/boot.js +5 -9
- package/dist/core/canvas/canvas.d.ts +13 -109
- package/dist/core/canvas/canvas.js +140 -401
- package/dist/core/canvas/crons.d.ts +2 -0
- package/dist/core/canvas/crons.js +16 -15
- package/dist/core/canvas/daemon-owner.js +10 -0
- package/dist/core/canvas/db.d.ts +2 -2
- package/dist/core/canvas/db.js +2 -18
- package/dist/core/canvas/deliveries.d.ts +104 -0
- package/dist/core/canvas/deliveries.js +354 -0
- package/dist/core/canvas/executions.d.ts +29 -0
- package/dist/core/canvas/executions.js +68 -0
- package/dist/core/canvas/history.js +35 -35
- package/dist/core/canvas/index.d.ts +3 -1
- package/dist/core/canvas/index.js +3 -1
- package/dist/core/canvas/migrations.js +20 -12
- package/dist/core/canvas/nav-model.js +1 -3
- package/dist/core/canvas/nav-render.d.ts +4 -4
- package/dist/core/canvas/nav-render.js +11 -21
- package/dist/core/canvas/node-sql-migration.d.ts +3 -0
- package/dist/core/canvas/node-sql-migration.js +261 -0
- package/dist/core/canvas/paths.d.ts +2 -16
- package/dist/core/canvas/paths.js +2 -31
- package/dist/core/canvas/recovery.d.ts +76 -0
- package/dist/core/canvas/recovery.js +588 -0
- package/dist/core/canvas/remote-canvas-source.js +4 -0
- package/dist/core/canvas/render-source.d.ts +16 -27
- package/dist/core/canvas/render-source.js +16 -45
- package/dist/core/canvas/sessions.d.ts +33 -0
- package/dist/core/canvas/sessions.js +78 -0
- package/dist/core/canvas/types.d.ts +33 -33
- package/dist/core/canvas/types.js +2 -5
- package/dist/core/canvas/waits.d.ts +18 -0
- package/dist/core/canvas/waits.js +70 -0
- package/dist/core/canvas/worktrees.d.ts +40 -0
- package/dist/core/canvas/worktrees.js +93 -0
- package/dist/core/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
- package/dist/core/feed/feed.d.ts +0 -6
- package/dist/core/feed/feed.js +68 -56
- package/dist/core/feed/inbox.d.ts +7 -81
- package/dist/core/feed/inbox.js +46 -378
- package/dist/core/feed/messages.d.ts +58 -0
- package/dist/core/feed/messages.js +217 -0
- package/dist/core/fs-utils.d.ts +4 -0
- package/dist/core/fs-utils.js +21 -1
- package/dist/core/human/answer.d.ts +1 -1
- package/dist/core/human/answer.js +1 -1
- package/dist/core/human/claim.d.ts +1 -1
- package/dist/core/human/claim.js +2 -4
- package/dist/core/human/component-docs.js +1 -1
- package/dist/core/human/feedback-companion.js +3 -2
- package/dist/core/human/feedback.d.ts +5 -8
- package/dist/core/human/feedback.js +57 -85
- package/dist/core/human/page-authoring.d.ts +30 -0
- package/dist/core/human/page-authoring.js +19 -0
- package/dist/core/human/requests.d.ts +136 -0
- package/dist/core/human/requests.js +515 -0
- package/dist/core/human/root.d.ts +0 -7
- package/dist/core/human/root.js +0 -17
- package/dist/core/human/scan.d.ts +2 -7
- package/dist/core/human/scan.js +48 -132
- package/dist/core/human/summary.d.ts +1 -1
- package/dist/core/human/summary.js +1 -1
- package/dist/core/human/tickets.d.ts +23 -83
- package/dist/core/human/tickets.js +92 -243
- package/dist/core/human/types.d.ts +5 -1
- package/dist/core/installed-plugins.js +8 -3
- package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
- package/dist/core/locked-file.d.ts +6 -3
- package/dist/core/locked-file.js +36 -9
- package/dist/core/memory/extensions.js +2 -0
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +2 -0
- package/dist/core/profiles/default-binding.d.ts +0 -4
- package/dist/core/profiles/default-binding.js +12 -58
- package/dist/core/profiles/env-store.js +8 -3
- package/dist/core/profiles/manifest.d.ts +2 -37
- package/dist/core/profiles/manifest.js +35 -161
- package/dist/core/profiles/select.js +3 -0
- package/dist/core/review/__tests__/capture-origin.test.js +13 -2
- package/dist/core/review/__tests__/comments.test.js +28 -10
- package/dist/core/review/__tests__/remap.test.js +28 -10
- package/dist/core/review/__tests__/stage-identity.test.js +17 -7
- package/dist/core/review/birth.d.ts +1 -1
- package/dist/core/review/birth.js +34 -5
- package/dist/core/review/comments.js +1 -1
- package/dist/core/review/document.js +1 -1
- package/dist/core/review/project.d.ts +5 -1
- package/dist/core/review/project.js +14 -36
- package/dist/core/review/realize.d.ts +3 -6
- package/dist/core/review/realize.js +51 -168
- package/dist/core/review/remap.js +1 -1
- package/dist/core/review/stage.d.ts +3 -2
- package/dist/core/review/stage.js +2 -3
- package/dist/core/review/store.d.ts +3 -21
- package/dist/core/review/store.js +140 -186
- package/dist/core/review/types.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
- package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
- package/dist/core/runtime/broker/auth-reload.js +9 -10
- package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
- package/dist/core/runtime/broker/daemon-ops.js +42 -9
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +11 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
- package/dist/core/runtime/broker/fault-retry.js +142 -95
- package/dist/core/runtime/broker/inbox.d.ts +4 -32
- package/dist/core/runtime/broker/inbox.js +4 -92
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +21 -12
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -13
- package/dist/core/runtime/broker.js +28 -22
- package/dist/core/runtime/close.d.ts +3 -9
- package/dist/core/runtime/close.js +16 -27
- package/dist/core/runtime/fault.d.ts +3 -93
- package/dist/core/runtime/fault.js +9 -419
- package/dist/core/runtime/kickoff.d.ts +3 -6
- package/dist/core/runtime/kickoff.js +12 -18
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +40 -7
- package/dist/core/runtime/placement.js +2 -2
- package/dist/core/runtime/recycle.js +8 -2
- package/dist/core/runtime/reset.js +22 -6
- package/dist/core/runtime/revive.js +226 -218
- package/dist/core/runtime/spawn.js +14 -3
- package/dist/core/scoped-state/db.d.ts +7 -0
- package/dist/core/scoped-state/db.js +92 -0
- package/dist/core/scoped-state/migrate.d.ts +11 -0
- package/dist/core/scoped-state/migrate.js +198 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +12 -0
- package/dist/core/scoped-state/profiles.js +62 -0
- package/dist/core/scoped-state/providers.d.ts +16 -0
- package/dist/core/scoped-state/providers.js +8 -0
- package/dist/core/scoped-state/schema.d.ts +3 -0
- package/dist/core/scoped-state/schema.js +26 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +82 -0
- package/dist/core/subscription-state.d.ts +29 -48
- package/dist/core/subscription-state.js +176 -712
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +2 -2
- package/dist/core/worktree-sweep.js +11 -16
- package/dist/core/worktree.js +6 -12
- package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
- package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
- package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
- package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +39 -15
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
- package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
- package/dist/daemon/api/__tests__/model-config.test.js +8 -8
- package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +4 -1
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
- package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +27 -41
- package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
- package/dist/daemon/api/bridge.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +6 -7
- package/dist/daemon/api/handlers/broker-ops.js +47 -84
- package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
- package/dist/daemon/api/handlers/broker-recovery.js +251 -0
- package/dist/daemon/api/handlers/canvas.js +2 -44
- package/dist/daemon/api/handlers/daemon.js +41 -0
- package/dist/daemon/api/handlers/feedback-comments.js +2 -2
- package/dist/daemon/api/handlers/health.js +10 -5
- package/dist/daemon/api/handlers/human-requests.js +168 -188
- package/dist/daemon/api/handlers/human.js +3 -151
- package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
- package/dist/daemon/api/handlers/inbox-page.js +89 -0
- package/dist/daemon/api/handlers/inbox.js +21 -120
- package/dist/daemon/api/handlers/messages.d.ts +1 -0
- package/dist/daemon/api/handlers/messages.js +73 -15
- package/dist/daemon/api/handlers/node-outcomes.js +58 -13
- package/dist/daemon/api/handlers/nodes.js +7 -13
- package/dist/daemon/api/handlers/reviews.js +4 -29
- package/dist/daemon/api/map.d.ts +25 -3
- package/dist/daemon/api/map.js +84 -14
- package/dist/daemon/api/server.js +68 -9
- package/dist/daemon/control.d.ts +18 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +8 -5
- package/dist/daemon/cron/settle.js +37 -13
- package/dist/daemon/cron/sinks.d.ts +18 -1
- package/dist/daemon/cron/sinks.js +47 -93
- package/dist/daemon/crtrd-cli.js +4 -19
- package/dist/daemon/crtrd.d.ts +2 -0
- package/dist/daemon/crtrd.js +206 -81
- package/dist/daemon/fleet.js +5 -6
- package/dist/daemon/human/finish.d.ts +12 -24
- package/dist/daemon/human/finish.js +88 -285
- package/dist/daemon/human/settle.d.ts +40 -0
- package/dist/daemon/human/settle.js +89 -0
- package/dist/daemon/human/sweep.d.ts +20 -5
- package/dist/daemon/human/sweep.js +56 -60
- package/dist/daemon/manage.d.ts +21 -16
- package/dist/daemon/manage.js +85 -51
- package/dist/daemon/messaging/node-message.d.ts +1 -1
- package/dist/daemon/messaging/node-message.js +9 -12
- package/dist/daemon/park-activity.js +3 -3
- package/dist/daemon/reconcilers/bash-deadline.js +6 -7
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +41 -19
- package/dist/daemon/reconcilers/controller-death.js +6 -18
- package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/delivery-lane.js +130 -0
- package/dist/daemon/reconcilers/live-obligation.js +3 -3
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
- package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
- package/dist/daemon/review/companion.js +5 -11
- package/dist/daemon/review/deliver.d.ts +1 -5
- package/dist/daemon/review/deliver.js +3 -52
- package/dist/daemon/review/finish.d.ts +2 -27
- package/dist/daemon/review/finish.js +79 -263
- package/dist/daemon/review/sweep.d.ts +3 -10
- package/dist/daemon/review/sweep.js +13 -131
- package/dist/daemon/startup-policy.d.ts +0 -5
- package/dist/daemon/startup-policy.js +0 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
- package/dist/migrations/__tests__/activation.test.js +9 -6
- package/dist/migrations/activation.d.ts +3 -2
- package/dist/migrations/activation.js +2 -4
- package/dist/migrations/corpus.d.ts +2 -5
- package/dist/migrations/corpus.js +9 -20
- package/dist/migrations/runner.d.ts +3 -1
- package/dist/migrations/runner.js +6 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
- package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
- package/dist/pi-extensions/canvas-passive-context.js +85 -37
- package/dist/pi-extensions/canvas-stophook.js +47 -31
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.js +3 -0
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/dist/clients/attach/__tests__/page-block.test.js +0 -54
- package/dist/clients/inbox/review-visibility.d.ts +0 -5
- package/dist/clients/inbox/review-visibility.js +0 -19
- package/dist/commands/canvas-rebuild-index.d.ts +0 -2
- package/dist/commands/canvas-rebuild-index.js +0 -46
- package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
- package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
- package/dist/core/__tests__/human-deliver.test.js +0 -256
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
- package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
- package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
- package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
- package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-store.test.js +0 -144
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
- package/dist/core/canvas/human-deliveries.d.ts +0 -39
- package/dist/core/canvas/human-deliveries.js +0 -75
- package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
- package/dist/core/canvas/node-outcome-deliveries.js +0 -159
- package/dist/core/feed/passive.d.ts +0 -3
- package/dist/core/feed/passive.js +0 -53
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
- package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
- package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-tickets.test.js +0 -161
- package/dist/core/review/ticket-filter.d.ts +0 -17
- package/dist/core/review/ticket-filter.js +0 -21
- package/dist/core/runtime/broker/passive.d.ts +0 -17
- package/dist/core/runtime/broker/passive.js +0 -44
- package/dist/core/runtime/busy.d.ts +0 -46
- package/dist/core/runtime/busy.js +0 -150
- package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
- package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
- package/dist/daemon/human/deliver-action.d.ts +0 -3
- package/dist/daemon/human/deliver-action.js +0 -9
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
- package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
- package/dist/daemon/startup-block-marker.d.ts +0 -25
- package/dist/daemon/startup-block-marker.js +0 -99
- /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
- /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
- /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
|
@@ -3,10 +3,14 @@ import { spawnSync } from 'node:child_process';
|
|
|
3
3
|
import { existsSync, mkdtempSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { dirname, join, relative } from 'node:path';
|
|
6
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
7
|
import test from 'node:test';
|
|
8
8
|
import { parse as parseYaml } from 'yaml';
|
|
9
9
|
import { onDiskMigrationIdentity } from '../../../migrations/registry.js';
|
|
10
|
+
import { initializeFreshScopedStore } from '../../../core/scoped-state/migrate.js';
|
|
11
|
+
import { userStore } from '../../../core/scoped-state/paths.js';
|
|
12
|
+
import { writeRawSettings } from '../../../core/scoped-state/settings.js';
|
|
13
|
+
import { createSourceDaemonFixture, startSourceDaemon, waitForHealth, } from '../../../daemon/__tests__/helpers/source-daemon.js';
|
|
10
14
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
11
15
|
const CLI = join(HERE, '../../../cli.ts');
|
|
12
16
|
const TSX_LOADER = import.meta.resolve('tsx/esm');
|
|
@@ -49,8 +53,17 @@ function write(path, content) {
|
|
|
49
53
|
}
|
|
50
54
|
/** Store keys and target ids are realpaths, so the fixture must be one too:
|
|
51
55
|
* macOS hands `mkdtemp` a `/var/folders` path whose realpath is `/private/...`. */
|
|
56
|
+
const migrateCanvasHomes = new Map();
|
|
52
57
|
function fixtureHome(prefix) {
|
|
53
|
-
|
|
58
|
+
const home = realpathSync(mkdtempSync(join(tmpdir(), prefix)));
|
|
59
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
60
|
+
const root = mkdtempSync(join(tmpdir(), 'crtr-sys-migrate-daemon-'));
|
|
61
|
+
migrateCanvasHomes.set(home, join(root, 'canvas'));
|
|
62
|
+
return home;
|
|
63
|
+
}
|
|
64
|
+
function writeUserConfig(home, raw) {
|
|
65
|
+
const store = userStore(join(home, '.crouter'));
|
|
66
|
+
writeRawSettings({ store, key: 'user', kind: 'user', root: store.root }, raw);
|
|
54
67
|
}
|
|
55
68
|
/** Fixture git, with identity and signing pinned so the ambient user's global
|
|
56
69
|
* config cannot fail a commit this test needs. */
|
|
@@ -66,8 +79,11 @@ function initRepo(dir) {
|
|
|
66
79
|
git(dir, 'add', 'README.md');
|
|
67
80
|
git(dir, 'commit', '-m', 'fixture');
|
|
68
81
|
}
|
|
82
|
+
function canvasHomeFor(home) {
|
|
83
|
+
return migrateDaemons.get(home)?.fixture.canvasHome ?? migrateCanvasHomes.get(home) ?? join(home, '.crouter', 'canvas');
|
|
84
|
+
}
|
|
69
85
|
function markerPath(home) {
|
|
70
|
-
return join(home, '
|
|
86
|
+
return join(canvasHomeFor(home), 'on-disk-migrations.json');
|
|
71
87
|
}
|
|
72
88
|
function readMarker(home) {
|
|
73
89
|
return JSON.parse(readFileSync(markerPath(home), 'utf8'));
|
|
@@ -112,11 +128,64 @@ function migrateEnv(home, profileId) {
|
|
|
112
128
|
if (key.startsWith('CRTR_'))
|
|
113
129
|
delete env[key];
|
|
114
130
|
}
|
|
131
|
+
env['CRTR_HOME'] = canvasHomeFor(home);
|
|
115
132
|
env['CRTR_PROFILE_ID'] = profileId;
|
|
133
|
+
env['CRTR_NO_DAEMON_AUTOSTART'] = '1';
|
|
116
134
|
env['CRTR_NO_AUTO_INIT'] = '1';
|
|
117
135
|
env['CRTR_NO_AUTO_UPDATE'] = '1';
|
|
118
136
|
return env;
|
|
119
137
|
}
|
|
138
|
+
const migrateDaemons = new Map();
|
|
139
|
+
async function startMigrateDaemon(home) {
|
|
140
|
+
const canvasHome = migrateCanvasHomes.get(home);
|
|
141
|
+
assert.ok(canvasHome, `fixture has no canvas home: ${home}`);
|
|
142
|
+
const fixture = await createSourceDaemonFixture({
|
|
143
|
+
root: dirname(canvasHome),
|
|
144
|
+
home,
|
|
145
|
+
cwd: home,
|
|
146
|
+
canvasHome,
|
|
147
|
+
});
|
|
148
|
+
const process = startSourceDaemon(fixture, { CRTR_PROFILE_ID: 'root-00000000' });
|
|
149
|
+
try {
|
|
150
|
+
await waitForHealth(process, fixture.tcpPort);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
await process.stop();
|
|
154
|
+
fixture.dispose();
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
migrateDaemons.set(home, { fixture, process });
|
|
158
|
+
}
|
|
159
|
+
async function stopMigrateDaemon(home) {
|
|
160
|
+
const daemon = migrateDaemons.get(home);
|
|
161
|
+
if (daemon === undefined)
|
|
162
|
+
return;
|
|
163
|
+
migrateDaemons.delete(home);
|
|
164
|
+
const exit = await daemon.process.stop();
|
|
165
|
+
daemon.fixture.dispose();
|
|
166
|
+
migrateCanvasHomes.delete(home);
|
|
167
|
+
assert.deepEqual(exit, { code: 0, signal: null }, `migration daemon must stop cleanly; stderr:\n${daemon.process.stderr()}`);
|
|
168
|
+
}
|
|
169
|
+
function seedNodeMemoryTarget(home, target) {
|
|
170
|
+
const canvas = pathToFileURL(join(HERE, '../../../core/canvas/canvas.ts')).href;
|
|
171
|
+
const program = `
|
|
172
|
+
import { createNode } from ${JSON.stringify(canvas)};
|
|
173
|
+
const target = JSON.parse(process.argv[1]);
|
|
174
|
+
createNode({
|
|
175
|
+
node_id: target.nodeId,
|
|
176
|
+
name: target.nodeId,
|
|
177
|
+
created: new Date().toISOString(),
|
|
178
|
+
cwd: target.cwd,
|
|
179
|
+
kind: 'developer',
|
|
180
|
+
mode: 'base',
|
|
181
|
+
lifecycle: 'terminal',
|
|
182
|
+
status: 'done',
|
|
183
|
+
profile_id: target.profileId,
|
|
184
|
+
});
|
|
185
|
+
`;
|
|
186
|
+
const result = spawnSync(process.execPath, ['--conditions=crtr-src', '--import', TSX_LOADER, '--input-type=module', '--eval', program, JSON.stringify(target)], { cwd: home, env: migrateEnv(home, target.profileId ?? 'root-00000000'), encoding: 'utf8' });
|
|
187
|
+
assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
|
|
188
|
+
}
|
|
120
189
|
function runMigrate(home, opts = {}) {
|
|
121
190
|
const result = spawnSync(process.execPath, [
|
|
122
191
|
'--conditions=crtr-src',
|
|
@@ -186,7 +255,7 @@ function manifest(name, projects) {
|
|
|
186
255
|
last_used_at: null,
|
|
187
256
|
});
|
|
188
257
|
}
|
|
189
|
-
test('sys migrate converges manifests, documents, and the whole repository-root corpus', () => {
|
|
258
|
+
test('sys migrate converges manifests, documents, and the whole repository-root corpus', async () => {
|
|
190
259
|
const home = fixtureHome('crtr-sys-migrate-');
|
|
191
260
|
const userRoot = join(home, '.crouter');
|
|
192
261
|
const rootProfile = join(userRoot, 'profiles', 'root-00000000');
|
|
@@ -200,7 +269,7 @@ test('sys migrate converges manifests, documents, and the whole repository-root
|
|
|
200
269
|
const embeddedPluginRoot = join(nestedOnlyProject, 'embedded', '.crouter', 'plugins', 'embedded-memory');
|
|
201
270
|
const disabledPluginRoot = join(userRoot, 'plugins', 'disabled-memory');
|
|
202
271
|
const nodeId = 'node-aaaa1111';
|
|
203
|
-
const nodeStore = join(
|
|
272
|
+
const nodeStore = join(canvasHomeFor(home), 'nodes', nodeId, 'context', 'memory');
|
|
204
273
|
const userDoc = join(userRoot, 'memory', 'user-link.md');
|
|
205
274
|
const rootDoc = join(rootProfile, 'memory', 'root.md');
|
|
206
275
|
const appletDoc = join(appletProfile, 'memory', 'identity.md');
|
|
@@ -215,6 +284,8 @@ test('sys migrate converges manifests, documents, and the whole repository-root
|
|
|
215
284
|
const disabledPluginDoc = join(disabledPluginRoot, 'memory', 'guide.md');
|
|
216
285
|
const nodeDoc = join(nodeStore, 'note.md');
|
|
217
286
|
try {
|
|
287
|
+
await startMigrateDaemon(home);
|
|
288
|
+
seedNodeMemoryTarget(home, { nodeId, cwd: appletProject, profileId: 'applet-deadbeef' });
|
|
218
289
|
// Root's string entries migrate to `preview`; every other profile's to
|
|
219
290
|
// `content`. The applet manifest is mixed: its already-current entry must
|
|
220
291
|
// survive untouched while the string beside it converts.
|
|
@@ -225,7 +296,7 @@ test('sys migrate converges manifests, documents, and the whole repository-root
|
|
|
225
296
|
write(userDoc, `${OLD_DOC}\nSee [[user/scoped]].\n`);
|
|
226
297
|
write(join(userRoot, 'memory', 'scoped', 'INDEX.md'), CURRENT_DOC);
|
|
227
298
|
// Root profile store: an INDEX spelling to collapse, an unqualified project
|
|
228
|
-
// name
|
|
299
|
+
// name outside its own target stack, and a name its own target stack cannot see.
|
|
229
300
|
write(rootDoc, `${OLD_DOC}\nSee [[notes/INDEX]], [[project]], and [[shared]].\n`);
|
|
230
301
|
write(join(rootProfile, 'memory', 'notes', 'INDEX.md'), CURRENT_DOC);
|
|
231
302
|
write(appletDoc, `${OLD_DOC}\nSee [[shared]].\n`);
|
|
@@ -267,12 +338,12 @@ See [[project]].
|
|
|
267
338
|
write(embeddedPluginDoc, OLD_DOC);
|
|
268
339
|
// A DISABLED plugin: no target mounts it, so its references resolve against
|
|
269
340
|
// its own store alone — and it is still migrated.
|
|
270
|
-
|
|
341
|
+
writeUserConfig(home, { plugins: { 'disabled-memory': { enabled: false } } });
|
|
271
342
|
write(join(disabledPluginRoot, '.crouter-plugin', 'plugin.json'), JSON.stringify({ name: 'disabled-memory', version: '1.0.0' }));
|
|
272
343
|
write(join(disabledPluginRoot, 'memory', 'notes', 'INDEX.md'), CURRENT_DOC);
|
|
273
344
|
write(disabledPluginDoc, `${CURRENT_DOC}\nSee [[disabled-memory/notes/INDEX]].\n`);
|
|
274
|
-
// A node store
|
|
275
|
-
|
|
345
|
+
// A node store whose SQL row was seeded before its documents. No meta.json
|
|
346
|
+
// exists: corpus discovery must use the daemon-owned roster.
|
|
276
347
|
write(nodeDoc, `${CURRENT_DOC}\nSee [[project]].\n`);
|
|
277
348
|
// Reached by --dir only: no manifest names it and it is under no discovered
|
|
278
349
|
// project root. Its `name:` is the FIRST frontmatter key, so the removal and
|
|
@@ -281,7 +352,7 @@ See [[project]].
|
|
|
281
352
|
write(join(extraProject, '.crouter', 'memory', 'INDEX.md'), `---\nname: extra-dir-project\nkind: knowledge\n---\n# Extra Dir Project\n`);
|
|
282
353
|
write(join(extraProject, '.crouter', 'memory', 'topic.md'), CURRENT_DOC);
|
|
283
354
|
const invisible = migrateJson(home, { dryRun: true });
|
|
284
|
-
assert.
|
|
355
|
+
assert.deepEqual(readMarker(home), onDiskMigrationIdentity(), 'the daemon completed its empty-corpus startup before fixture bytes were seeded');
|
|
285
356
|
assert.equal(invisible.discovered_stores.some((row) => row.store.startsWith(extraProject)), false, 'the --dir project must be outside the ambient discovery frontier');
|
|
286
357
|
const output = migrateJson(home, { dirs: [extraProject] });
|
|
287
358
|
assert.deepEqual(readMarker(home), onDiskMigrationIdentity());
|
|
@@ -301,8 +372,6 @@ See [[project]].
|
|
|
301
372
|
assert.doesNotMatch(migrated, /system-prompt-visibility|file-read-visibility/);
|
|
302
373
|
assert.match(migrated, /surfaces:\n - on: boot\n at: content/);
|
|
303
374
|
}
|
|
304
|
-
// Durable node metadata, read with no daemon.
|
|
305
|
-
assert.deepEqual(output.node_metadata, { available: true, nodes: 1 });
|
|
306
375
|
const nodeTarget = output.discovered_targets.find((row) => row.kind === 'node');
|
|
307
376
|
assert.equal(nodeTarget?.node_id, nodeId);
|
|
308
377
|
assert.equal(nodeTarget?.origin, nodeId);
|
|
@@ -379,7 +448,7 @@ surfaces:
|
|
|
379
448
|
// completion.
|
|
380
449
|
const rootDocText = readFileSync(rootDoc, 'utf8');
|
|
381
450
|
assert.match(rootDocText, /\[\[notes\]\]/);
|
|
382
|
-
assert.match(rootDocText, /\[\[
|
|
451
|
+
assert.match(rootDocText, /\[\[project\]\]/);
|
|
383
452
|
assert.match(rootDocText, /\[\[shared\]\]/);
|
|
384
453
|
assert.match(readFileSync(userDoc, 'utf8'), /\[\[user\/scoped\]\]/);
|
|
385
454
|
assert.match(readFileSync(appletDoc, 'utf8'), /\[\[shared\]\]/);
|
|
@@ -442,6 +511,7 @@ See [[applet-project/project]].
|
|
|
442
511
|
assertTreeUnchanged(converged, snapshotTree(home));
|
|
443
512
|
}
|
|
444
513
|
finally {
|
|
514
|
+
await stopMigrateDaemon(home);
|
|
445
515
|
rmSync(home, { recursive: true, force: true });
|
|
446
516
|
}
|
|
447
517
|
});
|
|
@@ -471,10 +541,12 @@ function seedConvergenceFixture(home, start) {
|
|
|
471
541
|
write(join(nestedOwner, '.crouter', 'memory', 'INDEX.md'), supersededSyntheticIndex('pkg'));
|
|
472
542
|
write(markerPath(home), JSON.stringify([{ id: '003-workspace-qualified-memory-identity', lane: 'corpus' }]));
|
|
473
543
|
}
|
|
474
|
-
test('pre-003 and superseded-003 corpora converge to the same bytes and the same current marker', () => {
|
|
544
|
+
test('pre-003 and superseded-003 corpora converge to the same bytes and the same current marker', async () => {
|
|
475
545
|
const preHome = fixtureHome('crtr-sys-migrate-conv-pre-');
|
|
476
546
|
const oldHome = fixtureHome('crtr-sys-migrate-conv-old-');
|
|
477
547
|
try {
|
|
548
|
+
await startMigrateDaemon(preHome);
|
|
549
|
+
await startMigrateDaemon(oldHome);
|
|
478
550
|
seedConvergenceFixture(preHome, 'pre-003');
|
|
479
551
|
seedConvergenceFixture(oldHome, 'superseded-003');
|
|
480
552
|
const fromPre = migrateJson(preHome);
|
|
@@ -519,17 +591,20 @@ test('pre-003 and superseded-003 corpora converge to the same bytes and the same
|
|
|
519
591
|
assert.equal(prefixRow(fromPre, join(preHome, 'conv-project', 'pkg')).nested_declaration_action, 'none');
|
|
520
592
|
}
|
|
521
593
|
finally {
|
|
594
|
+
await stopMigrateDaemon(preHome);
|
|
595
|
+
await stopMigrateDaemon(oldHome);
|
|
522
596
|
rmSync(preHome, { recursive: true, force: true });
|
|
523
597
|
rmSync(oldHome, { recursive: true, force: true });
|
|
524
598
|
}
|
|
525
599
|
});
|
|
526
|
-
test('a repository declaration is kept when declared, derived from the root guide, or created when no root index exists', () => {
|
|
600
|
+
test('a repository declaration is kept when declared, derived from the root guide, or created when no root index exists', async () => {
|
|
527
601
|
const home = fixtureHome('crtr-sys-migrate-decisions-');
|
|
528
602
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
529
603
|
const kept = join(home, 'kept-project');
|
|
530
604
|
const derived = join(home, 'derived-project');
|
|
531
605
|
const created = join(home, 'created-project');
|
|
532
606
|
try {
|
|
607
|
+
await startMigrateDaemon(home);
|
|
533
608
|
write(join(rootProfile, 'profile.json'), manifest('root', [kept, derived, created].map((path) => ({ path, memory: 'content' }))));
|
|
534
609
|
write(join(kept, '.crouter', 'memory', 'INDEX.md'), `---\nnamespace: kept-ns\nkind: knowledge\n---\n# Kept\n`);
|
|
535
610
|
write(join(kept, '.crouter', 'memory', 'note.md'), CURRENT_DOC);
|
|
@@ -563,15 +638,17 @@ This project's memory store. Every document here answers at \`created-project/<l
|
|
|
563
638
|
assert.equal(migrateJson(home).changed, 0);
|
|
564
639
|
}
|
|
565
640
|
finally {
|
|
641
|
+
await stopMigrateDaemon(home);
|
|
566
642
|
rmSync(home, { recursive: true, force: true });
|
|
567
643
|
}
|
|
568
644
|
});
|
|
569
|
-
test('a git repository whose only stores are descendants gets its repository-root declaration created', () => {
|
|
645
|
+
test('a git repository whose only stores are descendants gets its repository-root declaration created', async () => {
|
|
570
646
|
const home = fixtureHome('crtr-sys-migrate-git-descendant-');
|
|
571
647
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
572
648
|
const repo = join(home, 'pkg-repo');
|
|
573
649
|
const nestedOwner = join(repo, 'pkg');
|
|
574
650
|
try {
|
|
651
|
+
await startMigrateDaemon(home);
|
|
575
652
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: repo, memory: 'content' }]));
|
|
576
653
|
initRepo(repo);
|
|
577
654
|
write(join(nestedOwner, '.crouter', 'memory', 'note.md'), CURRENT_DOC);
|
|
@@ -590,19 +667,22 @@ test('a git repository whose only stores are descendants gets its repository-roo
|
|
|
590
667
|
assert.deepEqual(output.store_prefixes.map((row) => [row.owner_dir, row.owner_relative_path, row.effective_prefix]), [[nestedOwner, 'pkg', 'pkg-repo/pkg']]);
|
|
591
668
|
assert.match(readFileSync(join(repo, '.crouter', 'memory', 'INDEX.md'), 'utf8'), /^---\nnamespace: "pkg-repo"\n/);
|
|
592
669
|
assert.equal(output.renames.some((row) => row.from === 'note' && row.to === 'pkg-repo/pkg/note'), true, JSON.stringify(output.renames));
|
|
593
|
-
|
|
670
|
+
const second = migrateJson(home);
|
|
671
|
+
assert.equal(second.changed, 0, JSON.stringify(second.applied));
|
|
594
672
|
}
|
|
595
673
|
finally {
|
|
674
|
+
await stopMigrateDaemon(home);
|
|
596
675
|
rmSync(home, { recursive: true, force: true });
|
|
597
676
|
}
|
|
598
677
|
});
|
|
599
|
-
test('linked worktrees agree on one declaration, and a linked root missing one is filled from it', () => {
|
|
678
|
+
test('linked worktrees agree on one declaration, and a linked root missing one is filled from it', async () => {
|
|
600
679
|
for (const mode of ['agree', 'fill']) {
|
|
601
680
|
const home = fixtureHome(`crtr-sys-migrate-worktree-${mode}-`);
|
|
602
681
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
603
682
|
const main = join(home, 'shared-main');
|
|
604
683
|
const linked = join(home, 'shared-linked');
|
|
605
684
|
try {
|
|
685
|
+
await startMigrateDaemon(home);
|
|
606
686
|
write(join(rootProfile, 'profile.json'), manifest('root', [main, linked].map((path) => ({ path, memory: 'content' }))));
|
|
607
687
|
initRepo(main);
|
|
608
688
|
git(main, 'worktree', 'add', linked, '-b', 'linked');
|
|
@@ -628,16 +708,18 @@ test('linked worktrees agree on one declaration, and a linked root missing one i
|
|
|
628
708
|
assert.equal(migrateJson(home).changed, 0);
|
|
629
709
|
}
|
|
630
710
|
finally {
|
|
711
|
+
await stopMigrateDaemon(home);
|
|
631
712
|
rmSync(home, { recursive: true, force: true });
|
|
632
713
|
}
|
|
633
714
|
}
|
|
634
715
|
});
|
|
635
|
-
test('linked worktree roots declaring different namespaces block the corpus', () => {
|
|
716
|
+
test('linked worktree roots declaring different namespaces block the corpus', async () => {
|
|
636
717
|
const home = fixtureHome('crtr-sys-migrate-worktree-conflict-');
|
|
637
718
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
638
719
|
const main = join(home, 'shared-main');
|
|
639
720
|
const linked = join(home, 'shared-linked');
|
|
640
721
|
try {
|
|
722
|
+
await startMigrateDaemon(home);
|
|
641
723
|
write(join(rootProfile, 'profile.json'), manifest('root', [main, linked].map((path) => ({ path, memory: 'content' }))));
|
|
642
724
|
initRepo(main);
|
|
643
725
|
git(main, 'worktree', 'add', linked, '-b', 'linked');
|
|
@@ -656,10 +738,11 @@ test('linked worktree roots declaring different namespaces block the corpus', ()
|
|
|
656
738
|
assertTreeUnchanged(before, snapshotTree(main));
|
|
657
739
|
}
|
|
658
740
|
finally {
|
|
741
|
+
await stopMigrateDaemon(home);
|
|
659
742
|
rmSync(home, { recursive: true, force: true });
|
|
660
743
|
}
|
|
661
744
|
});
|
|
662
|
-
test('a nested declaration is removed, an exact synthetic index is deleted, and a substantive one is kept', () => {
|
|
745
|
+
test('a nested declaration is removed, an exact synthetic index is deleted, and a substantive one is kept', async () => {
|
|
663
746
|
const home = fixtureHome('crtr-sys-migrate-nested-declarations-');
|
|
664
747
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
665
748
|
const project = join(home, 'nest-repo');
|
|
@@ -668,6 +751,7 @@ test('a nested declaration is removed, an exact synthetic index is deleted, and
|
|
|
668
751
|
const syntheticIndex = join(syntheticOwner, '.crouter', 'memory', 'INDEX.md');
|
|
669
752
|
const substantiveIndex = join(substantiveOwner, '.crouter', 'memory', 'INDEX.md');
|
|
670
753
|
try {
|
|
754
|
+
await startMigrateDaemon(home);
|
|
671
755
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
672
756
|
write(join(project, '.crouter', 'memory', 'INDEX.md'), `---\nnamespace: nest-repo\nkind: knowledge\n---\n# Nest Repo\n`);
|
|
673
757
|
write(syntheticIndex, supersededSyntheticIndex('syn'));
|
|
@@ -684,16 +768,18 @@ test('a nested declaration is removed, an exact synthetic index is deleted, and
|
|
|
684
768
|
assert.equal(migrateJson(home).changed, 0);
|
|
685
769
|
}
|
|
686
770
|
finally {
|
|
771
|
+
await stopMigrateDaemon(home);
|
|
687
772
|
rmSync(home, { recursive: true, force: true });
|
|
688
773
|
}
|
|
689
774
|
});
|
|
690
|
-
test('a rootless repository takes its front door from the one legacy guide that owns it', () => {
|
|
775
|
+
test('a rootless repository takes its front door from the one legacy guide that owns it', async () => {
|
|
691
776
|
const home = fixtureHome('crtr-sys-migrate-front-door-');
|
|
692
777
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
693
778
|
const project = join(home, 'fd-root');
|
|
694
779
|
const guide = join(project, '.crouter', 'memory', 'guide.md');
|
|
695
780
|
const rootIndex = join(project, '.crouter', 'memory', 'INDEX.md');
|
|
696
781
|
try {
|
|
782
|
+
await startMigrateDaemon(home);
|
|
697
783
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
698
784
|
write(guide, `---
|
|
699
785
|
kind: knowledge
|
|
@@ -751,10 +837,11 @@ The authored body, preserved byte for byte.
|
|
|
751
837
|
assertTreeUnchanged(converged, snapshotTree(home));
|
|
752
838
|
}
|
|
753
839
|
finally {
|
|
840
|
+
await stopMigrateDaemon(home);
|
|
754
841
|
rmSync(home, { recursive: true, force: true });
|
|
755
842
|
}
|
|
756
843
|
});
|
|
757
|
-
test('repository-relative ordering prefixes do not block migration and derive canonical owner paths', () => {
|
|
844
|
+
test('repository-relative ordering prefixes do not block migration and derive canonical owner paths', async () => {
|
|
758
845
|
const home = fixtureHome('crtr-sys-migrate-ordering-prefix-');
|
|
759
846
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
760
847
|
const repository = join(home, 'ordered-repository');
|
|
@@ -762,6 +849,7 @@ test('repository-relative ordering prefixes do not block migration and derive ca
|
|
|
762
849
|
const rootIndex = join(repository, '.crouter', 'memory', 'INDEX.md');
|
|
763
850
|
const nestedDoc = join(nestedOwner, '.crouter', 'memory', 'guide.md');
|
|
764
851
|
try {
|
|
852
|
+
await startMigrateDaemon(home);
|
|
765
853
|
initRepo(repository);
|
|
766
854
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: repository, memory: 'content' }]));
|
|
767
855
|
write(rootIndex, '---\nnamespace: acme\nkind: knowledge\n---\n# Repository\n');
|
|
@@ -772,10 +860,11 @@ test('repository-relative ordering prefixes do not block migration and derive ca
|
|
|
772
860
|
assert.equal(prefixRow(output, nestedOwner).effective_prefix, 'acme/api');
|
|
773
861
|
}
|
|
774
862
|
finally {
|
|
863
|
+
await stopMigrateDaemon(home);
|
|
775
864
|
rmSync(home, { recursive: true, force: true });
|
|
776
865
|
}
|
|
777
866
|
});
|
|
778
|
-
test('the legacy front door is found in a nested store of the same repository, and a half-done transfer finishes', () => {
|
|
867
|
+
test('the legacy front door is found in a nested store of the same repository, and a half-done transfer finishes', async () => {
|
|
779
868
|
const home = fixtureHome('crtr-sys-migrate-front-door-nested-');
|
|
780
869
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
781
870
|
const project = join(home, 'fd-nested');
|
|
@@ -784,6 +873,7 @@ test('the legacy front door is found in a nested store of the same repository, a
|
|
|
784
873
|
const guide = join(nestedOwner, '.crouter', 'memory', 'guide.md');
|
|
785
874
|
const legacyNamed = join(nestedOwner, '.crouter', 'memory', 'deep-note.md');
|
|
786
875
|
try {
|
|
876
|
+
await startMigrateDaemon(home);
|
|
787
877
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
788
878
|
write(rootIndex, `---\nnamespace: fd-nested\nkind: knowledge\n---\n# FD Nested\n`);
|
|
789
879
|
write(guide, `---
|
|
@@ -850,10 +940,11 @@ surfaces:
|
|
|
850
940
|
assert.doesNotMatch(readFileSync(guide, 'utf8'), /workspace-open/);
|
|
851
941
|
}
|
|
852
942
|
finally {
|
|
943
|
+
await stopMigrateDaemon(home);
|
|
853
944
|
rmSync(home, { recursive: true, force: true });
|
|
854
945
|
}
|
|
855
946
|
});
|
|
856
|
-
test('two legacy front doors, and a root workspace-open that is not at content, each block the corpus', () => {
|
|
947
|
+
test('two legacy front doors, and a root workspace-open that is not at content, each block the corpus', async () => {
|
|
857
948
|
for (const shape of ['two-leaves', 'root-predicate']) {
|
|
858
949
|
const home = fixtureHome(`crtr-sys-migrate-front-door-${shape}-`);
|
|
859
950
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
@@ -866,6 +957,7 @@ test('two legacy front doors, and a root workspace-open that is not at content,
|
|
|
866
957
|
match: "./**"
|
|
867
958
|
at: content`;
|
|
868
959
|
try {
|
|
960
|
+
await startMigrateDaemon(home);
|
|
869
961
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
870
962
|
if (shape === 'two-leaves') {
|
|
871
963
|
write(rootIndex, `---\nnamespace: fd-blocked\nkind: knowledge\n---\n# FD Blocked\n`);
|
|
@@ -896,16 +988,18 @@ test('two legacy front doors, and a root workspace-open that is not at content,
|
|
|
896
988
|
assertTreeUnchanged(before, snapshotTree(project));
|
|
897
989
|
}
|
|
898
990
|
finally {
|
|
991
|
+
await stopMigrateDaemon(home);
|
|
899
992
|
rmSync(home, { recursive: true, force: true });
|
|
900
993
|
}
|
|
901
994
|
}
|
|
902
995
|
});
|
|
903
|
-
test('a leaf carrying both the legacy front door and a translated route keeps every retained authored byte', () => {
|
|
996
|
+
test('a leaf carrying both the legacy front door and a translated route keeps every retained authored byte', async () => {
|
|
904
997
|
const home = fixtureHome('crtr-sys-migrate-front-door-compose-');
|
|
905
998
|
const rootProfile = join(home, '.crouter', 'profiles', 'root-00000000');
|
|
906
999
|
const project = join(home, 'compose-repo');
|
|
907
1000
|
const workspaceDoc = join(project, '.crouter', 'memory', 'workspace.md');
|
|
908
1001
|
try {
|
|
1002
|
+
await startMigrateDaemon(home);
|
|
909
1003
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
910
1004
|
// Pre-003 identity: nothing declares a namespace, so `topics/*` still names
|
|
911
1005
|
// the store's own documents and must be translated in the same pass that
|
|
@@ -966,15 +1060,17 @@ Body bytes that must survive both transforms.
|
|
|
966
1060
|
assert.equal(migrateJson(home).changed, 0);
|
|
967
1061
|
}
|
|
968
1062
|
finally {
|
|
1063
|
+
await stopMigrateDaemon(home);
|
|
969
1064
|
rmSync(home, { recursive: true, force: true });
|
|
970
1065
|
}
|
|
971
1066
|
});
|
|
972
|
-
test('an unreadable profile manifest blocks forced completion and remains in skipped output', () => {
|
|
1067
|
+
test('an unreadable profile manifest blocks forced completion and remains in skipped output', async () => {
|
|
973
1068
|
const home = fixtureHome('crtr-sys-migrate-unreadable-profile-');
|
|
974
1069
|
const userRoot = join(home, '.crouter');
|
|
975
1070
|
const profileId = 'bad-deadbeef';
|
|
976
1071
|
const profilePath = join(userRoot, 'profiles', profileId, 'profile.json');
|
|
977
1072
|
try {
|
|
1073
|
+
await startMigrateDaemon(home);
|
|
978
1074
|
write(profilePath, '{not json');
|
|
979
1075
|
write(markerPath(home), JSON.stringify(onDiskMigrationIdentity()));
|
|
980
1076
|
const payload = migrateBlocked(home);
|
|
@@ -991,16 +1087,18 @@ test('an unreadable profile manifest blocks forced completion and remains in ski
|
|
|
991
1087
|
assert.equal(existsSync(markerPath(home)), false);
|
|
992
1088
|
}
|
|
993
1089
|
finally {
|
|
1090
|
+
await stopMigrateDaemon(home);
|
|
994
1091
|
rmSync(home, { recursive: true, force: true });
|
|
995
1092
|
}
|
|
996
1093
|
});
|
|
997
|
-
test('sys migrate blocks the whole corpus when one link names different documents per target, and writes nothing', () => {
|
|
1094
|
+
test('sys migrate blocks the whole corpus when one link names different documents per target, and writes nothing', async () => {
|
|
998
1095
|
const home = fixtureHome('crtr-sys-migrate-divergent-');
|
|
999
1096
|
const userRoot = join(home, '.crouter');
|
|
1000
1097
|
const rootProfile = join(userRoot, 'profiles', 'root-00000000');
|
|
1001
1098
|
const alpha = join(home, 'alpha-project');
|
|
1002
1099
|
const beta = join(home, 'beta-project');
|
|
1003
1100
|
try {
|
|
1101
|
+
await startMigrateDaemon(home);
|
|
1004
1102
|
// Already current for the manifest and document lanes: the only thing this
|
|
1005
1103
|
// run could write is the corpus cut, so "nothing was written" is provable
|
|
1006
1104
|
// byte for byte.
|
|
@@ -1045,13 +1143,13 @@ test('sys migrate blocks the whole corpus when one link names different document
|
|
|
1045
1143
|
assert.ok(payload.received.renames.some((row) => row.store_root === store && row.to.startsWith(`${relative(home, project)}/`)), JSON.stringify(payload.received.renames));
|
|
1046
1144
|
}
|
|
1047
1145
|
assert.ok(Array.isArray(payload.received.references));
|
|
1048
|
-
assert.equal(payload.received.node_metadata.available, true);
|
|
1049
1146
|
}
|
|
1050
1147
|
finally {
|
|
1148
|
+
await stopMigrateDaemon(home);
|
|
1051
1149
|
rmSync(home, { recursive: true, force: true });
|
|
1052
1150
|
}
|
|
1053
1151
|
});
|
|
1054
|
-
test('a corpus blocker never claims nothing was written when the earlier lanes already wrote', () => {
|
|
1152
|
+
test('a corpus blocker never claims nothing was written when the earlier lanes already wrote', async () => {
|
|
1055
1153
|
const home = fixtureHome('crtr-sys-migrate-earlier-writes-');
|
|
1056
1154
|
const userRoot = join(home, '.crouter');
|
|
1057
1155
|
const rootProfile = join(userRoot, 'profiles', 'root-00000000');
|
|
@@ -1059,6 +1157,7 @@ test('a corpus blocker never claims nothing was written when the earlier lanes a
|
|
|
1059
1157
|
const beta = join(home, 'beta-project');
|
|
1060
1158
|
const userDoc = join(userRoot, 'memory', 'pointer.md');
|
|
1061
1159
|
try {
|
|
1160
|
+
await startMigrateDaemon(home);
|
|
1062
1161
|
// A PRE-migration manifest and an old-format document, so the manifest and
|
|
1063
1162
|
// convergent lanes both write before the corpus lane plans — and then one
|
|
1064
1163
|
// `[[guide]]` naming a different document per target blocks that lane.
|
|
@@ -1086,10 +1185,11 @@ test('a corpus blocker never claims nothing was written when the earlier lanes a
|
|
|
1086
1185
|
assertTreeUnchanged(projectsBefore, snapshotTree(alpha));
|
|
1087
1186
|
}
|
|
1088
1187
|
finally {
|
|
1188
|
+
await stopMigrateDaemon(home);
|
|
1089
1189
|
rmSync(home, { recursive: true, force: true });
|
|
1090
1190
|
}
|
|
1091
1191
|
});
|
|
1092
|
-
test('a verification failure after both write phases reports the rewrites that are on disk', () => {
|
|
1192
|
+
test('a verification failure after both write phases reports the rewrites that are on disk', async () => {
|
|
1093
1193
|
const home = fixtureHome('crtr-sys-migrate-verification-');
|
|
1094
1194
|
const userRoot = join(home, '.crouter');
|
|
1095
1195
|
const rootProfile = join(userRoot, 'profiles', 'root-00000000');
|
|
@@ -1097,6 +1197,7 @@ test('a verification failure after both write phases reports the rewrites that a
|
|
|
1097
1197
|
const projectIndex = join(project, '.crouter', 'memory', 'INDEX.md');
|
|
1098
1198
|
const strayDoc = join(project, '.crouter', 'memory', 'stray.md');
|
|
1099
1199
|
try {
|
|
1200
|
+
await startMigrateDaemon(home);
|
|
1100
1201
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
1101
1202
|
write(projectIndex, `---\nkind: knowledge\n---\n# Verify Project\n`);
|
|
1102
1203
|
// `namespace:` on a NON-root document: not an identity field this lane
|
|
@@ -1130,22 +1231,24 @@ surfaces:
|
|
|
1130
1231
|
`);
|
|
1131
1232
|
}
|
|
1132
1233
|
finally {
|
|
1234
|
+
await stopMigrateDaemon(home);
|
|
1133
1235
|
rmSync(home, { recursive: true, force: true });
|
|
1134
1236
|
}
|
|
1135
1237
|
});
|
|
1136
|
-
test('a nested store reached only through a node target inherits the ancestor repository declaration', () => {
|
|
1238
|
+
test('a nested store reached only through a node target inherits the ancestor repository declaration', async () => {
|
|
1137
1239
|
const home = fixtureHome('crtr-sys-migrate-node-nested-');
|
|
1138
1240
|
const userRoot = join(home, '.crouter');
|
|
1139
1241
|
const rootProfile = join(userRoot, 'profiles', 'root-00000000');
|
|
1140
1242
|
const nodeId = 'node-bbbb2222';
|
|
1141
|
-
const nodeStore = join(
|
|
1243
|
+
const nodeStore = join(canvasHomeFor(home), 'nodes', nodeId, 'context', 'memory');
|
|
1142
1244
|
const nodeProject = join(home, 'node-cwd-project');
|
|
1143
1245
|
const nestedOwner = join(nodeProject, 'nested');
|
|
1144
1246
|
try {
|
|
1145
|
-
|
|
1146
|
-
|
|
1247
|
+
await startMigrateDaemon(home);
|
|
1248
|
+
seedNodeMemoryTarget(home, { nodeId, cwd: nodeProject, profileId: 'root-00000000' });
|
|
1249
|
+
// No project in any manifest and none above the cwd: the daemon's SQL row
|
|
1250
|
+
// is the ONLY path to this project root.
|
|
1147
1251
|
write(join(rootProfile, 'profile.json'), manifest('root', []));
|
|
1148
|
-
write(join(userRoot, 'canvas', 'nodes', nodeId, 'meta.json'), JSON.stringify({ node_id: nodeId, cwd: nodeProject, profile_id: 'root-00000000', kind: 'developer' }));
|
|
1149
1252
|
write(join(nodeStore, 'note.md'), CURRENT_DOC);
|
|
1150
1253
|
write(join(nodeProject, '.crouter', 'memory', 'INDEX.md'), `---\nkind: knowledge\n---\n# Node Cwd Project\n`);
|
|
1151
1254
|
write(join(nestedOwner, '.crouter', 'memory', 'topic.md'), CURRENT_DOC);
|
|
@@ -1165,16 +1268,18 @@ test('a nested store reached only through a node target inherits the ancestor re
|
|
|
1165
1268
|
assert.equal(output.discovered_targets.some((row) => row.kind === 'project' && row.origin === nestedOwner), true);
|
|
1166
1269
|
}
|
|
1167
1270
|
finally {
|
|
1271
|
+
await stopMigrateDaemon(home);
|
|
1168
1272
|
rmSync(home, { recursive: true, force: true });
|
|
1169
1273
|
}
|
|
1170
1274
|
});
|
|
1171
|
-
test('a memory-read route translates through an INDEX collapse and a root-plus-descendant split', () => {
|
|
1275
|
+
test('a memory-read route translates through an INDEX collapse and a root-plus-descendant split', async () => {
|
|
1172
1276
|
const home = fixtureHome('crtr-sys-migrate-routes-');
|
|
1173
1277
|
const userRoot = join(home, '.crouter');
|
|
1174
1278
|
const rootProfile = join(userRoot, 'profiles', 'root-00000000');
|
|
1175
1279
|
const project = join(home, 'route-project');
|
|
1176
1280
|
const carrier = join(project, '.crouter', 'memory', 'carrier.md');
|
|
1177
1281
|
try {
|
|
1282
|
+
await startMigrateDaemon(home);
|
|
1178
1283
|
write(join(rootProfile, 'profile.json'), manifest('root', [{ path: project, memory: 'content' }]));
|
|
1179
1284
|
write(join(project, '.crouter', 'memory', 'INDEX.md'), `---\nkind: knowledge\n---\n# Route Project\n`);
|
|
1180
1285
|
// `topics/INDEX` collapses onto `route-project/topics`, and `topics/**`
|
|
@@ -1219,6 +1324,7 @@ surfaces:
|
|
|
1219
1324
|
assert.deepEqual(second.references, []);
|
|
1220
1325
|
}
|
|
1221
1326
|
finally {
|
|
1327
|
+
await stopMigrateDaemon(home);
|
|
1222
1328
|
rmSync(home, { recursive: true, force: true });
|
|
1223
1329
|
}
|
|
1224
1330
|
});
|
|
@@ -7,6 +7,8 @@ import { test } from 'node:test';
|
|
|
7
7
|
import assert from 'node:assert/strict';
|
|
8
8
|
import { isNowEligibleFault } from '../node-lifecycle-revive.js';
|
|
9
9
|
import { faultNeedsYou } from '../../core/canvas/status-glyph.js';
|
|
10
|
+
// The gate reads the fault the daemon projected onto the node, so the fixture
|
|
11
|
+
// builds the projected shape, not the wider parse-time one.
|
|
10
12
|
function fault(over) {
|
|
11
13
|
return {
|
|
12
14
|
link: 'pi→provider',
|
|
@@ -2,7 +2,8 @@ import { CrtrClient } from '../api/index.js';
|
|
|
2
2
|
import type { CanvasSource } from '../core/canvas/source.js';
|
|
3
3
|
import type { NodeStatus, SubscriptionRef } from '../core/canvas/types.js';
|
|
4
4
|
import type { Scope } from '../types.js';
|
|
5
|
-
import type { NodeDetailDTO
|
|
5
|
+
import type { NodeDetailDTO } from '../api/dto/nodes.js';
|
|
6
|
+
import type { NodeMeta, NodeRow } from '../core/canvas/types.js';
|
|
6
7
|
/** Rethrow an `ApiError` as the clean structured CLI error agents parse
|
|
7
8
|
* (`core/io` `handle`) — instead of the generic "internal bug" stderr path a
|
|
8
9
|
* raw non-`CrtrError` throw would take. The mapping itself lives in ONE place
|
|
@@ -60,11 +61,11 @@ export declare class ApiCanvasSource implements CanvasSource {
|
|
|
60
61
|
/** Map a 404 from the API to the interface's `null` "not found" contract;
|
|
61
62
|
* re-throw everything else. */
|
|
62
63
|
private orNull;
|
|
63
|
-
getNode(nodeId: string): Promise<
|
|
64
|
-
getRow(nodeId: string): Promise<
|
|
64
|
+
getNode(nodeId: string): Promise<NodeMeta | null>;
|
|
65
|
+
getRow(nodeId: string): Promise<NodeRow | null>;
|
|
65
66
|
listNodes(filter?: {
|
|
66
67
|
status?: NodeStatus | NodeStatus[];
|
|
67
|
-
}): Promise<
|
|
68
|
+
}): Promise<NodeRow[]>;
|
|
68
69
|
subscriptionsOf(subscriber: string): Promise<SubscriptionRef[]>;
|
|
69
70
|
subscribersOf(publisher: string): Promise<SubscriptionRef[]>;
|
|
70
71
|
/** BFS over the active `subscribes_to` edges from `root` (its transitive view),
|
|
@@ -19,12 +19,19 @@ import { join } from 'node:path';
|
|
|
19
19
|
import { CrtrClient, ApiError } from '../api/index.js';
|
|
20
20
|
import { apiErrorToCliError } from '../core/io.js';
|
|
21
21
|
import { autostartDisabled, ensureDaemon } from '../daemon/manage.js';
|
|
22
|
-
import { daemonStartupBlocked } from '../daemon/startup-block-marker.js';
|
|
23
22
|
import { DAEMON_STARTUP_WINDOW_MS } from '../daemon/startup-policy.js';
|
|
24
23
|
import { readState } from '../core/config.js';
|
|
25
24
|
import { resolveRemoteCanvasTarget } from '../core/remote-canvas-target.js';
|
|
26
25
|
import { RemoteCanvasSource } from '../core/canvas/remote-canvas-source.js';
|
|
27
26
|
import { crtrHome } from '../core/canvas/paths.js';
|
|
27
|
+
/** The API projects exactly the fault a node row carries; `api/` simply cannot
|
|
28
|
+
* express the branded `operation_id` (it imports Node built-ins only), so the
|
|
29
|
+
* wire value is asserted back to the row's fault type here rather than
|
|
30
|
+
* reshaped. `broker↔crtrd` is deliberately absent from the wire link union: a
|
|
31
|
+
* stored fault can never carry it. */
|
|
32
|
+
function withRowFault(dto) {
|
|
33
|
+
return { ...dto, fault: (dto.fault ?? null) };
|
|
34
|
+
}
|
|
28
35
|
// Error translation
|
|
29
36
|
/** Rethrow an `ApiError` as the clean structured CLI error agents parse
|
|
30
37
|
* (`core/io` `handle`) — instead of the generic "internal bug" stderr path a
|
|
@@ -127,9 +134,6 @@ export function cliClient(opts) {
|
|
|
127
134
|
// On a cold-start timeout, enrich the bare `daemon_unavailable` with the
|
|
128
135
|
// tail of crtrd's event log instead of discarding it.
|
|
129
136
|
coldStartDiagnostic: readColdStartDiagnostic,
|
|
130
|
-
// A blocked startup is standing: every poll left in the window would report
|
|
131
|
-
// the same thing this already knows, so fail now and carry the repair.
|
|
132
|
-
coldStartAbort: daemonStartupBlocked,
|
|
133
137
|
coldStartPollWindowMs: DAEMON_STARTUP_WINDOW_MS,
|
|
134
138
|
});
|
|
135
139
|
}
|
|
@@ -193,10 +197,12 @@ export class ApiCanvasSource {
|
|
|
193
197
|
}
|
|
194
198
|
}
|
|
195
199
|
async getNode(nodeId) {
|
|
196
|
-
|
|
200
|
+
const detail = await this.orNull(() => this.client.getNode(nodeId));
|
|
201
|
+
return detail === null ? null : withRowFault(detail);
|
|
197
202
|
}
|
|
198
203
|
async getRow(nodeId) {
|
|
199
|
-
|
|
204
|
+
const detail = await this.orNull(() => this.client.getNode(nodeId));
|
|
205
|
+
return detail === null ? null : withRowFault(detail);
|
|
200
206
|
}
|
|
201
207
|
async listNodes(filter) {
|
|
202
208
|
const status = filter?.status;
|
|
@@ -214,7 +220,7 @@ export class ApiCanvasSource {
|
|
|
214
220
|
else {
|
|
215
221
|
rows = await this.client.listNodes();
|
|
216
222
|
}
|
|
217
|
-
return rows;
|
|
223
|
+
return rows.map((row) => withRowFault(row));
|
|
218
224
|
}
|
|
219
225
|
async subscriptionsOf(subscriber) {
|
|
220
226
|
return this.roster().then((index) => index.subscriptions.get(subscriber) ?? []);
|