@north-light/crouter 0.3.318 → 0.3.319
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/README.md +0 -3
- package/dist/api/client.js +2 -912
- package/dist/api/dto/attach.js +0 -13
- package/dist/api/dto/bash-jobs.js +1 -9
- package/dist/api/dto/broker-ops.js +0 -6
- package/dist/api/dto/broker.js +0 -20
- package/dist/api/dto/canvas.js +0 -2
- package/dist/api/dto/chat-inventory.js +0 -11
- package/dist/api/dto/common.js +1 -15
- package/dist/api/dto/config.js +0 -3
- package/dist/api/dto/crons.js +1 -10
- package/dist/api/dto/files.js +0 -7
- package/dist/api/dto/focus.js +0 -10
- package/dist/api/dto/health.js +0 -2
- package/dist/api/dto/human-requests.js +0 -4
- package/dist/api/dto/human.js +0 -4
- package/dist/api/dto/inbox.js +0 -4
- package/dist/api/dto/lifecycle.js +0 -3
- package/dist/api/dto/mail.js +0 -1
- package/dist/api/dto/memory.js +0 -6
- package/dist/api/dto/messages.js +0 -2
- package/dist/api/dto/model-config.js +0 -1
- package/dist/api/dto/modelauth.js +0 -4
- package/dist/api/dto/node-outcomes.js +0 -2
- package/dist/api/dto/nodes.js +0 -3
- package/dist/api/dto/profiles.js +1 -4
- package/dist/api/dto/recovery.js +0 -1
- package/dist/api/dto/reports.js +0 -2
- package/dist/api/dto/review-comments.js +0 -5
- package/dist/api/dto/reviews.js +0 -5
- package/dist/api/dto/subscriptions.js +0 -2
- package/dist/api/dto/worktree.js +0 -6
- package/dist/api/errors.js +1 -40
- package/dist/api/index.js +1 -33
- package/dist/api/plugin-manifest-schema.js +0 -23
- package/dist/api/routes.js +1 -147
- package/dist/build-root.js +1 -198
- package/dist/cli.js +3 -99
- package/dist/clients/attach/ansi-cells.js +1 -137
- package/dist/clients/attach/chrome/bash-jobs.js +1 -31
- package/dist/clients/attach/chrome/canvas-panels.js +1 -194
- package/dist/clients/attach/chrome/completion-bell.js +1 -89
- package/dist/clients/attach/chrome/cron-wait.js +1 -34
- package/dist/clients/attach/chrome/git-info.js +2 -44
- package/dist/clients/attach/chrome/header.js +1 -30
- package/dist/clients/attach/chrome/inbox-strip.js +1 -199
- package/dist/clients/attach/chrome/recap.js +1 -19
- package/dist/clients/attach/chrome/review-wait.js +1 -22
- package/dist/clients/attach/chrome/roster.js +4 -275
- package/dist/clients/attach/chrome/status-line.js +1 -117
- package/dist/clients/attach/chrome/ticket-panel.js +1 -280
- package/dist/clients/attach/chrome/widgets.js +1 -51
- package/dist/clients/attach/command.js +1 -107
- package/dist/clients/attach/config.js +1 -274
- package/dist/clients/attach/input/capabilities.js +1 -104
- package/dist/clients/attach/input/clipboard-image.js +3 -220
- package/dist/clients/attach/input/completion-frecency.js +1 -141
- package/dist/clients/attach/input/controller.js +7 -377
- package/dist/clients/attach/input/overlay-owner.js +1 -199
- package/dist/clients/attach/input/ref-autocomplete.js +2 -176
- package/dist/clients/attach/input/titled-editor.js +4 -859
- package/dist/clients/attach/overlays/auth.js +2 -271
- package/dist/clients/attach/overlays/dialogs.js +2 -102
- package/dist/clients/attach/overlays/file-review.js +2 -128
- package/dist/clients/attach/overlays/graph.js +1 -661
- package/dist/clients/attach/overlays/help.js +1 -211
- package/dist/clients/attach/overlays/mcp.js +1 -302
- package/dist/clients/attach/overlays/pickers.js +1 -163
- package/dist/clients/attach/render/activity-slot.js +1 -13
- package/dist/clients/attach/render/assistant-message.js +1 -56
- package/dist/clients/attach/render/card-presentation.js +5 -218
- package/dist/clients/attach/render/chat-view.js +5 -1708
- package/dist/clients/attach/render/condensed-history.js +1 -60
- package/dist/clients/attach/render/context-message.js +1 -63
- package/dist/clients/attach/render/crtr-output.js +17 -905
- package/dist/clients/attach/render/diagram.js +7 -111
- package/dist/clients/attach/render/edit-diff.js +5 -304
- package/dist/clients/attach/render/glyph-codepoints.js +1 -42
- package/dist/clients/attach/render/group-activity.js +2 -263
- package/dist/clients/attach/render/group-recap.js +1 -152
- package/dist/clients/attach/render/markdown-source.js +5 -266
- package/dist/clients/attach/render/measured-container.js +1 -322
- package/dist/clients/attach/render/page-block.js +1 -183
- package/dist/clients/attach/render/scroll-animation.js +1 -80
- package/dist/clients/attach/render/tool-calls.js +3 -361
- package/dist/clients/attach/render/transcript-copy.js +2 -81
- package/dist/clients/attach/render/transcript-search.js +1 -152
- package/dist/clients/attach/render/viewport.js +1 -184
- package/dist/clients/attach/session/banner.js +1 -29
- package/dist/clients/attach/session/bindings.js +1 -71
- package/dist/clients/attach/session/chrome-refresh.js +1 -94
- package/dist/clients/attach/session/connection.js +1 -186
- package/dist/clients/attach/session/context.js +0 -16
- package/dist/clients/attach/session/editor-frame.js +1 -142
- package/dist/clients/attach/session/editor-inventory.js +6 -160
- package/dist/clients/attach/session/file-links.js +1 -68
- package/dist/clients/attach/session/focus-events.js +1 -12
- package/dist/clients/attach/session/frame.js +1 -214
- package/dist/clients/attach/session/frames.js +1 -188
- package/dist/clients/attach/session/identity.js +1 -26
- package/dist/clients/attach/session/input-wiring.js +1 -140
- package/dist/clients/attach/session/invariant.js +1 -15
- package/dist/clients/attach/session/keys.js +1 -77
- package/dist/clients/attach/session/layout.js +1 -59
- package/dist/clients/attach/session/mouse.js +1 -78
- package/dist/clients/attach/session/pane-focus.js +1 -42
- package/dist/clients/attach/session/pane-tag.js +1 -112
- package/dist/clients/attach/session/pi-assets.js +1 -24
- package/dist/clients/attach/session/pi-oauth-flows.js +1 -21
- package/dist/clients/attach/session/profile-files.js +1 -228
- package/dist/clients/attach/session/reconnect.js +1 -175
- package/dist/clients/attach/session/selection.js +3 -108
- package/dist/clients/attach/session/state-sync.js +1 -67
- package/dist/clients/attach/session/surface-frame.js +1 -73
- package/dist/clients/attach/session/surface-host.js +1 -255
- package/dist/clients/attach/session/teardown.js +5 -94
- package/dist/clients/attach/session/transcript-search.js +3 -151
- package/dist/clients/attach/session/whip-achievements.js +2 -145
- package/dist/clients/attach/session/whip.js +1 -362
- package/dist/clients/attach/slash/dispatch.js +1 -706
- package/dist/clients/attach/slash/prompt-preview.js +1 -121
- package/dist/clients/attach/viewer.js +441 -441
- package/dist/clients/conversation/projection.js +1 -324
- package/dist/clients/conversation/submit.js +1 -51
- package/dist/clients/inbox/controller.js +1 -701
- package/dist/clients/inbox/dto-adapt.js +1 -93
- package/dist/clients/inbox/layout.js +1 -9
- package/dist/clients/inbox/page-adapter.js +1 -55
- package/dist/clients/inbox/resolve.js +1 -35
- package/dist/clients/inbox/review/anchors.js +1 -89
- package/dist/clients/inbox/review/comments-client.js +1 -98
- package/dist/clients/inbox/review/companion-pane.js +1 -82
- package/dist/clients/inbox/review/document-surface.js +2 -1188
- package/dist/clients/inbox/review/frame.js +1 -216
- package/dist/clients/inbox/review/keys.js +1 -123
- package/dist/clients/inbox/review/launch.js +1 -151
- package/dist/clients/inbox/review/live-source.js +1 -160
- package/dist/clients/inbox/review/nvim.js +1 -44
- package/dist/clients/inbox/review/remap.js +1 -157
- package/dist/clients/inbox/review/review-client.js +1 -123
- package/dist/clients/inbox/review/roundtrip.js +3 -36
- package/dist/clients/inbox/review/state.js +4 -315
- package/dist/clients/inbox/review-adapter.js +1 -43
- package/dist/clients/inbox/surface.js +1 -152
- package/dist/clients/inbox/tui/ansi.js +3 -321
- package/dist/clients/inbox/tui/input.js +5 -392
- package/dist/clients/inbox/tui/keys.js +1 -104
- package/dist/clients/inbox/tui/page-body.js +1 -66
- package/dist/clients/inbox/tui/panel.js +1 -84
- package/dist/clients/inbox/tui/render.js +2 -368
- package/dist/clients/inbox/tui/slots.js +3 -134
- package/dist/clients/inbox/tui/types.js +0 -1
- package/dist/clients/inbox/tui.js +1 -86
- package/dist/clients/surfaces/host.js +0 -1
- package/dist/commands/api-client.js +4 -290
- package/dist/commands/attention.js +1 -215
- package/dist/commands/canvas-browse.js +1 -70
- package/dist/commands/canvas-config.js +2 -192
- package/dist/commands/canvas-history/grep.js +7 -85
- package/dist/commands/canvas-history/read.js +3 -50
- package/dist/commands/canvas-history/search.js +10 -99
- package/dist/commands/canvas-history/shared.js +1 -139
- package/dist/commands/canvas-history/stats.js +6 -68
- package/dist/commands/canvas-history.js +1 -32
- package/dist/commands/canvas-issue.js +14 -149
- package/dist/commands/canvas-prune.js +1 -108
- package/dist/commands/canvas-roster.js +1 -69
- package/dist/commands/canvas-snapshot.js +1 -34
- package/dist/commands/canvas-use.js +1 -61
- package/dist/commands/canvas.js +1 -49
- package/dist/commands/chord.js +1 -241
- package/dist/commands/cron.js +11 -534
- package/dist/commands/dashboard.js +1 -85
- package/dist/commands/human/components.js +3 -77
- package/dist/commands/human/feedback.js +1 -112
- package/dist/commands/human/prompts.js +1 -331
- package/dist/commands/human/queue.js +1 -191
- package/dist/commands/human/request.js +1 -266
- package/dist/commands/human/review.js +1 -288
- package/dist/commands/human/shared.js +1 -67
- package/dist/commands/human.js +4 -60
- package/dist/commands/memory/delete.js +1 -100
- package/dist/commands/memory/edit.js +21 -219
- package/dist/commands/memory/find.js +2 -244
- package/dist/commands/memory/history.js +5 -199
- package/dist/commands/memory/lint.js +1 -107
- package/dist/commands/memory/list.js +1 -142
- package/dist/commands/memory/move.js +1 -223
- package/dist/commands/memory/origin.js +1 -130
- package/dist/commands/memory/read.js +6 -232
- package/dist/commands/memory/shared.js +12 -802
- package/dist/commands/memory/write.js +13 -235
- package/dist/commands/memory.js +1 -30
- package/dist/commands/node/bash.js +5 -245
- package/dist/commands/node/create.js +3 -332
- package/dist/commands/node/inspect.js +12 -300
- package/dist/commands/node/lifecycle.js +2 -453
- package/dist/commands/node/message.js +1 -161
- package/dist/commands/node/outcome.js +4 -134
- package/dist/commands/node/pyramid.js +2 -79
- package/dist/commands/node/subscription.js +1 -78
- package/dist/commands/node/wait.js +7 -163
- package/dist/commands/node-context.js +2 -159
- package/dist/commands/node-inspect-artifacts.js +8 -109
- package/dist/commands/node-lifecycle-revive.js +1 -217
- package/dist/commands/node-snapshot.js +1 -37
- package/dist/commands/node-transcript.js +1 -62
- package/dist/commands/node-worktree.js +1 -138
- package/dist/commands/node.js +1 -29
- package/dist/commands/pkg/browse/actions.js +1 -198
- package/dist/commands/pkg/browse/catalog.js +1 -466
- package/dist/commands/pkg/browse/command-view.js +1 -191
- package/dist/commands/pkg/browse/detail-panel.js +1 -402
- package/dist/commands/pkg/browse/doc-view.js +1 -89
- package/dist/commands/pkg/browse/list-panel.js +2 -168
- package/dist/commands/pkg/browse/model.js +1 -36
- package/dist/commands/pkg/browse/shell.js +1 -640
- package/dist/commands/pkg/browse.js +1 -27
- package/dist/commands/pkg/market-inspect.js +1 -141
- package/dist/commands/pkg/market-manage.js +1 -327
- package/dist/commands/pkg/market.js +1 -14
- package/dist/commands/pkg/plugin-inspect.js +1 -168
- package/dist/commands/pkg/plugin-manage.js +17 -1109
- package/dist/commands/pkg/plugin.js +1 -14
- package/dist/commands/pkg/shared.js +1 -62
- package/dist/commands/pkg.js +1 -21
- package/dist/commands/profile/default.js +1 -139
- package/dist/commands/profile/delete.js +1 -66
- package/dist/commands/profile/env.js +3 -188
- package/dist/commands/profile/kind.js +2 -35
- package/dist/commands/profile/list.js +1 -43
- package/dist/commands/profile/meta.js +1 -67
- package/dist/commands/profile/new.js +1 -115
- package/dist/commands/profile/pause.js +1 -59
- package/dist/commands/profile/project.js +1 -113
- package/dist/commands/profile/rename.js +1 -38
- package/dist/commands/profile/show.js +1 -52
- package/dist/commands/profile.js +1 -35
- package/dist/commands/push.js +9 -265
- package/dist/commands/revive.js +10 -181
- package/dist/commands/surface/node/cycle.js +1 -83
- package/dist/commands/surface/node/focus.js +1 -81
- package/dist/commands/surface/node/id.js +1 -38
- package/dist/commands/surface/node/pin.js +1 -42
- package/dist/commands/surface/node/placement.js +1 -134
- package/dist/commands/surface-edit.js +1 -157
- package/dist/commands/surface-inbox.js +1 -98
- package/dist/commands/surface-inspect.js +1 -39
- package/dist/commands/surface-node.js +1 -19
- package/dist/commands/surface-reload.js +2 -134
- package/dist/commands/surface-tmux-spread.js +1 -214
- package/dist/commands/surface.js +1 -28
- package/dist/commands/sys/branch.js +1 -19
- package/dist/commands/sys/config.js +1 -353
- package/dist/commands/sys/context/admin/actions.js +2 -246
- package/dist/commands/sys/context/admin/detail-panel.js +1 -247
- package/dist/commands/sys/context/admin/docs-panel.js +1 -191
- package/dist/commands/sys/context/admin/list-view.js +1 -183
- package/dist/commands/sys/context/admin/model.js +1 -229
- package/dist/commands/sys/context/admin/rail-panel.js +1 -227
- package/dist/commands/sys/context/admin/read-view.js +2 -194
- package/dist/commands/sys/context/admin/shell.js +1 -910
- package/dist/commands/sys/context/admin.js +2 -126
- package/dist/commands/sys/context/doc.js +3 -197
- package/dist/commands/sys/context/prompt-review.js +11 -291
- package/dist/commands/sys/context/resolve.js +10 -489
- package/dist/commands/sys/context/sysprompt.js +5 -96
- package/dist/commands/sys/context.js +1 -20
- package/dist/commands/sys/daemon.js +1 -313
- package/dist/commands/sys/doctor.js +1 -617
- package/dist/commands/sys/feedback.js +7 -228
- package/dist/commands/sys/logs.js +3 -129
- package/dist/commands/sys/migrate.js +1 -94
- package/dist/commands/sys/panels/broker-limits-panel.js +2 -110
- package/dist/commands/sys/panels/dependencies-panel.js +1 -80
- package/dist/commands/sys/panels/keybindings-panel.js +1 -703
- package/dist/commands/sys/panels/models-panel.js +1 -1133
- package/dist/commands/sys/panels/plugins-panel.js +1 -80
- package/dist/commands/sys/panels/prefs-panel.js +1 -85
- package/dist/commands/sys/panels/profiles-panel.js +1 -601
- package/dist/commands/sys/panels/provider-panel.js +1 -538
- package/dist/commands/sys/settings-shell.js +1 -400
- package/dist/commands/sys/settings.js +1 -46
- package/dist/commands/sys/setup-core.js +6 -579
- package/dist/commands/sys/setup-settings-runner.js +1 -16
- package/dist/commands/sys/setup-wizard.js +1 -279
- package/dist/commands/sys/setup.js +1 -34
- package/dist/commands/sys/shared.js +1 -81
- package/dist/commands/sys/support/prepare.js +3 -239
- package/dist/commands/sys/support/submit.js +6 -524
- package/dist/commands/sys/support.js +1 -18
- package/dist/commands/sys/sync-deps.js +15 -498
- package/dist/commands/sys/sync-project-guidance.js +4 -481
- package/dist/commands/sys/sync-shared.js +1 -49
- package/dist/commands/sys/sync-skills.js +2 -311
- package/dist/commands/sys/sync.js +1 -18
- package/dist/commands/sys/update.js +1 -147
- package/dist/commands/sys/worktrees.js +5 -53
- package/dist/commands/sys.js +1 -18
- package/dist/core/activity-signal.js +2 -38
- package/dist/core/asset-root.js +1 -18
- package/dist/core/auth-file.js +2 -179
- package/dist/core/auth-interaction.js +3 -94
- package/dist/core/auto-update.js +4 -94
- package/dist/core/bash-guard.js +11 -393
- package/dist/core/bash-jobs.js +7 -411
- package/dist/core/bootstrap.js +2 -53
- package/dist/core/broker-client/client.js +1 -184
- package/dist/core/broker-client/index.js +1 -13
- package/dist/core/broker-client/transport-relay.js +1 -157
- package/dist/core/broker-client/transport-socket.js +1 -179
- package/dist/core/broker-client/transport.js +1 -26
- package/dist/core/canvas/attention.js +1 -47
- package/dist/core/canvas/boot-id.js +1 -26
- package/dist/core/canvas/boot.js +1 -186
- package/dist/core/canvas/browse/app.js +3 -919
- package/dist/core/canvas/browse/model.js +1 -477
- package/dist/core/canvas/browse/pins.js +1 -29
- package/dist/core/canvas/browse/render.js +3 -1055
- package/dist/core/canvas/canvas.js +15 -922
- package/dist/core/canvas/crons.js +11 -481
- package/dist/core/canvas/daemon-owner.js +2 -146
- package/dist/core/canvas/db.js +2 -100
- package/dist/core/canvas/deliveries.js +22 -283
- package/dist/core/canvas/delivery-contract.js +1 -8
- package/dist/core/canvas/executions.js +1 -68
- package/dist/core/canvas/extensions.js +1 -83
- package/dist/core/canvas/focuses.js +1 -77
- package/dist/core/canvas/history.js +24 -860
- package/dist/core/canvas/index.js +1 -15
- package/dist/core/canvas/install-id.js +1 -84
- package/dist/core/canvas/labels.js +1 -43
- package/dist/core/canvas/meta-file.js +1 -89
- package/dist/core/canvas/migrations.js +41 -1150
- package/dist/core/canvas/nav-model.js +1 -231
- package/dist/core/canvas/nav-render.js +1 -260
- package/dist/core/canvas/node-order.js +1 -37
- package/dist/core/canvas/node-recap.js +2 -67
- package/dist/core/canvas/node-sql-migration.js +2 -209
- package/dist/core/canvas/paths.js +1 -153
- package/dist/core/canvas/pid.js +4 -683
- package/dist/core/canvas/recovery.js +3 -565
- package/dist/core/canvas/remote-canvas-source.js +1 -288
- package/dist/core/canvas/remote-transport.js +1 -57
- package/dist/core/canvas/render-source.js +10 -635
- package/dist/core/canvas/sessions.js +1 -78
- package/dist/core/canvas/source.js +1 -47
- package/dist/core/canvas/status-glyph.js +1 -132
- package/dist/core/canvas/telemetry.js +1 -35
- package/dist/core/canvas/types.js +1 -6
- package/dist/core/canvas/waits.js +4 -68
- package/dist/core/canvas/worktrees.js +1 -93
- package/dist/core/clipboard-text.js +1 -57
- package/dist/core/command-hooks/artifact.js +1 -145
- package/dist/core/command-hooks/catalog.js +1 -38
- package/dist/core/command-hooks/compose.js +1 -99
- package/dist/core/command-hooks/discovery.js +1 -228
- package/dist/core/command-hooks/help.js +1 -18
- package/dist/core/command-hooks/index.js +1 -7
- package/dist/core/command-hooks/lifecycle-catalog.js +1 -9
- package/dist/core/command-hooks/lifecycle-create.js +1 -51
- package/dist/core/command-hooks/report.js +1 -28
- package/dist/core/command-hooks/schema.js +1 -157
- package/dist/core/command-hooks/transport/exec-invoke.js +1 -276
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -211
- package/dist/core/command-manifests/manifest.js +1 -324
- package/dist/core/command-manifests/registry.js +1 -118
- package/dist/core/command-manifests/schema.js +1 -736
- package/dist/core/command-plugins/bundle.js +1 -261
- package/dist/core/command-plugins/compose.js +1 -65
- package/dist/core/command-plugins/discovery.js +1 -245
- package/dist/core/command-plugins/endpoint.js +1 -48
- package/dist/core/command-plugins/extensions.js +1 -166
- package/dist/core/command-plugins/help-addenda.js +1 -44
- package/dist/core/command-plugins/presence.js +1 -17
- package/dist/core/command-plugins/revalidate.js +2 -152
- package/dist/core/command-plugins/transport/exec-invoke.js +1 -215
- package/dist/core/command-plugins/transport/http-fetch.js +1 -68
- package/dist/core/command-plugins/transport/http-invoke.js +3 -546
- package/dist/core/command.js +10 -739
- package/dist/core/config.js +1 -1059
- package/dist/core/document-lines.js +3 -6
- package/dist/core/env-name.js +1 -9
- package/dist/core/errors.js +1 -52
- package/dist/core/events/emit.js +1 -17
- package/dist/core/events/envelope.js +1 -84
- package/dist/core/events/errors.js +1 -69
- package/dist/core/events/index.js +1 -4
- package/dist/core/events/operation-id.js +1 -24
- package/dist/core/events/read.js +1 -623
- package/dist/core/events/serialize.js +1 -199
- package/dist/core/events/source.js +1 -31
- package/dist/core/events/types.js +1 -11
- package/dist/core/exclusive-lock.js +1 -197
- package/dist/core/fault-classifier.js +1 -96
- package/dist/core/feed/feed.js +7 -202
- package/dist/core/feed/inbox-migrate.js +3 -135
- package/dist/core/feed/inbox.js +10 -122
- package/dist/core/feed/messages.js +6 -212
- package/dist/core/frontmatter.js +1 -35
- package/dist/core/fs-utils.js +3 -202
- package/dist/core/git.js +2 -103
- package/dist/core/help.js +9 -310
- package/dist/core/host-exports/builtins.js +9 -68
- package/dist/core/host-exports/export.js +3 -124
- package/dist/core/human/action-binding.js +1 -40
- package/dist/core/human/answer-text.js +5 -100
- package/dist/core/human/answer.js +1 -119
- package/dist/core/human/claim.js +3 -67
- package/dist/core/human/completion.js +1 -27
- package/dist/core/human/component-docs.js +78 -272
- package/dist/core/human/convention.js +2 -82
- package/dist/core/human/feedback-companion.js +1 -106
- package/dist/core/human/feedback.js +1 -88
- package/dist/core/human/page-authoring.js +1 -19
- package/dist/core/human/page-catalog.js +1 -172
- package/dist/core/human/page-errors.js +1 -7
- package/dist/core/human/page-eval.js +1 -125
- package/dist/core/human/page-html-markdown.js +8 -260
- package/dist/core/human/page-markdown.js +17 -295
- package/dist/core/human/page-schema.js +1 -373
- package/dist/core/human/page-synth.js +8 -27
- package/dist/core/human/page.js +1 -198
- package/dist/core/human/requests.js +15 -466
- package/dist/core/human/review-schema.js +1 -34
- package/dist/core/human/root.js +1 -11
- package/dist/core/human/scan.js +1 -69
- package/dist/core/human/summary.js +1 -5
- package/dist/core/human/tickets.js +1 -171
- package/dist/core/human/types.js +0 -1
- package/dist/core/human/visible-paths.js +1 -77
- package/dist/core/human-actions.js +1 -101
- package/dist/core/inspector/chrome.js +1 -14
- package/dist/core/inspector/contract.js +0 -1
- package/dist/core/inspector/core.js +2 -295
- package/dist/core/inspector/host.js +4 -538
- package/dist/core/inspector/model.js +2 -226
- package/dist/core/inspector/text.js +6 -45
- package/dist/core/inspector/transport.js +1 -36
- package/dist/core/inspector/tui.js +2 -295
- package/dist/core/installed-plugins.js +1 -78
- package/dist/core/io.js +7 -356
- package/dist/core/keybindings/attach-control.js +1 -42
- package/dist/core/keybindings/background-bash.js +1 -33
- package/dist/core/keybindings/catalog.js +1 -256
- package/dist/core/keybindings/inbox.js +1 -25
- package/dist/core/keybindings/index.js +1 -7
- package/dist/core/keybindings/match.js +1 -127
- package/dist/core/keybindings/persistence.js +1 -49
- package/dist/core/keybindings/resolve.js +1 -348
- package/dist/core/keybindings/types.js +0 -1
- package/dist/core/locked-file.js +1 -118
- package/dist/core/log.js +3 -27
- package/dist/core/manifest-recovery.js +1 -72
- package/dist/core/manifest-stale.js +1 -39
- package/dist/core/manifest.js +1 -20
- package/dist/core/memory/doc-link-grammar.js +2 -109
- package/dist/core/memory/extensions.js +1 -221
- package/dist/core/memory/history.js +6 -268
- package/dist/core/memory/identity.js +1 -181
- package/dist/core/memory/inline-ref-grammar.js +1 -98
- package/dist/core/memory/inline-ref-guidance.js +2 -35
- package/dist/core/memory/inline-ref-inventory.js +1 -59
- package/dist/core/memory/lint.js +2 -671
- package/dist/core/memory/project-namespace.js +2 -85
- package/dist/core/memory/repository-association.js +1 -129
- package/dist/core/memory/tree.js +1 -93
- package/dist/core/memory-resolver.js +2 -611
- package/dist/core/model-config.js +1 -107
- package/dist/core/model-routes.js +1 -201
- package/dist/core/nested-stores.js +2 -166
- package/dist/core/output.js +7 -99
- package/dist/core/pagination.js +1 -88
- package/dist/core/plugin-swap-lock.js +1 -31
- package/dist/core/pool-credential-store.js +1 -116
- package/dist/core/predicate.js +1 -191
- package/dist/core/preview-registry.js +2 -411
- package/dist/core/preview-result-path.js +1 -26
- package/dist/core/profiles/default-binding.js +1 -24
- package/dist/core/profiles/deletion-reservation.js +1 -42
- package/dist/core/profiles/env-store.js +2 -162
- package/dist/core/profiles/fuzzy-match.js +1 -92
- package/dist/core/profiles/manifest.js +1 -574
- package/dist/core/profiles/select.js +35 -741
- package/dist/core/profiles/state-block.js +3 -17
- package/dist/core/provider-error-recognition.js +1 -74
- package/dist/core/provider-failure.js +1 -86
- package/dist/core/provider-management.js +1 -22
- package/dist/core/remote-canvas-target.js +1 -30
- package/dist/core/render.js +18 -138
- package/dist/core/resolver.js +1 -111
- package/dist/core/review/birth.js +1 -52
- package/dist/core/review/comments.js +5 -279
- package/dist/core/review/companion.js +1 -215
- package/dist/core/review/document.js +2 -138
- package/dist/core/review/project.js +1 -36
- package/dist/core/review/realize.js +1 -71
- package/dist/core/review/remap.js +4 -141
- package/dist/core/review/signal.js +1 -12
- package/dist/core/review/stage.js +1 -184
- package/dist/core/review/store.js +1 -168
- package/dist/core/review/types.js +1 -23
- package/dist/core/runtime/advertised-command-invocation.js +1 -233
- package/dist/core/runtime/auth-reload.js +1 -67
- package/dist/core/runtime/banner.js +1 -51
- package/dist/core/runtime/bearings-render.js +18 -250
- package/dist/core/runtime/bearings.js +7 -194
- package/dist/core/runtime/bin-contributions.js +2 -186
- package/dist/core/runtime/boot-root.js +1 -107
- package/dist/core/runtime/branded-host.js +2 -264
- package/dist/core/runtime/broker/auth-reload.js +1 -157
- package/dist/core/runtime/broker/client-registry.js +1 -179
- package/dist/core/runtime/broker/daemon-ops.js +1 -88
- package/dist/core/runtime/broker/engine-drive.js +1 -354
- package/dist/core/runtime/broker/engine-routing.js +1 -211
- package/dist/core/runtime/broker/event-projection.js +1 -193
- package/dist/core/runtime/broker/extension-abort.js +1 -36
- package/dist/core/runtime/broker/fault-retry.js +1 -588
- package/dist/core/runtime/broker/frame-client.js +1 -132
- package/dist/core/runtime/broker/frame-dispatch.js +1 -183
- package/dist/core/runtime/broker/frame-engine-control.js +1 -231
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -41
- package/dist/core/runtime/broker/frame-model-query.js +1 -69
- package/dist/core/runtime/broker/frame-read.js +1 -116
- package/dist/core/runtime/broker/frame-replies.js +1 -64
- package/dist/core/runtime/broker/frame-session.js +4 -203
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -13
- package/dist/core/runtime/broker/inbox.js +13 -163
- package/dist/core/runtime/broker/node-named.js +1 -27
- package/dist/core/runtime/broker/read-ops.js +1 -171
- package/dist/core/runtime/broker/rebind.js +1 -318
- package/dist/core/runtime/broker/tool-groups.js +1 -246
- package/dist/core/runtime/broker/turn-admission.js +1 -31
- package/dist/core/runtime/broker/turn-ignition.js +1 -84
- package/dist/core/runtime/broker-cli.js +3 -81
- package/dist/core/runtime/broker-extension-render.js +5 -135
- package/dist/core/runtime/broker-inventory.js +1 -116
- package/dist/core/runtime/broker-persona-guidance.js +4 -154
- package/dist/core/runtime/broker-protocol.js +3 -152
- package/dist/core/runtime/broker-request.js +1 -85
- package/dist/core/runtime/broker-sdk.js +1 -129
- package/dist/core/runtime/broker.js +1 -1214
- package/dist/core/runtime/canvas-extensions.js +1 -96
- package/dist/core/runtime/chat-inventory-rows.js +1 -105
- package/dist/core/runtime/close.js +1 -265
- package/dist/core/runtime/command-expansion.js +9 -104
- package/dist/core/runtime/command-surface.js +1 -117
- package/dist/core/runtime/connectivity.js +1 -73
- package/dist/core/runtime/deliver-live.js +1 -88
- package/dist/core/runtime/fault-recovery.js +1 -83
- package/dist/core/runtime/fault.js +1 -17
- package/dist/core/runtime/fleet.js +1 -58
- package/dist/core/runtime/front-door-env.js +1 -16
- package/dist/core/runtime/front-door.js +7 -183
- package/dist/core/runtime/headless-pi.js +1 -161
- package/dist/core/runtime/host.js +1 -457
- package/dist/core/runtime/interactive-deliver.js +1 -51
- package/dist/core/runtime/invocation.js +0 -10
- package/dist/core/runtime/kickoff.js +30 -327
- package/dist/core/runtime/launch-config-worker.js +1 -12
- package/dist/core/runtime/launch-prompt.js +4 -13
- package/dist/core/runtime/launch-target.js +1 -55
- package/dist/core/runtime/launch.js +1 -483
- package/dist/core/runtime/lifecycle.js +2 -213
- package/dist/core/runtime/managed-provider-cooling.js +1 -62
- package/dist/core/runtime/memory.js +1 -17
- package/dist/core/runtime/model-registry.js +1 -13
- package/dist/core/runtime/model-selection.js +1 -135
- package/dist/core/runtime/model-swap.js +1 -86
- package/dist/core/runtime/naming.js +14 -298
- package/dist/core/runtime/nerd-font.js +2 -127
- package/dist/core/runtime/node-read.js +2 -386
- package/dist/core/runtime/nodes.js +1 -331
- package/dist/core/runtime/outcome-document.js +1 -97
- package/dist/core/runtime/package-health.js +4 -99
- package/dist/core/runtime/persona.js +2 -55
- package/dist/core/runtime/pi-cli.js +1 -65
- package/dist/core/runtime/pi-vendored.js +1 -66
- package/dist/core/runtime/placement-tmux.js +1 -81
- package/dist/core/runtime/placement.js +1 -386
- package/dist/core/runtime/promote.js +1 -174
- package/dist/core/runtime/prospective-inventory-cli.js +3 -61
- package/dist/core/runtime/prospective-inventory.js +2 -88
- package/dist/core/runtime/recap.js +27 -103
- package/dist/core/runtime/recycle.js +1 -190
- package/dist/core/runtime/reopen.js +1 -138
- package/dist/core/runtime/reset.js +1 -245
- package/dist/core/runtime/resume-root.js +10 -290
- package/dist/core/runtime/revive-all.js +1 -107
- package/dist/core/runtime/revive.js +4 -544
- package/dist/core/runtime/roadmap.js +4 -38
- package/dist/core/runtime/session-branch.js +1 -46
- package/dist/core/runtime/session-cycles.js +1 -110
- package/dist/core/runtime/session-list-cache.js +1 -406
- package/dist/core/runtime/session-visibility.js +1 -99
- package/dist/core/runtime/shell-expansion.js +9 -100
- package/dist/core/runtime/situational-context.js +2 -67
- package/dist/core/runtime/situational-live.js +1 -41
- package/dist/core/runtime/spawn-env.js +1 -255
- package/dist/core/runtime/spawn.js +3 -577
- package/dist/core/runtime/stamp/channel.js +1 -76
- package/dist/core/runtime/stamp/protocol.js +1 -113
- package/dist/core/runtime/stop-guard.js +7 -116
- package/dist/core/runtime/stop-signals.js +1 -46
- package/dist/core/runtime/stream-watchdog.js +1 -134
- package/dist/core/runtime/structured-output.js +4 -156
- package/dist/core/runtime/surface-bg.js +1 -85
- package/dist/core/runtime/tmux-bindings.js +4 -730
- package/dist/core/runtime/tmux-chrome.js +1 -5
- package/dist/core/runtime/tmux-driver.js +7 -637
- package/dist/core/runtime/tool-group-summary.js +6 -85
- package/dist/core/runtime/turn-visibility.js +1 -31
- package/dist/core/runtime/view-socket.js +1 -83
- package/dist/core/runtime/warm-pool.js +1 -395
- package/dist/core/scope.js +1 -254
- package/dist/core/scoped-state/db.js +1 -135
- package/dist/core/scoped-state/migrate.js +3 -181
- package/dist/core/scoped-state/paths.js +1 -27
- package/dist/core/scoped-state/profiles.js +1 -62
- package/dist/core/scoped-state/providers.js +1 -8
- package/dist/core/scoped-state/schema.js +3 -16
- package/dist/core/scoped-state/settings.js +1 -82
- package/dist/core/secrets.js +2 -55
- package/dist/core/self-update.js +1 -71
- package/dist/core/session-model/session-state.js +1 -180
- package/dist/core/shell-segments.js +4 -169
- package/dist/core/spawn.js +1 -26
- package/dist/core/stdout-errors.js +1 -14
- package/dist/core/subscription-state.js +3 -193
- package/dist/core/substrate/frontmatter-validation.js +1 -105
- package/dist/core/substrate/gate-explain.js +1 -424
- package/dist/core/substrate/gate.js +1 -26
- package/dist/core/substrate/index.js +1 -30
- package/dist/core/substrate/injected-store.js +1 -249
- package/dist/core/substrate/listings.js +1 -115
- package/dist/core/substrate/on-read-node.js +1 -36
- package/dist/core/substrate/on-read.js +9 -315
- package/dist/core/substrate/plan.js +1 -266
- package/dist/core/substrate/render-node.js +1 -30
- package/dist/core/substrate/render.js +65 -689
- package/dist/core/substrate/schema.js +1 -186
- package/dist/core/substrate/session-cache.js +1 -83
- package/dist/core/substrate/subject-fields.js +1 -35
- package/dist/core/substrate/subject.js +1 -47
- package/dist/core/substrate/surface-match.js +1 -242
- package/dist/core/termrender/code-doc.js +5 -92
- package/dist/core/termrender/display.js +2 -56
- package/dist/core/termrender/termrender.js +14 -719
- package/dist/core/termrender/version.js +1 -1
- package/dist/core/timing.js +2 -94
- package/dist/core/tui/draw.js +2 -378
- package/dist/core/tui/fuzzy.js +1 -38
- package/dist/core/tui/markdown.js +3 -407
- package/dist/core/tui/page-host.js +1 -74
- package/dist/core/tui/panel.js +1 -137
- package/dist/core/tui/terminal.js +2 -100
- package/dist/core/user-settings.js +1 -454
- package/dist/core/wake.js +1 -296
- package/dist/core/worktree-close.js +6 -228
- package/dist/core/worktree-containment.js +3 -48
- package/dist/core/worktree-landing.js +4 -56
- package/dist/core/worktree-mutation-async.js +10 -280
- package/dist/core/worktree-quarantine.js +1 -54
- package/dist/core/worktree-sweep.js +6 -453
- package/dist/core/worktree.js +18 -899
- package/dist/daemon/api/bridge.js +8 -418
- package/dist/daemon/api/handlers/attach.js +1 -65
- package/dist/daemon/api/handlers/bash-jobs.js +2 -91
- package/dist/daemon/api/handlers/broker-ops.js +1 -447
- package/dist/daemon/api/handlers/broker-recovery.js +1 -251
- package/dist/daemon/api/handlers/canvas.js +6 -490
- package/dist/daemon/api/handlers/chat-inventory.js +1 -25
- package/dist/daemon/api/handlers/crons.js +1 -373
- package/dist/daemon/api/handlers/daemon.js +1 -76
- package/dist/daemon/api/handlers/feedback-comments.js +3 -199
- package/dist/daemon/api/handlers/files.js +1 -63
- package/dist/daemon/api/handlers/focus.js +1 -92
- package/dist/daemon/api/handlers/health.js +1 -76
- package/dist/daemon/api/handlers/human-requests.js +1 -379
- package/dist/daemon/api/handlers/human.js +1 -3
- package/dist/daemon/api/handlers/inbox-page.js +1 -89
- package/dist/daemon/api/handlers/inbox.js +1 -301
- package/dist/daemon/api/handlers/memory.js +1 -50
- package/dist/daemon/api/handlers/messages.js +2 -506
- package/dist/daemon/api/handlers/model-config.js +1 -44
- package/dist/daemon/api/handlers/modelauth.js +1 -165
- package/dist/daemon/api/handlers/node-outcomes.js +1 -181
- package/dist/daemon/api/handlers/nodes.js +1 -939
- package/dist/daemon/api/handlers/profiles.js +1 -140
- package/dist/daemon/api/handlers/prospective-chat-inventory.js +1 -59
- package/dist/daemon/api/handlers/reports.js +16 -332
- package/dist/daemon/api/handlers/review-comments.js +1 -465
- package/dist/daemon/api/handlers/reviews.js +1 -200
- package/dist/daemon/api/handlers/subscriptions.js +1 -53
- package/dist/daemon/api/handlers/validate.js +1 -58
- package/dist/daemon/api/handlers/worktree.js +1 -39
- package/dist/daemon/api/map.js +2 -735
- package/dist/daemon/api/router.js +1 -190
- package/dist/daemon/api/server.js +11 -408
- package/dist/daemon/boot-migrations.js +1 -31
- package/dist/daemon/companion-retire.js +1 -34
- package/dist/daemon/control.js +1 -22
- package/dist/daemon/cron/armed-context.js +1 -100
- package/dist/daemon/cron/capture.js +2 -45
- package/dist/daemon/cron/disposition.js +1 -55
- package/dist/daemon/cron/escalation.js +3 -124
- package/dist/daemon/cron/held.js +1 -20
- package/dist/daemon/cron/lease-recovery.js +1 -119
- package/dist/daemon/cron/live-runs.js +1 -23
- package/dist/daemon/cron/passes.js +1 -58
- package/dist/daemon/cron/settle.js +1 -61
- package/dist/daemon/cron/sinks.js +2 -59
- package/dist/daemon/cron-run.js +1 -405
- package/dist/daemon/crtrd-cli.js +1 -23
- package/dist/daemon/crtrd.js +8 -854
- package/dist/daemon/delivery/run-delivery.js +1 -164
- package/dist/daemon/fleet.js +17 -475
- package/dist/daemon/human/finish.js +10 -179
- package/dist/daemon/human/settle.js +1 -89
- package/dist/daemon/human/sweep.js +1 -66
- package/dist/daemon/manage.js +2 -595
- package/dist/daemon/messaging/node-message.js +1 -99
- package/dist/daemon/park-activity.js +1 -30
- package/dist/daemon/park-pending.js +1 -52
- package/dist/daemon/pidfile.js +1 -37
- package/dist/daemon/profile-delete.js +1 -306
- package/dist/daemon/reconcilers/bash-deadline.js +1 -80
- package/dist/daemon/reconcilers/broker-supervision.js +4 -761
- package/dist/daemon/reconcilers/controller-death.js +1 -14
- package/dist/daemon/reconcilers/cron-lane.js +1 -29
- package/dist/daemon/reconcilers/delivery-lane.js +1 -130
- package/dist/daemon/reconcilers/live-obligation.js +1 -87
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -202
- package/dist/daemon/reconcilers/node-deadline.js +1 -82
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -172
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -59
- package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -146
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -11
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -36
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -207
- package/dist/daemon/review/comment-notify.js +2 -109
- package/dist/daemon/review/companion.js +1 -29
- package/dist/daemon/review/deliver.js +3 -8
- package/dist/daemon/review/finish.js +1 -122
- package/dist/daemon/review/sweep.js +1 -18
- package/dist/daemon/startup-policy.js +1 -1
- package/dist/daemon/supervise-cadence.js +1 -6
- package/dist/hook-authoring.js +5 -447
- package/dist/hook-process.js +1 -34
- package/dist/index.js +1 -52
- package/dist/migrations/001-surfaces-frontmatter.js +1 -161
- package/dist/migrations/002-profile-project-memory.js +1 -72
- package/dist/migrations/003-repository-root-memory-identity/front-door.js +11 -231
- package/dist/migrations/003-repository-root-memory-identity/index.js +5 -513
- package/dist/migrations/003-repository-root-memory-identity/references.js +5 -469
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +3 -349
- package/dist/migrations/activation.js +2 -89
- package/dist/migrations/convergent.js +2 -82
- package/dist/migrations/corpus.js +3 -483
- package/dist/migrations/frontmatter-splice.js +8 -176
- package/dist/migrations/profile-manifests.js +2 -70
- package/dist/migrations/registry.js +1 -42
- package/dist/migrations/runner.js +1 -85
- package/dist/migrations/types.js +0 -24
- package/dist/pi-extensions/broker-local.js +2 -106
- package/dist/pi-extensions/canvas-bash-valve.js +7 -461
- package/dist/pi-extensions/canvas-context-intro.js +2 -113
- package/dist/pi-extensions/canvas-doc-substrate.js +9 -178
- package/dist/pi-extensions/canvas-goal-capture.js +1 -83
- package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1010
- package/dist/pi-extensions/canvas-passive-context.js +14 -203
- package/dist/pi-extensions/canvas-preview-result.js +2 -72
- package/dist/pi-extensions/canvas-prompt-scrub.js +2 -54
- package/dist/pi-extensions/canvas-recap.js +11 -405
- package/dist/pi-extensions/canvas-review-boundary.js +3 -63
- package/dist/pi-extensions/canvas-stamp.js +2 -77
- package/dist/pi-extensions/canvas-stophook.js +1 -643
- package/dist/pi-extensions/canvas-structured-output.js +13 -35
- package/dist/pi-extensions/canvas-tool-guide.js +9 -78
- package/dist/pi-extensions/envelope-merge.js +8 -29
- package/dist/prompts/review.js +20 -42
- package/dist/shared/birth-announcement.js +1 -25
- package/dist/shared/crtr-version.js +1 -18
- package/dist/shared/env.js +1 -214
- package/dist/shared/generated-context.js +11 -226
- package/dist/shared/predicates.js +1 -4
- package/dist/shared/shell-quote.js +1 -5
- package/dist/shared/tool-groups.js +1 -64
- package/dist/shared/working-activity.js +1 -27
- package/dist/suppress-experimental-warnings.js +1 -15
- package/dist/types.js +1 -185
- package/docs/public-api.md +10 -9
- package/package.json +5 -4
- package/runtime.lock.json +5 -5
- package/dist/api/__tests__/integration/client.test.d.ts +0 -1
- package/dist/api/__tests__/integration/client.test.js +0 -163
- package/dist/builtin-pi-packages/pi-crtr-extensions/__tests__/insights-active-init.test.ts +0 -98
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +0 -93
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +0 -2530
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +0 -11
- package/dist/clients/__tests__/helpers/human-daemon.js +0 -60
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +0 -97
- package/dist/clients/attach/__tests__/bash-call-width.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/bash-call-width.test.js +0 -38
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +0 -175
- package/dist/clients/attach/__tests__/completion-frecency.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/completion-frecency.test.js +0 -35
- package/dist/clients/attach/__tests__/context-message.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/context-message.test.js +0 -130
- package/dist/clients/attach/__tests__/crtr-output.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/crtr-output.test.js +0 -68
- package/dist/clients/attach/__tests__/diagram.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/diagram.test.js +0 -42
- package/dist/clients/attach/__tests__/edit-diff.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -31
- package/dist/clients/attach/__tests__/frame-selection.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/frame-selection.test.js +0 -84
- package/dist/clients/attach/__tests__/group-activity.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +0 -165
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +0 -83
- package/dist/clients/attach/__tests__/pane-tag-successor.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/pane-tag-successor.test.js +0 -56
- package/dist/clients/attach/__tests__/profile-files.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/profile-files.test.js +0 -21
- package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/prompt-preview.test.js +0 -21
- package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +0 -64
- package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/titled-editor-paste.test.js +0 -114
- package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +0 -83
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +0 -81
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +0 -135
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +0 -66
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +0 -35
- package/dist/clients/inbox/review/__tests__/review-core.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/review-core.test.js +0 -52
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +0 -100
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +0 -1
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +0 -69
- package/dist/commands/__tests__/human.test.d.ts +0 -1
- package/dist/commands/__tests__/human.test.js +0 -172
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.d.ts +0 -1
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +0 -237
- package/dist/commands/__tests__/integration/migrate.test.d.ts +0 -1
- package/dist/commands/__tests__/integration/migrate.test.js +0 -1330
- package/dist/commands/__tests__/node-message.test.d.ts +0 -1
- package/dist/commands/__tests__/node-message.test.js +0 -112
- package/dist/commands/__tests__/node-new.test.d.ts +0 -1
- package/dist/commands/__tests__/node-new.test.js +0 -58
- package/dist/commands/__tests__/revive-now-gate.test.d.ts +0 -1
- package/dist/commands/__tests__/revive-now-gate.test.js +0 -62
- package/dist/commands/__tests__/seam/daemon-status.test.d.ts +0 -1
- package/dist/commands/__tests__/seam/daemon-status.test.js +0 -29
- package/dist/commands/__tests__/surface-reload-target.test.d.ts +0 -1
- package/dist/commands/__tests__/surface-reload-target.test.js +0 -21
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +0 -379
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +0 -124
- package/dist/commands/memory/__tests__/repository-root-lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +0 -148
- package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +0 -114
- package/dist/commands/sys/__tests__/setup-core.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-core.test.js +0 -45
- package/dist/commands/sys/__tests__/sync-project-guidance.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +0 -244
- package/dist/core/__tests__/bash-guard.test.d.ts +0 -1
- package/dist/core/__tests__/bash-guard.test.js +0 -190
- package/dist/core/__tests__/boot-fault-attempt.test.d.ts +0 -1
- package/dist/core/__tests__/boot-fault-attempt.test.js +0 -105
- package/dist/core/__tests__/boot.test.d.ts +0 -1
- package/dist/core/__tests__/boot.test.js +0 -274
- package/dist/core/__tests__/branded-host-concurrency.test.d.ts +0 -1
- package/dist/core/__tests__/branded-host-concurrency.test.js +0 -72
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +0 -75
- package/dist/core/__tests__/broker-launch-candidates.test.d.ts +0 -1
- package/dist/core/__tests__/broker-launch-candidates.test.js +0 -311
- package/dist/core/__tests__/broker-preflight.test.d.ts +0 -1
- package/dist/core/__tests__/broker-preflight.test.js +0 -95
- package/dist/core/__tests__/broker-stream-watchdog-floor.test.d.ts +0 -1
- package/dist/core/__tests__/broker-stream-watchdog-floor.test.js +0 -82
- package/dist/core/__tests__/broker-turn-admission.test.d.ts +0 -1
- package/dist/core/__tests__/broker-turn-admission.test.js +0 -44
- package/dist/core/__tests__/canvas-db-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-db-boundary.test.js +0 -46
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +0 -710
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +0 -310
- package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +0 -397
- package/dist/core/__tests__/canvas.test.d.ts +0 -1
- package/dist/core/__tests__/canvas.test.js +0 -138
- package/dist/core/__tests__/child-death-wake.test.d.ts +0 -1
- package/dist/core/__tests__/child-death-wake.test.js +0 -153
- package/dist/core/__tests__/cli-help-contract.test.d.ts +0 -1
- package/dist/core/__tests__/cli-help-contract.test.js +0 -152
- package/dist/core/__tests__/close.test.d.ts +0 -1
- package/dist/core/__tests__/close.test.js +0 -284
- package/dist/core/__tests__/collectible.test.d.ts +0 -1
- package/dist/core/__tests__/collectible.test.js +0 -89
- package/dist/core/__tests__/config-change-delta.test.d.ts +0 -1
- package/dist/core/__tests__/config-change-delta.test.js +0 -108
- package/dist/core/__tests__/context-intro.test.d.ts +0 -1
- package/dist/core/__tests__/context-intro.test.js +0 -123
- package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +0 -1
- package/dist/core/__tests__/cron-armed-context-failure.test.js +0 -150
- package/dist/core/__tests__/cron-held-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/cron-held-settlement.test.js +0 -240
- package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +0 -1
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +0 -166
- package/dist/core/__tests__/cron-self-cancel-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +0 -84
- package/dist/core/__tests__/cron-timeout-descendants.test.d.ts +0 -1
- package/dist/core/__tests__/cron-timeout-descendants.test.js +0 -114
- package/dist/core/__tests__/daemon-boot.test.d.ts +0 -1
- package/dist/core/__tests__/daemon-boot.test.js +0 -422
- package/dist/core/__tests__/daemon-wedge.test.d.ts +0 -1
- package/dist/core/__tests__/daemon-wedge.test.js +0 -106
- package/dist/core/__tests__/dead-node-policy-table.test.d.ts +0 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +0 -77
- package/dist/core/__tests__/events-contract.test.d.ts +0 -1
- package/dist/core/__tests__/events-contract.test.js +0 -76
- package/dist/core/__tests__/extension-abort.test.d.ts +0 -1
- package/dist/core/__tests__/extension-abort.test.js +0 -21
- package/dist/core/__tests__/fault-classifier.test.d.ts +0 -1
- package/dist/core/__tests__/fault-classifier.test.js +0 -138
- package/dist/core/__tests__/fixtures/api-server-host.d.ts +0 -1
- package/dist/core/__tests__/fixtures/api-server-host.js +0 -47
- package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +0 -2
- package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +0 -34
- package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +0 -2
- package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +0 -32
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +0 -347
- package/dist/core/__tests__/fixtures/fake-engine.js +0 -1509
- package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +0 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +0 -311
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +0 -1
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +0 -75
- package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +0 -1
- package/dist/core/__tests__/fixtures/metadata-migration-race.js +0 -49
- package/dist/core/__tests__/focuses.test.d.ts +0 -1
- package/dist/core/__tests__/focuses.test.js +0 -113
- package/dist/core/__tests__/fs-utils.test.d.ts +0 -1
- package/dist/core/__tests__/fs-utils.test.js +0 -50
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -43
- package/dist/core/__tests__/helpers/broker-clients.js +0 -174
- package/dist/core/__tests__/helpers/fleet.d.ts +0 -12
- package/dist/core/__tests__/helpers/fleet.js +0 -50
- package/dist/core/__tests__/helpers/harness.d.ts +0 -124
- package/dist/core/__tests__/helpers/harness.js +0 -806
- package/dist/core/__tests__/helpers/viewer-panes.d.ts +0 -12
- package/dist/core/__tests__/helpers/viewer-panes.js +0 -133
- package/dist/core/__tests__/history-inbox.test.d.ts +0 -1
- package/dist/core/__tests__/history-inbox.test.js +0 -121
- package/dist/core/__tests__/human-action-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/human-action-delivery.test.js +0 -162
- package/dist/core/__tests__/human-actions.test.d.ts +0 -1
- package/dist/core/__tests__/human-actions.test.js +0 -120
- package/dist/core/__tests__/inline-memory-refs.test.d.ts +0 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +0 -225
- package/dist/core/__tests__/integration/broker-fork-seam.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -193
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +0 -750
- package/dist/core/__tests__/integration/broker-snapshot-history.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +0 -288
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +0 -103
- package/dist/core/__tests__/integration/command-plugins.test.d.ts +0 -1
- package/dist/core/__tests__/integration/command-plugins.test.js +0 -1200
- package/dist/core/__tests__/integration/deferred-no-wake.test.d.ts +0 -1
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -610
- package/dist/core/__tests__/integration/flagship-lifecycle.test.d.ts +0 -1
- package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -264
- package/dist/core/__tests__/integration/fresh-home-commands.test.d.ts +0 -1
- package/dist/core/__tests__/integration/fresh-home-commands.test.js +0 -49
- package/dist/core/__tests__/integration/git-optional-locks.test.d.ts +0 -1
- package/dist/core/__tests__/integration/git-optional-locks.test.js +0 -81
- package/dist/core/__tests__/integration/host-teardown-process-group.test.d.ts +0 -1
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +0 -480
- package/dist/core/__tests__/integration/lifecycle-hooks.test.d.ts +0 -1
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +0 -498
- package/dist/core/__tests__/integration/live-mutation-verbs.test.d.ts +0 -1
- package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -180
- package/dist/core/__tests__/integration/live-mutation.test.d.ts +0 -1
- package/dist/core/__tests__/integration/live-mutation.test.js +0 -173
- package/dist/core/__tests__/integration/plugin-revalidate.test.d.ts +0 -1
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +0 -359
- package/dist/core/__tests__/integration/profile-pause.test.d.ts +0 -1
- package/dist/core/__tests__/integration/profile-pause.test.js +0 -115
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +0 -1
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +0 -151
- package/dist/core/__tests__/integration/revive.test.d.ts +0 -1
- package/dist/core/__tests__/integration/revive.test.js +0 -615
- package/dist/core/__tests__/integration/spawn-root.test.d.ts +0 -1
- package/dist/core/__tests__/integration/spawn-root.test.js +0 -536
- package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -132
- package/dist/core/__tests__/integration/tmux-surface.test.d.ts +0 -1
- package/dist/core/__tests__/integration/tmux-surface.test.js +0 -330
- package/dist/core/__tests__/integration/worktree-land.test.d.ts +0 -1
- package/dist/core/__tests__/integration/worktree-land.test.js +0 -607
- package/dist/core/__tests__/integration/worktree-reap.test.d.ts +0 -1
- package/dist/core/__tests__/integration/worktree-reap.test.js +0 -842
- package/dist/core/__tests__/kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/kickoff.test.js +0 -196
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.d.ts +0 -1
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +0 -62
- package/dist/core/__tests__/lifecycle.test.d.ts +0 -1
- package/dist/core/__tests__/lifecycle.test.js +0 -176
- package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +0 -63
- package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +0 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +0 -228
- package/dist/core/__tests__/migration.test.d.ts +0 -1
- package/dist/core/__tests__/migration.test.js +0 -946
- package/dist/core/__tests__/model-pin-durability.test.d.ts +0 -1
- package/dist/core/__tests__/model-pin-durability.test.js +0 -195
- package/dist/core/__tests__/model-routes-config.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes-config.test.js +0 -150
- package/dist/core/__tests__/nested-store-discovery.test.d.ts +0 -1
- package/dist/core/__tests__/nested-store-discovery.test.js +0 -89
- package/dist/core/__tests__/node-outcome.test.d.ts +0 -1
- package/dist/core/__tests__/node-outcome.test.js +0 -246
- package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +0 -66
- package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +0 -132
- package/dist/core/__tests__/on-read-nested-store.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +0 -135
- package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +0 -1
- package/dist/core/__tests__/parse-argv-stdin-secret.test.js +0 -68
- package/dist/core/__tests__/passive-subscription.test.d.ts +0 -1
- package/dist/core/__tests__/passive-subscription.test.js +0 -120
- package/dist/core/__tests__/pid-identity-match.test.d.ts +0 -1
- package/dist/core/__tests__/pid-identity-match.test.js +0 -145
- package/dist/core/__tests__/pid-zombie.test.d.ts +0 -1
- package/dist/core/__tests__/pid-zombie.test.js +0 -42
- package/dist/core/__tests__/plugin-kinds.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-kinds.test.js +0 -182
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +0 -43
- package/dist/core/__tests__/plugin-page-components.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-page-components.test.js +0 -159
- package/dist/core/__tests__/preview-mirror-cap.test.d.ts +0 -1
- package/dist/core/__tests__/preview-mirror-cap.test.js +0 -53
- package/dist/core/__tests__/preview-registry-sync.test.d.ts +0 -1
- package/dist/core/__tests__/preview-registry-sync.test.js +0 -107
- package/dist/core/__tests__/profile-project-memory-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +0 -644
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +0 -1
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +0 -91
- package/dist/core/__tests__/prune.test.d.ts +0 -1
- package/dist/core/__tests__/prune.test.js +0 -243
- package/dist/core/__tests__/push-final-guard.test.d.ts +0 -1
- package/dist/core/__tests__/push-final-guard.test.js +0 -191
- package/dist/core/__tests__/relaunch-root.test.d.ts +0 -1
- package/dist/core/__tests__/relaunch-root.test.js +0 -249
- package/dist/core/__tests__/remote-canvas-target.test.d.ts +0 -1
- package/dist/core/__tests__/remote-canvas-target.test.js +0 -93
- package/dist/core/__tests__/repository-association.test.d.ts +0 -1
- package/dist/core/__tests__/repository-association.test.js +0 -153
- package/dist/core/__tests__/repository-root-identity.test.d.ts +0 -1
- package/dist/core/__tests__/repository-root-identity.test.js +0 -223
- package/dist/core/__tests__/respawn-throttle.test.d.ts +0 -1
- package/dist/core/__tests__/respawn-throttle.test.js +0 -20
- package/dist/core/__tests__/review-model-floor.test.d.ts +0 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -83
- package/dist/core/__tests__/revive-all.test.d.ts +0 -1
- package/dist/core/__tests__/revive-all.test.js +0 -157
- package/dist/core/__tests__/revive-capacity.test.d.ts +0 -1
- package/dist/core/__tests__/revive-capacity.test.js +0 -184
- package/dist/core/__tests__/revive-parked-fresh.test.d.ts +0 -1
- package/dist/core/__tests__/revive-parked-fresh.test.js +0 -176
- package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +0 -1
- package/dist/core/__tests__/scope-crouter-home-fence.test.js +0 -55
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -262
- package/dist/core/__tests__/seam/broker-attach-stream.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -176
- package/dist/core/__tests__/seam/broker-cap-freeze.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +0 -155
- package/dist/core/__tests__/seam/broker-crash-teardown.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -131
- package/dist/core/__tests__/seam/broker-pane-resolution.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-pane-resolution.test.js +0 -204
- package/dist/core/__tests__/seam/broker-provider-retry.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +0 -686
- package/dist/core/__tests__/seam/broker-startup-diagnostics.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-startup-diagnostics.test.js +0 -82
- package/dist/core/__tests__/seam/broker-whip-interrupt.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-whip-interrupt.test.js +0 -50
- package/dist/core/__tests__/seam/deadline-wake-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/seam/deadline-wake-delivery.test.js +0 -138
- package/dist/core/__tests__/seam/dormancy-release.test.d.ts +0 -1
- package/dist/core/__tests__/seam/dormancy-release.test.js +0 -516
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +0 -65
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.d.ts +0 -1
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +0 -84
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +0 -1
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +0 -160
- package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +0 -177
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +0 -1
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +0 -31
- package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.d.ts +0 -1
- package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.js +0 -60
- package/dist/core/__tests__/seam/self-close-teardown.test.d.ts +0 -1
- package/dist/core/__tests__/seam/self-close-teardown.test.js +0 -49
- package/dist/core/__tests__/seam/yield-refresh-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/seam/yield-refresh-transaction.test.js +0 -100
- package/dist/core/__tests__/secrets.test.d.ts +0 -1
- package/dist/core/__tests__/secrets.test.js +0 -49
- package/dist/core/__tests__/self-update.test.d.ts +0 -1
- package/dist/core/__tests__/self-update.test.js +0 -46
- package/dist/core/__tests__/session-branch.test.d.ts +0 -1
- package/dist/core/__tests__/session-branch.test.js +0 -61
- package/dist/core/__tests__/session-cycles.test.d.ts +0 -1
- package/dist/core/__tests__/session-cycles.test.js +0 -133
- package/dist/core/__tests__/session-model.test.d.ts +0 -1
- package/dist/core/__tests__/session-model.test.js +0 -111
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +0 -71
- package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +0 -1
- package/dist/core/__tests__/stdin-body-no-discard.test.js +0 -33
- package/dist/core/__tests__/stdout-errors.test.d.ts +0 -1
- package/dist/core/__tests__/stdout-errors.test.js +0 -16
- package/dist/core/__tests__/stop-guard.test.d.ts +0 -1
- package/dist/core/__tests__/stop-guard.test.js +0 -237
- package/dist/core/__tests__/stream-watchdog.test.d.ts +0 -1
- package/dist/core/__tests__/stream-watchdog.test.js +0 -154
- package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +0 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +0 -95
- package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/tmux-driver-boundary.test.js +0 -50
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +0 -54
- package/dist/core/__tests__/worktree-landing.test.d.ts +0 -1
- package/dist/core/__tests__/worktree-landing.test.js +0 -11
- package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +0 -1
- package/dist/core/__tests__/yield-ensures-daemon.test.js +0 -55
- package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +0 -1
- package/dist/core/broker-client/__tests__/transport-relay.test.js +0 -214
- package/dist/core/broker-client/__tests__/transport-socket.test.d.ts +0 -1
- package/dist/core/broker-client/__tests__/transport-socket.test.js +0 -73
- package/dist/core/canvas/__tests__/attention.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/attention.test.js +0 -83
- package/dist/core/canvas/__tests__/history-transcript.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/history-transcript.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +0 -328
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-transport.test.js +0 -97
- package/dist/core/canvas/__tests__/render-remote.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/render-remote.test.js +0 -243
- package/dist/core/canvas/__tests__/session-window.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/session-window.test.js +0 -70
- package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +0 -1
- package/dist/core/feed/__tests__/inbox-migrate.test.js +0 -49
- package/dist/core/human/__tests__/page-catalog.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-catalog.test.js +0 -20
- package/dist/core/human/__tests__/page-html-markdown.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-html-markdown.test.js +0 -48
- package/dist/core/human/__tests__/page.test.d.ts +0 -1
- package/dist/core/human/__tests__/page.test.js +0 -92
- package/dist/core/keybindings/__tests__/resolve.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/resolve.test.js +0 -171
- package/dist/core/profiles/__tests__/env-store.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +0 -99
- package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/fuzzy-match.test.js +0 -51
- package/dist/core/profiles/__tests__/root-profile.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/root-profile.test.js +0 -59
- package/dist/core/review/__tests__/capture-origin.test.d.ts +0 -1
- package/dist/core/review/__tests__/capture-origin.test.js +0 -150
- package/dist/core/review/__tests__/comments.test.d.ts +0 -1
- package/dist/core/review/__tests__/comments.test.js +0 -116
- package/dist/core/review/__tests__/remap.test.d.ts +0 -1
- package/dist/core/review/__tests__/remap.test.js +0 -177
- package/dist/core/review/__tests__/stage-identity.test.d.ts +0 -1
- package/dist/core/review/__tests__/stage-identity.test.js +0 -150
- package/dist/core/runtime/__tests__/engine-route.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +0 -36
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +0 -45
- package/dist/core/runtime/__tests__/node-env.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/node-env.test.js +0 -73
- package/dist/core/runtime/__tests__/spawn-env.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-env.test.js +0 -259
- package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-command.test.js +0 -89
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +0 -28
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +0 -92
- package/dist/daemon/__tests__/autostart-storm.test.d.ts +0 -1
- package/dist/daemon/__tests__/autostart-storm.test.js +0 -128
- package/dist/daemon/__tests__/broker-ownership.test.d.ts +0 -1
- package/dist/daemon/__tests__/broker-ownership.test.js +0 -25
- package/dist/daemon/__tests__/daemon-ownership.test.d.ts +0 -1
- package/dist/daemon/__tests__/daemon-ownership.test.js +0 -27
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +0 -30
- package/dist/daemon/__tests__/helpers/source-daemon.js +0 -176
- package/dist/daemon/__tests__/integration/api-startup-readiness.test.d.ts +0 -1
- package/dist/daemon/__tests__/integration/api-startup-readiness.test.js +0 -83
- package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +0 -1
- package/dist/daemon/__tests__/integration/migration-startup.test.js +0 -127
- package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-deadline-lane.test.js +0 -77
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +0 -146
- package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +0 -116
- package/dist/daemon/__tests__/reconciler-signature.test.d.ts +0 -1
- package/dist/daemon/__tests__/reconciler-signature.test.js +0 -37
- package/dist/daemon/__tests__/subtree-filter-freshness.test.d.ts +0 -1
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +0 -63
- package/dist/daemon/__tests__/thaw-order.test.d.ts +0 -1
- package/dist/daemon/__tests__/thaw-order.test.js +0 -55
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +0 -58
- package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +0 -175
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +0 -216
- package/dist/daemon/api/__tests__/error-seam.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/error-seam.test.js +0 -83
- package/dist/daemon/api/__tests__/model-config.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/model-config.test.js +0 -73
- package/dist/daemon/api/__tests__/node-create-description.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/node-create-description.test.js +0 -127
- package/dist/daemon/api/__tests__/node-model-validation.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +0 -183
- package/dist/daemon/api/__tests__/nodes-activity-query.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +0 -99
- package/dist/daemon/api/__tests__/profile-launch-gates.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +0 -172
- package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +0 -95
- package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +0 -260
- package/dist/daemon/api/__tests__/seam/api-server.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/api-server.test.js +0 -442
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +0 -310
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -351
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +0 -159
- package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +0 -372
- package/dist/daemon/api/__tests__/submit-result.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/submit-result.test.js +0 -215
- package/dist/migrations/__tests__/activation-concurrency.test.d.ts +0 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +0 -146
- package/dist/migrations/__tests__/activation.test.d.ts +0 -1
- package/dist/migrations/__tests__/activation.test.js +0 -152
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +0 -1
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +0 -149
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +0 -86
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +0 -364
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +0 -106
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +0 -62
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -432
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +0 -152
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +0 -88
- package/dist/pi-extensions/__tests__/canvas-tool-guide.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-tool-guide.test.js +0 -96
- package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.js +0 -133
- package/dist/pi-extensions/__tests__/pre-command-gate.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +0 -232
- package/dist/shared/__tests__/env-boundary.test.d.ts +0 -1
- package/dist/shared/__tests__/env-boundary.test.js +0 -95
- package/dist/shared/__tests__/generated-context-grammar.test.d.ts +0 -1
- package/dist/shared/__tests__/generated-context-grammar.test.js +0 -80
- package/docs/compat/hearth-crtr-v1.md +0 -179
- package/docs/compat/hearth-crtr-v2.md +0 -177
- package/docs/compat/hearth-crtr-v3.md +0 -176
- package/docs/compat/hearth-crtr-v4.md +0 -182
- package/docs/compat/hearth-crtr-v5.md +0 -169
|
@@ -1,52 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// migration homes. This module owns the v1..vN sequence gated by
|
|
3
|
-
// `PRAGMA user_version`: schema DDL, one-time data backfills, and the
|
|
4
|
-
// journaled on-disk-lane splice (`../../migrations/registry.ts`'s
|
|
5
|
-
// `journaled` entries, appended at the tail of `MIGRATIONS`). A step here
|
|
6
|
-
// runs through the daemon's explicit `migrate()` startup call, exactly once per database,
|
|
7
|
-
// transactionally.
|
|
8
|
-
//
|
|
9
|
-
// The other two homes:
|
|
10
|
-
// - `../../migrations/registry.ts` — the `STATE_MIGRATIONS` registry for
|
|
11
|
-
// on-disk memory documents, profile manifests, and the corpus lane,
|
|
12
|
-
// driven by `crtr sys migrate`. Its registrants may import ONLY
|
|
13
|
-
// fs/frontmatter utilities — never canvas-db or canvas accessors — so
|
|
14
|
-
// the file stays legal in every CLI leaf's import graph. That is why
|
|
15
|
-
// this chain (which reads node meta, queries other tables mid-step, and
|
|
16
|
-
// builds shell commands from canvas data) is NOT a registrant there.
|
|
17
|
-
// - `../../daemon/boot-migrations.ts` — filesystem repairs that run
|
|
18
|
-
// unconditionally at every daemon boot, outside any version gate
|
|
19
|
-
// (idempotent by their own convergence, not `user_version`).
|
|
20
|
-
//
|
|
21
|
-
// `db.ts` itself keeps only connection management (`openDb`/`withCanvasWrite`
|
|
22
|
-
// /`closeDb`) and re-exports `migrate`/`MIGRATIONS` from here so external
|
|
23
|
-
// imports are unaffected by this split.
|
|
24
|
-
import { importNodeSqlAuthority } from './node-sql-migration.js';
|
|
25
|
-
import { migrateRecoveryWitnesses } from './recovery.js';
|
|
26
|
-
import { migrateMessagingState } from './deliveries.js';
|
|
27
|
-
import { migrateHumanRequestsState } from '../human/requests.js';
|
|
28
|
-
import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs';
|
|
29
|
-
import { basename, join, resolve } from 'node:path';
|
|
30
|
-
import { crtrHome, isSafeNodeId, nodesRoot, nodeMetaPath } from './paths.js';
|
|
31
|
-
import { STATE_MIGRATIONS } from '../../migrations/registry.js';
|
|
32
|
-
import { customExtensionPaths } from './extensions.js';
|
|
33
|
-
import { readMetaObject, updateJsonFileDurably, withMetaLock, writeMetaObjectLocked } from './meta-file.js';
|
|
34
|
-
// Schema as a forward-only migration list
|
|
35
|
-
//
|
|
36
|
-
// The schema is the migration list: one place a schema change is expressed,
|
|
37
|
-
// one gate (`PRAGMA user_version`) that applies it. `migrate()` runs every
|
|
38
|
-
// pending step in order and bumps `user_version` after each, so a fresh db and
|
|
39
|
-
// the live fleet (all at `user_version 0`) converge on the same final shape.
|
|
40
|
-
// Migrations are append-only and forward-only — never edit a shipped step. The
|
|
41
|
-
// v36 body below is the sole corrective exception: v0.3.250 shipped a destructive
|
|
42
|
-
// stale-row decision, so v36 is narrowed for databases still below its gate while
|
|
43
|
-
// appended v37 repairs databases that already crossed it. Do not repeat this
|
|
44
|
-
// exception; an appended migration is required unless it would run too late to
|
|
45
|
-
// prevent destruction at an existing version boundary.
|
|
46
|
-
/** v1 — the baseline tables + indexes. `IF NOT EXISTS` makes this a no-op on
|
|
47
|
-
* any existing db (the live fleet already has these tables). */
|
|
48
|
-
function baselineSchema(db) {
|
|
49
|
-
db.exec(`
|
|
1
|
+
var J=Object.defineProperty;var i=(e,n)=>J(e,"name",{value:n,configurable:!0});import{importNodeSqlAuthority as Q}from"./node-sql-migration.js";import{migrateRecoveryWitnesses as V}from"./recovery.js";import{migrateMessagingState as Z}from"./deliveries.js";import{migrateHumanRequestsState as ee}from"../human/requests.js";import{existsSync as A,readFileSync as h,readdirSync as X,realpathSync as ne}from"node:fs";import{basename as te,join as y,resolve as H}from"node:path";import{crtrHome as oe,isSafeNodeId as ie,nodesRoot as S,nodeMetaPath as I}from"./paths.js";import{STATE_MIGRATIONS as re}from"../../migrations/registry.js";import{customExtensionPaths as se}from"./extensions.js";import{readMetaObject as P,updateJsonFileDurably as b,withMetaLock as Te,writeMetaObjectLocked as Ee}from"./meta-file.js";function ae(e){e.exec(`
|
|
50
2
|
CREATE TABLE IF NOT EXISTS nodes (
|
|
51
3
|
node_id TEXT PRIMARY KEY,
|
|
52
4
|
name TEXT NOT NULL,
|
|
@@ -71,97 +23,7 @@ CREATE TABLE IF NOT EXISTS edges (
|
|
|
71
23
|
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(type, to_id);
|
|
72
24
|
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(type, from_id);
|
|
73
25
|
CREATE INDEX IF NOT EXISTS idx_nodes_status ON nodes(status);
|
|
74
|
-
`);
|
|
75
|
-
}
|
|
76
|
-
/** A table's current columns, used to make additive migrations safe to re-run
|
|
77
|
-
* against a partially applied schema. Shared across every table this chain
|
|
78
|
-
* alters in place (`nodes`, `consult_outbox`, `crons`) instead of each step
|
|
79
|
-
* hand-rolling its own `PRAGMA table_info` + `Set` build. */
|
|
80
|
-
function tableColumns(db, table) {
|
|
81
|
-
return new Set(db.prepare(`PRAGMA table_info(${table})`).all().map((r) => r.name));
|
|
82
|
-
}
|
|
83
|
-
function addColumnIfMissing(db, columns, name, ddl) {
|
|
84
|
-
if (columns.has(name))
|
|
85
|
-
return;
|
|
86
|
-
db.exec(ddl);
|
|
87
|
-
columns.add(name);
|
|
88
|
-
}
|
|
89
|
-
/** `nodes`-table convenience alias — every existing call site names it this
|
|
90
|
-
* way, and the table this chain adds columns to most is `nodes`. */
|
|
91
|
-
function nodeColumns(db) {
|
|
92
|
-
return tableColumns(db, 'nodes');
|
|
93
|
-
}
|
|
94
|
-
const addNodeColumnIfMissing = addColumnIfMissing;
|
|
95
|
-
/** v2 — the additive runtime columns: `intent, pi_pid, window, tmux_session`.
|
|
96
|
-
* `status` already lives in the baseline row, so it is NOT re-added here. All
|
|
97
|
-
* four default to NULL; v3 backfills them. */
|
|
98
|
-
function addRuntimeColumns(db) {
|
|
99
|
-
const columns = nodeColumns(db);
|
|
100
|
-
addNodeColumnIfMissing(db, columns, 'intent', `ALTER TABLE nodes ADD COLUMN intent TEXT;`);
|
|
101
|
-
addNodeColumnIfMissing(db, columns, 'pi_pid', `ALTER TABLE nodes ADD COLUMN pi_pid INTEGER;`);
|
|
102
|
-
addNodeColumnIfMissing(db, columns, 'window', `ALTER TABLE nodes ADD COLUMN window TEXT;`);
|
|
103
|
-
addNodeColumnIfMissing(db, columns, 'tmux_session', `ALTER TABLE nodes ADD COLUMN tmux_session TEXT;`);
|
|
104
|
-
}
|
|
105
|
-
/** v3 — DATA backfill. The runtime fields
|
|
106
|
-
* (`intent, pi_pid, window, tmux_session`) become authoritative in the row;
|
|
107
|
-
* copy each existing node's values out of its meta.json into the row columns
|
|
108
|
-
* once, so the version boundary loses no live state. `status` already mirrors
|
|
109
|
-
* the row, so it is not re-copied.
|
|
110
|
-
*
|
|
111
|
-
* LAYERING NOTE — a sanctioned exception: a *data* migration must read
|
|
112
|
-
* meta.json, which db.ts normally would not. Reading it
|
|
113
|
-
* directly here — via paths.ts, a one-time, clearly-labeled boot-time data
|
|
114
|
-
* migration — is the deliberate choice over splitting the `user_version`
|
|
115
|
-
* counter across two modules. Idempotent and gated: it runs exactly once at the
|
|
116
|
-
* v2→v3 boundary. An UPDATE for a node with no row yet hits 0 rows (harmless). */
|
|
117
|
-
function backfillRuntime(db) {
|
|
118
|
-
const root = nodesRoot();
|
|
119
|
-
if (!existsSync(root))
|
|
120
|
-
return;
|
|
121
|
-
const upd = db.prepare('UPDATE nodes SET intent = ?, pi_pid = ?, "window" = ?, tmux_session = ? WHERE node_id = ?');
|
|
122
|
-
for (const id of readdirSync(root)) {
|
|
123
|
-
const p = nodeMetaPath(id);
|
|
124
|
-
if (!existsSync(p))
|
|
125
|
-
continue;
|
|
126
|
-
let meta;
|
|
127
|
-
try {
|
|
128
|
-
meta = JSON.parse(readFileSync(p, 'utf8'));
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
continue; // a single unreadable meta never aborts the migration
|
|
132
|
-
}
|
|
133
|
-
upd.run(meta['intent'] ?? null, meta['pi_pid'] ?? null, meta['window'] ?? null, meta['tmux_session'] ?? null, id);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
/** v4 — edges referential integrity (IRREVERSIBLE table rebuild). Rebuild the
|
|
137
|
-
* `edges` table so `from_id`/`to_id` are FOREIGN KEYs to `nodes(node_id)` with
|
|
138
|
-
* `ON DELETE CASCADE`: after this, deleting a node can NEVER orphan an edge —
|
|
139
|
-
* the schema GCs them, so prune (and any future delete) doesn't have to. The
|
|
140
|
-
* cargo-cult `PRAGMA foreign_keys = ON` (openDb) finally enforces something.
|
|
141
|
-
*
|
|
142
|
-
* GOTCHA — pre-existing orphan edges. Nothing ever deleted a node before this
|
|
143
|
-
* phase, but manual dir removals / failed spawns can have left `edges` whose
|
|
144
|
-
* endpoint has no `nodes` row. Copying those into the FK-constrained table
|
|
145
|
-
* would violate the constraint, so the rebuild runs with `foreign_keys = OFF`
|
|
146
|
-
* (it MUST be toggled in autocommit — a no-op inside a txn) and the
|
|
147
|
-
* INSERT…SELECT FILTERS orphans: only edges whose BOTH endpoints have a row
|
|
148
|
-
* survive. `PRAGMA foreign_key_check` then confirms the rebuilt table is clean,
|
|
149
|
-
* and a row-count assertion guards that every NON-orphan edge is preserved.
|
|
150
|
-
*
|
|
151
|
-
* CRASH-SAFETY — the whole rebuild is one transaction. A throw ROLLs it back to
|
|
152
|
-
* the pre-v4 state (the `edges_new` scratch table and all copies vanish) and
|
|
153
|
-
* `user_version` stays at 3, so the next open re-runs v4 cleanly: no half-state.
|
|
154
|
-
* Even a crash between COMMIT and the version bump is safe — re-running v4 over
|
|
155
|
-
* an already-rebuilt (clean) `edges` is idempotent in effect. */
|
|
156
|
-
function edgesForeignKeyCascade(db) {
|
|
157
|
-
// Degenerate db with no `edges` table (a real db always has it — v1 created it
|
|
158
|
-
// — but a hand-seeded fixture may not). Nothing to rebuild; create the
|
|
159
|
-
// FK-shaped table fresh so the schema still converges, then we're done.
|
|
160
|
-
const hasEdges = db
|
|
161
|
-
.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'edges'")
|
|
162
|
-
.get() !== undefined;
|
|
163
|
-
if (!hasEdges) {
|
|
164
|
-
db.exec(`
|
|
26
|
+
`)}i(ae,"baselineSchema");function w(e,n){return new Set(e.prepare(`PRAGMA table_info(${n})`).all().map(t=>t.name))}i(w,"tableColumns");function Y(e,n,t,o){n.has(t)||(e.exec(o),n.add(t))}i(Y,"addColumnIfMissing");function l(e){return w(e,"nodes")}i(l,"nodeColumns");const a=Y;function de(e){const n=l(e);a(e,n,"intent","ALTER TABLE nodes ADD COLUMN intent TEXT;"),a(e,n,"pi_pid","ALTER TABLE nodes ADD COLUMN pi_pid INTEGER;"),a(e,n,"window","ALTER TABLE nodes ADD COLUMN window TEXT;"),a(e,n,"tmux_session","ALTER TABLE nodes ADD COLUMN tmux_session TEXT;")}i(de,"addRuntimeColumns");function _e(e){const n=S();if(!A(n))return;const t=e.prepare('UPDATE nodes SET intent = ?, pi_pid = ?, "window" = ?, tmux_session = ? WHERE node_id = ?');for(const o of X(n)){const s=I(o);if(!A(s))continue;let T;try{T=JSON.parse(h(s,"utf8"))}catch{continue}t.run(T.intent??null,T.pi_pid??null,T.window??null,T.tmux_session??null,o)}}i(_e,"backfillRuntime");function ce(e){if(!(e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'edges'").get()!==void 0)){e.exec(`
|
|
165
27
|
CREATE TABLE edges (
|
|
166
28
|
type TEXT NOT NULL,
|
|
167
29
|
from_id TEXT NOT NULL,
|
|
@@ -174,21 +36,9 @@ CREATE TABLE edges (
|
|
|
174
36
|
);
|
|
175
37
|
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(type, to_id);
|
|
176
38
|
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(type, from_id);
|
|
177
|
-
`);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
// FK enforcement must be toggled OUTSIDE a transaction (a no-op within one).
|
|
181
|
-
db.exec('PRAGMA foreign_keys = OFF;');
|
|
182
|
-
try {
|
|
183
|
-
// Non-orphan edges that MUST survive the rebuild (both endpoints present).
|
|
184
|
-
const expected = db
|
|
185
|
-
.prepare(`SELECT COUNT(*) AS n FROM edges
|
|
39
|
+
`);return}e.exec("PRAGMA foreign_keys = OFF;");try{const t=e.prepare(`SELECT COUNT(*) AS n FROM edges
|
|
186
40
|
WHERE from_id IN (SELECT node_id FROM nodes)
|
|
187
|
-
AND to_id IN (SELECT node_id FROM nodes)`)
|
|
188
|
-
.get().n;
|
|
189
|
-
db.exec('BEGIN');
|
|
190
|
-
try {
|
|
191
|
-
db.exec(`
|
|
41
|
+
AND to_id IN (SELECT node_id FROM nodes)`).get().n;e.exec("BEGIN");try{e.exec(`
|
|
192
42
|
CREATE TABLE edges_new (
|
|
193
43
|
type TEXT NOT NULL,
|
|
194
44
|
from_id TEXT NOT NULL,
|
|
@@ -207,74 +57,14 @@ DROP TABLE edges;
|
|
|
207
57
|
ALTER TABLE edges_new RENAME TO edges;
|
|
208
58
|
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(type, to_id);
|
|
209
59
|
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(type, from_id);
|
|
210
|
-
`);
|
|
211
|
-
// Row-count assertion: every non-orphan edge preserved across the rebuild.
|
|
212
|
-
const after = db.prepare('SELECT COUNT(*) AS n FROM edges').get().n;
|
|
213
|
-
if (after !== expected) {
|
|
214
|
-
throw new Error(`edges FK rebuild lost rows: expected ${expected} non-orphan edge(s), got ${after}`);
|
|
215
|
-
}
|
|
216
|
-
// Belt-and-suspenders: the rebuilt table must hold no FK violations (the
|
|
217
|
-
// orphan filter above should guarantee this).
|
|
218
|
-
const violations = db.prepare('PRAGMA foreign_key_check').all();
|
|
219
|
-
if (violations.length > 0) {
|
|
220
|
-
throw new Error(`edges FK rebuild left ${violations.length} foreign-key violation(s)`);
|
|
221
|
-
}
|
|
222
|
-
db.exec('COMMIT');
|
|
223
|
-
}
|
|
224
|
-
catch (e) {
|
|
225
|
-
db.exec('ROLLBACK');
|
|
226
|
-
throw e;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
finally {
|
|
230
|
-
db.exec('PRAGMA foreign_keys = ON;');
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
/** v5 — additive runtime column `pane`: LOCATION's authoritative handle, the
|
|
234
|
-
* durable tmux `%pane_id` a node's pane is anchored on. Unlike the derived
|
|
235
|
-
* `window`/`tmux_session` cache (v2), the pane id survives a user
|
|
236
|
-
* `move-pane`/`join-pane`/`break-pane` and window renumbering, so a later step
|
|
237
|
-
* reconciles window/session FROM it and uses pane-existence for liveness.
|
|
238
|
-
* Defaults NULL — nothing reads it until the placement layer lands, so this
|
|
239
|
-
* observes no behavior change. Additive, forward-only. */
|
|
240
|
-
function addPaneColumn(db) {
|
|
241
|
-
const columns = nodeColumns(db);
|
|
242
|
-
addNodeColumnIfMissing(db, columns, 'pane', `ALTER TABLE nodes ADD COLUMN pane TEXT;`);
|
|
243
|
-
}
|
|
244
|
-
/** v6 — the `focuses` table: durable, PLURAL on-screen viewports, one row per
|
|
245
|
-
* viewport (Q7 widens canvas.db from "topology" to "topology + focuses"). Each
|
|
246
|
-
* row is anchored on the durable tmux `%pane_id`; `session` is a derived cache
|
|
247
|
-
* reconciled from the pane; `node_id` is UNIQUE so a node occupies at most one
|
|
248
|
-
* focus (Q5). The focuses table is the CANONICAL focus store — there is no
|
|
249
|
-
* focus.ptr file and no dual-write bridge; placement writes focus rows directly. */
|
|
250
|
-
function addFocusesTable(db) {
|
|
251
|
-
db.exec(`
|
|
60
|
+
`);const o=e.prepare("SELECT COUNT(*) AS n FROM edges").get().n;if(o!==t)throw new Error(`edges FK rebuild lost rows: expected ${t} non-orphan edge(s), got ${o}`);const s=e.prepare("PRAGMA foreign_key_check").all();if(s.length>0)throw new Error(`edges FK rebuild left ${s.length} foreign-key violation(s)`);e.exec("COMMIT")}catch(o){throw e.exec("ROLLBACK"),o}}finally{e.exec("PRAGMA foreign_keys = ON;")}}i(ce,"edgesForeignKeyCascade");function Ne(e){const n=l(e);a(e,n,"pane","ALTER TABLE nodes ADD COLUMN pane TEXT;")}i(Ne,"addPaneColumn");function ue(e){e.exec(`
|
|
252
61
|
CREATE TABLE IF NOT EXISTS focuses (
|
|
253
62
|
focus_id TEXT PRIMARY KEY, -- stable internal id for the viewport
|
|
254
63
|
pane TEXT, -- the durable %pane_id realizing the focus
|
|
255
64
|
session TEXT, -- derived cache of the user session (reconciled from pane)
|
|
256
|
-
node_id TEXT NOT NULL UNIQUE -- the node shown; UNIQUE
|
|
65
|
+
node_id TEXT NOT NULL UNIQUE -- the node shown; UNIQUE \u2192 a node occupies <=1 focus
|
|
257
66
|
);
|
|
258
|
-
`);
|
|
259
|
-
}
|
|
260
|
-
/** v7 — the `wakeups` table: durable store for scheduled wake-ups (the
|
|
261
|
-
* scheduled-wakeups feature). One row per armed wake. `node_id` is the TARGET
|
|
262
|
-
* and the node-anchored cancel anchor — it carries a `ON DELETE CASCADE` FK to
|
|
263
|
-
* `nodes(node_id)` so a pruned/deleted node's node-anchored wakes are reaped in
|
|
264
|
-
* the same transaction (mirroring the edges v4 cascade; works because
|
|
265
|
-
* `PRAGMA foreign_keys = ON` is set at every open). NULL `node_id` = a
|
|
266
|
-
* canvas-detached wake (deferred spawn / spawn-cron) that survives.
|
|
267
|
-
*
|
|
268
|
-
* `owner_id` is the ARMER, set on EVERY row, and is deliberately a PLAIN indexed
|
|
269
|
-
* column with NO FK (design D1/D2): an FK on `owner_id` would cascade-drop a
|
|
270
|
-
* crashed-then-pruned armer's detached cron, violating Invariant E. A detached
|
|
271
|
-
* wake is never reaped by node-row cascade.
|
|
272
|
-
*
|
|
273
|
-
* `fire_at` is an ISO 8601 UTC string for the NEXT occurrence, so the per-tick
|
|
274
|
-
* due query is a lexicographic `<=` compare. The partial unique index
|
|
275
|
-
* `idx_wakeups_deadline` enforces ≤1 deadline per node. Additive, forward-only. */
|
|
276
|
-
function appendWakeupsTable(db) {
|
|
277
|
-
db.exec(`
|
|
67
|
+
`)}i(ue,"addFocusesTable");function le(e){e.exec(`
|
|
278
68
|
CREATE TABLE IF NOT EXISTS wakeups (
|
|
279
69
|
wakeup_id TEXT PRIMARY KEY,
|
|
280
70
|
node_id TEXT, -- TARGET + node-anchored cancel anchor; NULL = canvas-detached
|
|
@@ -290,26 +80,7 @@ CREATE INDEX IF NOT EXISTS idx_wakeups_fire ON wakeups(fire_at);
|
|
|
290
80
|
CREATE INDEX IF NOT EXISTS idx_wakeups_node ON wakeups(node_id); -- by-node cancel / list
|
|
291
81
|
CREATE INDEX IF NOT EXISTS idx_wakeups_owner ON wakeups(owner_id); -- by-owner reap (ruling A)
|
|
292
82
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_wakeups_deadline ON wakeups(node_id) WHERE kind = 'deadline';
|
|
293
|
-
`);
|
|
294
|
-
}
|
|
295
|
-
/** v9 — generalize the `wakeups` table (v7) into the `triggers` table (the
|
|
296
|
-
* unified node-trigger-grammar substrate). The old `kind` axis (bare/noted/
|
|
297
|
-
* deadline/spawn) splits into three orthogonal axes: `action` (what enacts:
|
|
298
|
-
* 'msg'|'new') x `action_mode` (how: 'inbox_message'|'fresh_revive'|
|
|
299
|
-
* 'deadline_message'|'node_birth') x `trigger_type` (when: 'at'|'every'|
|
|
300
|
-
* 'when'|'until') — so a daemon-owned predicate (`--when`) trigger can live in
|
|
301
|
-
* the same table as a clock trigger. Predicate-only columns (`when_script`
|
|
302
|
-
* through `last_stderr`) are additive null/idle for every migrated clock row.
|
|
303
|
-
*
|
|
304
|
-
* Migration mapping, preserving every existing `wakeup_id` as `trigger_id`
|
|
305
|
-
* (so an old wake's id stays cancelable): bare→fresh_revive, noted→
|
|
306
|
-
* inbox_message, deadline→deadline_message (trigger_type='until'), spawn→
|
|
307
|
-
* node_birth. `payload` JSON carries over unchanged — the old per-kind
|
|
308
|
-
* payload shapes (plus SpawnChildOpts) map 1:1 onto the intermediate row, so
|
|
309
|
-
* no JSON transform is needed. The `wakeups` table is then DROPPED — not kept
|
|
310
|
-
* as a parallel table. Additive, forward-only. */
|
|
311
|
-
function migrateWakeupsToTriggers(db) {
|
|
312
|
-
db.exec(`
|
|
83
|
+
`)}i(le,"appendWakeupsTable");function Le(e){e.exec(`
|
|
313
84
|
CREATE TABLE IF NOT EXISTS triggers (
|
|
314
85
|
trigger_id TEXT PRIMARY KEY,
|
|
315
86
|
owner_id TEXT NOT NULL,
|
|
@@ -360,134 +131,12 @@ SELECT
|
|
|
360
131
|
FROM wakeups;
|
|
361
132
|
|
|
362
133
|
DROP TABLE wakeups;
|
|
363
|
-
`);
|
|
364
|
-
}
|
|
365
|
-
/** v8 — additive identity column `host_kind`: which HOST launches + supervises a
|
|
366
|
-
* node — `'tmux'` (a pane) or `'broker'` (the headless in-process engine). It is
|
|
367
|
-
* durable IDENTITY mirrored from meta.json like `cwd` (NOT runtime like `pane`),
|
|
368
|
-
* so it survives an index rebuild via the `IDENTITY_KEYS`/`upsertRow` path.
|
|
369
|
-
* Defaults NULL ⇒ `'tmux'` (every existing node is tmux-hosted); no data
|
|
370
|
-
* backfill. Additive, forward-only. */
|
|
371
|
-
function addHostKindColumn(db) {
|
|
372
|
-
const columns = nodeColumns(db);
|
|
373
|
-
addNodeColumnIfMissing(db, columns, 'host_kind', `ALTER TABLE nodes ADD COLUMN host_kind TEXT;`);
|
|
374
|
-
}
|
|
375
|
-
/** v10 — the `canvas_meta` key/value table: a single durable place for
|
|
376
|
-
* small, cross-process canvas-wide scalars that aren't node rows. First user:
|
|
377
|
-
* the boot marker (boot.ts), which records the last-seen kernel boot identity
|
|
378
|
-
* so boot-liveness reconciliation is a single-writer SQLite transaction on
|
|
379
|
-
* this row rather than a race-prone JSON file. Additive, forward-only. */
|
|
380
|
-
function addCanvasMetaTable(db) {
|
|
381
|
-
db.exec(`
|
|
134
|
+
`)}i(Le,"migrateWakeupsToTriggers");function pe(e){const n=l(e);a(e,n,"host_kind","ALTER TABLE nodes ADD COLUMN host_kind TEXT;")}i(pe,"addHostKindColumn");function Oe(e){e.exec(`
|
|
382
135
|
CREATE TABLE IF NOT EXISTS canvas_meta (
|
|
383
136
|
key TEXT PRIMARY KEY,
|
|
384
137
|
value TEXT NOT NULL
|
|
385
138
|
);
|
|
386
|
-
`);
|
|
387
|
-
}
|
|
388
|
-
/** v11 — additive identity column `profile_id`: the profile-directory id
|
|
389
|
-
* (`<slug>-<id>`) a node runs under, chosen once at spawn (inherited from the
|
|
390
|
-
* spawner, or `--profile`). Durable IDENTITY mirrored from meta.json like
|
|
391
|
-
* `cwd`/`host_kind` (NOT runtime like `pane`), so it survives an index rebuild
|
|
392
|
-
* via the `IDENTITY_KEYS`/`upsertRow` path. Defaults NULL for historical
|
|
393
|
-
* root/no-profile rows; new root conversations use the stable root profile
|
|
394
|
-
* id instead. No data backfill. Additive, forward-only. */
|
|
395
|
-
function addProfileIdColumn(db) {
|
|
396
|
-
const columns = nodeColumns(db);
|
|
397
|
-
addNodeColumnIfMissing(db, columns, 'profile_id', `ALTER TABLE nodes ADD COLUMN profile_id TEXT;`);
|
|
398
|
-
}
|
|
399
|
-
/** v12 — additive runtime column `pi_pid_identity`: the LAUNCH-time process-
|
|
400
|
-
* identity fingerprint (`pid.ts`'s `composeIdentity`) recorded alongside
|
|
401
|
-
* `pi_pid` (v2) by `recordPid`, so `headlessBrokerHost.teardown()` can refuse
|
|
402
|
-
* to signal a `pi_pid` the OS has since recycled for an unrelated process
|
|
403
|
-
* (see `NodeRuntime.pi_pid_identity`).
|
|
404
|
-
* Defaults NULL ⇒ no baseline ⇒ the guard fails open, exactly like a node
|
|
405
|
-
* booted before this column existed. No data backfill: an existing `pi_pid`
|
|
406
|
-
* with no recorded identity simply has no launch-time baseline to compare
|
|
407
|
-
* against. Additive, forward-only. */
|
|
408
|
-
function addPidIdentityColumn(db) {
|
|
409
|
-
const columns = nodeColumns(db);
|
|
410
|
-
addNodeColumnIfMissing(db, columns, 'pi_pid_identity', `ALTER TABLE nodes ADD COLUMN pi_pid_identity TEXT;`);
|
|
411
|
-
}
|
|
412
|
-
/** v13 — mutable controller-message wait state. It belongs with runtime state,
|
|
413
|
-
* not meta identity: both the waiting node and an incoming sender can settle it. */
|
|
414
|
-
function addMessageWaitColumn(db) {
|
|
415
|
-
const columns = nodeColumns(db);
|
|
416
|
-
addNodeColumnIfMissing(db, columns, 'waiting_for', `ALTER TABLE nodes ADD COLUMN waiting_for TEXT;`);
|
|
417
|
-
}
|
|
418
|
-
/** v14 — canonical final identity. Existing done rows receive their newest valid
|
|
419
|
-
* final report once; runtime never infers canonical state from report files. */
|
|
420
|
-
function addCanonicalFinalColumns(db) {
|
|
421
|
-
const columns = nodeColumns(db);
|
|
422
|
-
// Metadata-only migration harnesses can legitimately advance user_version on
|
|
423
|
-
// an otherwise empty database. There is no node index to repair in that case.
|
|
424
|
-
if (columns.size === 0)
|
|
425
|
-
return;
|
|
426
|
-
addNodeColumnIfMissing(db, columns, 'final_report', `ALTER TABLE nodes ADD COLUMN final_report TEXT;`);
|
|
427
|
-
addNodeColumnIfMissing(db, columns, 'finalized_at', `ALTER TABLE nodes ADD COLUMN finalized_at TEXT;`);
|
|
428
|
-
const rows = db.prepare("SELECT node_id FROM nodes WHERE status = 'done' AND final_report IS NULL").all();
|
|
429
|
-
const update = db.prepare('UPDATE nodes SET final_report = ?, finalized_at = ? WHERE node_id = ? AND final_report IS NULL');
|
|
430
|
-
for (const { node_id } of rows) {
|
|
431
|
-
const dir = join(nodesRoot(), node_id, 'reports');
|
|
432
|
-
if (!existsSync(dir))
|
|
433
|
-
continue;
|
|
434
|
-
let winner = null;
|
|
435
|
-
for (const name of readdirSync(dir)) {
|
|
436
|
-
if (!name.endsWith('.md'))
|
|
437
|
-
continue;
|
|
438
|
-
try {
|
|
439
|
-
const raw = readFileSync(join(dir, name), 'utf8');
|
|
440
|
-
const match = /^---\nnode: [^\n]+\nkind: final\nts: ([^\n]+)\n---\n/.exec(raw);
|
|
441
|
-
if (match === null || Number.isNaN(Date.parse(match[1])))
|
|
442
|
-
continue;
|
|
443
|
-
const candidate = { name, ts: match[1] };
|
|
444
|
-
if (winner === null || candidate.ts > winner.ts || (candidate.ts === winner.ts && candidate.name > winner.name))
|
|
445
|
-
winner = candidate;
|
|
446
|
-
}
|
|
447
|
-
catch { /* malformed historical reports are not canonical */ }
|
|
448
|
-
}
|
|
449
|
-
if (winner !== null)
|
|
450
|
-
update.run(winner.name, winner.ts, node_id);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
/** v15 — canonicalize persisted launch metadata after a retired generation-root
|
|
454
|
-
* experiment. Canvas hooks are launch-owned; retain every genuine custom extra. */
|
|
455
|
-
function normalizePersistedLaunchExtensions(_db) {
|
|
456
|
-
const root = nodesRoot();
|
|
457
|
-
if (!existsSync(root))
|
|
458
|
-
return;
|
|
459
|
-
for (const id of readdirSync(root)) {
|
|
460
|
-
const path = nodeMetaPath(id);
|
|
461
|
-
if (!existsSync(path))
|
|
462
|
-
continue;
|
|
463
|
-
updateJsonFileDurably(path, (meta) => {
|
|
464
|
-
const launch = meta['launch'];
|
|
465
|
-
if (typeof launch !== 'object' || launch === null || Array.isArray(launch))
|
|
466
|
-
return false;
|
|
467
|
-
const extensions = launch.extensions;
|
|
468
|
-
if (!Array.isArray(extensions) || !extensions.every((value) => typeof value === 'string'))
|
|
469
|
-
return false;
|
|
470
|
-
const custom = customExtensionPaths(extensions);
|
|
471
|
-
if (custom.length === extensions.length)
|
|
472
|
-
return false;
|
|
473
|
-
launch.extensions = custom;
|
|
474
|
-
return true;
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
/** v17 — monotonically identifies each explicit wait arm. Delivery settlement
|
|
479
|
-
* uses this watermark as well as the controller identity. */
|
|
480
|
-
function addMessageWaitGenerationColumn(db) {
|
|
481
|
-
const columns = nodeColumns(db);
|
|
482
|
-
addNodeColumnIfMissing(db, columns, 'waiting_for_generation', `ALTER TABLE nodes ADD COLUMN waiting_for_generation INTEGER NOT NULL DEFAULT 0;`);
|
|
483
|
-
}
|
|
484
|
-
/** v18 — create the historical `consult_outbox` table. The old schema stays
|
|
485
|
-
* replayable for existing databases until its later migration removes it.
|
|
486
|
-
* No current user-facing flow creates rows. Its remaining diagnostics and
|
|
487
|
-
* retention readers keep armed/pending legacy rows from losing their node
|
|
488
|
-
* before startup or crash reconciliation terminalizes those rows. */
|
|
489
|
-
function addHumanWorkOutboxTable(db) {
|
|
490
|
-
db.exec(`
|
|
139
|
+
`)}i(Oe,"addCanvasMetaTable");function Ae(e){const n=l(e);a(e,n,"profile_id","ALTER TABLE nodes ADD COLUMN profile_id TEXT;")}i(Ae,"addProfileIdColumn");function fe(e){const n=l(e);a(e,n,"pi_pid_identity","ALTER TABLE nodes ADD COLUMN pi_pid_identity TEXT;")}i(fe,"addPidIdentityColumn");function Re(e){const n=l(e);a(e,n,"waiting_for","ALTER TABLE nodes ADD COLUMN waiting_for TEXT;")}i(Re,"addMessageWaitColumn");function $(e){const n=l(e);if(n.size===0)return;a(e,n,"final_report","ALTER TABLE nodes ADD COLUMN final_report TEXT;"),a(e,n,"finalized_at","ALTER TABLE nodes ADD COLUMN finalized_at TEXT;");const t=e.prepare("SELECT node_id FROM nodes WHERE status = 'done' AND final_report IS NULL").all(),o=e.prepare("UPDATE nodes SET final_report = ?, finalized_at = ? WHERE node_id = ? AND final_report IS NULL");for(const{node_id:s}of t){const T=y(S(),s,"reports");if(!A(T))continue;let r=null;for(const E of X(T))if(E.endsWith(".md"))try{const d=h(y(T,E),"utf8"),_=/^---\nnode: [^\n]+\nkind: final\nts: ([^\n]+)\n---\n/.exec(d);if(_===null||Number.isNaN(Date.parse(_[1])))continue;const c={name:E,ts:_[1]};(r===null||c.ts>r.ts||c.ts===r.ts&&c.name>r.name)&&(r=c)}catch{}r!==null&&o.run(r.name,r.ts,s)}}i($,"addCanonicalFinalColumns");function me(e){const n=S();if(A(n))for(const t of X(n)){const o=I(t);A(o)&&b(o,s=>{const T=s.launch;if(typeof T!="object"||T===null||Array.isArray(T))return!1;const r=T.extensions;if(!Array.isArray(r)||!r.every(d=>typeof d=="string"))return!1;const E=se(r);return E.length===r.length?!1:(T.extensions=E,!0)})}}i(me,"normalizePersistedLaunchExtensions");function Ie(e){const n=l(e);a(e,n,"waiting_for_generation","ALTER TABLE nodes ADD COLUMN waiting_for_generation INTEGER NOT NULL DEFAULT 0;")}i(Ie,"addMessageWaitGenerationColumn");function Xe(e){e.exec(`
|
|
491
140
|
CREATE TABLE IF NOT EXISTS consult_outbox (
|
|
492
141
|
node_id TEXT PRIMARY KEY, -- legacy work node id
|
|
493
142
|
dir TEXT NOT NULL, -- legacy ticket directory
|
|
@@ -501,56 +150,15 @@ CREATE INDEX IF NOT EXISTS idx_consult_outbox_status ON consult_outbox(status);
|
|
|
501
150
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_dir ON consult_outbox(dir);
|
|
502
151
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_dir_request_status ON consult_outbox(dir, request_id, status);
|
|
503
152
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_dir_status ON consult_outbox(dir, status);
|
|
504
|
-
`);
|
|
505
|
-
}
|
|
506
|
-
/** v19 — generalize the physical `consult_outbox` ABI into human work without
|
|
507
|
-
* changing its table name. Existing rows and old literal follow-up inserts gain
|
|
508
|
-
* `follow_up` by default; Visual reserves namespaced statuses so old
|
|
509
|
-
* `armed`/`pending` reconcilers cannot select it. */
|
|
510
|
-
function addHumanWorkColumns(db) {
|
|
511
|
-
const columns = tableColumns(db, 'consult_outbox');
|
|
512
|
-
const add = (name, ddl) => addColumnIfMissing(db, columns, name, ddl);
|
|
513
|
-
add('work_kind', "ALTER TABLE consult_outbox ADD COLUMN work_kind TEXT NOT NULL DEFAULT 'follow_up';");
|
|
514
|
-
add('interaction_id', 'ALTER TABLE consult_outbox ADD COLUMN interaction_id TEXT;');
|
|
515
|
-
add('generation_id', 'ALTER TABLE consult_outbox ADD COLUMN generation_id TEXT;');
|
|
516
|
-
add('interaction_snapshot', 'ALTER TABLE consult_outbox ADD COLUMN interaction_snapshot TEXT;');
|
|
517
|
-
add('handler_command', 'ALTER TABLE consult_outbox ADD COLUMN handler_command TEXT;');
|
|
518
|
-
add('handler_args_json', 'ALTER TABLE consult_outbox ADD COLUMN handler_args_json TEXT;');
|
|
519
|
-
add('claim_token', 'ALTER TABLE consult_outbox ADD COLUMN claim_token TEXT;');
|
|
520
|
-
db.exec(`
|
|
153
|
+
`)}i(Xe,"addHumanWorkOutboxTable");function Se(e){const n=w(e,"consult_outbox"),t=i((o,s)=>Y(e,n,o,s),"add");t("work_kind","ALTER TABLE consult_outbox ADD COLUMN work_kind TEXT NOT NULL DEFAULT 'follow_up';"),t("interaction_id","ALTER TABLE consult_outbox ADD COLUMN interaction_id TEXT;"),t("generation_id","ALTER TABLE consult_outbox ADD COLUMN generation_id TEXT;"),t("interaction_snapshot","ALTER TABLE consult_outbox ADD COLUMN interaction_snapshot TEXT;"),t("handler_command","ALTER TABLE consult_outbox ADD COLUMN handler_command TEXT;"),t("handler_args_json","ALTER TABLE consult_outbox ADD COLUMN handler_args_json TEXT;"),t("claim_token","ALTER TABLE consult_outbox ADD COLUMN claim_token TEXT;"),e.exec(`
|
|
521
154
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_human_work_status ON consult_outbox(work_kind, status);
|
|
522
155
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_human_work_dir_status ON consult_outbox(dir, work_kind, status);
|
|
523
156
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_human_work_request_status ON consult_outbox(dir, request_id, work_kind, status);
|
|
524
157
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_consult_outbox_visual_request ON consult_outbox(dir, request_id, work_kind) WHERE work_kind = 'visual';
|
|
525
|
-
`);
|
|
526
|
-
}
|
|
527
|
-
/** v20 — index `nodes(parent)` and `nodes(created)`. `listNodes()`'s
|
|
528
|
-
* `ORDER BY created` and the `children = rows.filter(r => r.parent === id)`
|
|
529
|
-
* child lookup (`daemon/api/handlers/nodes.ts`'s `edgesFor`) were both
|
|
530
|
-
* full-table scans under the daemon's single event loop; a live fleet's
|
|
531
|
-
* `GET /v1/nodes/:id` measured >15s under concurrent-viewer load. Additive,
|
|
532
|
-
* forward-only — `IF NOT EXISTS` makes re-running a no-op. */
|
|
533
|
-
function addNodeParentCreatedIndexes(db) {
|
|
534
|
-
db.exec(`
|
|
158
|
+
`)}i(Se,"addHumanWorkColumns");function Ue(e){e.exec(`
|
|
535
159
|
CREATE INDEX IF NOT EXISTS idx_nodes_parent ON nodes(parent);
|
|
536
160
|
CREATE INDEX IF NOT EXISTS idx_nodes_created ON nodes(created);
|
|
537
|
-
`);
|
|
538
|
-
}
|
|
539
|
-
/** v21 — the `crons` + `cron_runs` tables. One scheduling primitive: run this
|
|
540
|
-
* bash, then. Key contracts pinned by the spec:
|
|
541
|
-
* - `created_by` is provenance ONLY — no FK, never cascades; a lifelong job
|
|
542
|
-
* is not hostage to the window that typed it.
|
|
543
|
-
* - `anchor_node` is the OPT-IN node coupling, carrying the one FK
|
|
544
|
-
* (ON DELETE CASCADE); NULL = outlives every node on the canvas.
|
|
545
|
-
* - the partial unique index `idx_crons_deadline` is the ≤1-deadline-per-node
|
|
546
|
-
* backstop for the future `node wait deadline` sugar (cancel_on_wake rows).
|
|
547
|
-
* - execution context (cwd/env/profile) is SNAPSHOTTED at arm time, never
|
|
548
|
-
* resolved at run time.
|
|
549
|
-
* - `cron_runs` is a bounded ring (last 20 per cron, pruned by the DAO's
|
|
550
|
-
* recordCronRun).
|
|
551
|
-
* Additive and forward-only. */
|
|
552
|
-
function addCronsTables(db) {
|
|
553
|
-
db.exec(`
|
|
161
|
+
`)}i(Ue,"addNodeParentCreatedIndexes");function ge(e){e.exec(`
|
|
554
162
|
CREATE TABLE IF NOT EXISTS crons (
|
|
555
163
|
cron_id TEXT PRIMARY KEY,
|
|
556
164
|
name TEXT NOT NULL, -- agent-legible label; how it shows in list
|
|
@@ -605,411 +213,38 @@ CREATE TABLE IF NOT EXISTS cron_runs ( -- bounded ring, last 20 p
|
|
|
605
213
|
FOREIGN KEY (cron_id) REFERENCES crons(cron_id) ON DELETE CASCADE
|
|
606
214
|
);
|
|
607
215
|
CREATE INDEX IF NOT EXISTS idx_cron_runs_cron ON cron_runs(cron_id, started);
|
|
608
|
-
`);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
function uniqueHeredocDelimiter(body, stem) {
|
|
614
|
-
let suffix = 0;
|
|
615
|
-
while (true) {
|
|
616
|
-
const delimiter = `${stem}_${suffix}`;
|
|
617
|
-
if (!body.split('\n').includes(delimiter))
|
|
618
|
-
return delimiter;
|
|
619
|
-
suffix++;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
function heredocCommand(command, body, stem) {
|
|
623
|
-
const delimiter = uniqueHeredocDelimiter(body, stem);
|
|
624
|
-
return `${command} <<'${delimiter}'\n${body}\n${delimiter}`;
|
|
625
|
-
}
|
|
626
|
-
/** `payload` was a NULLABLE text column, so NULL, non-string, and legacy or
|
|
627
|
-
* hand-edited JSON are all shapes the retired schema declared legal. A schema
|
|
628
|
-
* migration must never fail on data shape, so anything unreadable degrades to
|
|
629
|
-
* an empty payload; the per-key readers below then decide whether what is left
|
|
630
|
-
* is enough to convert the row. */
|
|
631
|
-
function migrationPayload(raw) {
|
|
632
|
-
if (typeof raw !== 'string')
|
|
633
|
-
return {};
|
|
634
|
-
try {
|
|
635
|
-
const parsed = JSON.parse(raw);
|
|
636
|
-
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
|
|
637
|
-
return {};
|
|
638
|
-
return parsed;
|
|
639
|
-
}
|
|
640
|
-
catch {
|
|
641
|
-
return {};
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
function requiredString(payload, key, triggerId) {
|
|
645
|
-
const value = payload[key];
|
|
646
|
-
if (typeof value !== 'string' || value.trim() === '') {
|
|
647
|
-
throw new Error(`trigger ${triggerId} payload requires non-empty ${key}`);
|
|
648
|
-
}
|
|
649
|
-
return value;
|
|
650
|
-
}
|
|
651
|
-
function optionalString(payload, key) {
|
|
652
|
-
const value = payload[key];
|
|
653
|
-
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
654
|
-
}
|
|
655
|
-
/** The same reader over a `triggers` ROW rather than its payload: returns the
|
|
656
|
-
* column when it holds a usable string, `undefined` otherwise. */
|
|
657
|
-
function optionalColumn(row, key) {
|
|
658
|
-
const value = row[key];
|
|
659
|
-
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
660
|
-
}
|
|
661
|
-
function migratedMessageCommand(target, tier, body, triggerId) {
|
|
662
|
-
return heredocCommand(`crtr node message send --to ${shellSingleQuote(target)} --tier ${shellSingleQuote(tier)}`, body, `CRTR_MIGRATED_${triggerId.replace(/[^A-Za-z0-9]/g, '_')}`);
|
|
663
|
-
}
|
|
664
|
-
/** A body-less predicate message: the retired daemon filled the body from the
|
|
665
|
-
* gate's stdout at fire time (`p.body ?? outcome.stdout`), so the migrated
|
|
666
|
-
* script pipes the captured gate output into the send. */
|
|
667
|
-
function migratedGateStdoutMessageCommand(target, tier) {
|
|
668
|
-
return `printf '%s\\n' "$CRTR_GATE_STDOUT" | crtr node message send --to ${shellSingleQuote(target)} --tier ${shellSingleQuote(tier)}`;
|
|
669
|
-
}
|
|
670
|
-
function migratedSpawnCommand(payload, triggerId) {
|
|
671
|
-
const flags = [`crtr node new --kind ${shellSingleQuote(requiredString(payload, 'kind', triggerId))}`];
|
|
672
|
-
const strings = [
|
|
673
|
-
['mode', 'mode'],
|
|
674
|
-
['cwd', 'cwd'],
|
|
675
|
-
['name', 'name'],
|
|
676
|
-
['parent', 'parent'],
|
|
677
|
-
['worktreeBase', 'worktree'],
|
|
678
|
-
['forkFrom', 'fork-from'],
|
|
679
|
-
['model', 'model'],
|
|
680
|
-
['profile', 'profile'],
|
|
681
|
-
['situationalContext', 'situational-context'],
|
|
682
|
-
];
|
|
683
|
-
for (const [key, flag] of strings) {
|
|
684
|
-
const value = optionalString(payload, key);
|
|
685
|
-
if (value !== undefined)
|
|
686
|
-
flags.push(`--${flag} ${shellSingleQuote(value)}`);
|
|
687
|
-
}
|
|
688
|
-
if (payload['root'] === true)
|
|
689
|
-
flags.push('--root');
|
|
690
|
-
const prompt = requiredString(payload, 'prompt', triggerId);
|
|
691
|
-
return heredocCommand(flags.join(' '), prompt, `CRTR_MIGRATED_${triggerId.replace(/[^A-Za-z0-9]/g, '_')}`);
|
|
692
|
-
}
|
|
693
|
-
/** The `canvas_meta` key holding the v22 skip ledger: a JSON array of
|
|
694
|
-
* `{ trigger_id, reason }` for every retired schedule the migration could not
|
|
695
|
-
* express as a cron. Written only when at least one row is skipped. */
|
|
696
|
-
const V22_SKIPPED_META_KEY = 'migration.v22.skipped';
|
|
697
|
-
/** The execution-context cwd for a schedule whose armer is gone. `owner_id`
|
|
698
|
-
* carries NO foreign key by design (see v7), so a crashed-then-pruned armer's
|
|
699
|
-
* detached schedule is an EXPECTED row, not a corrupt one — it must still
|
|
700
|
-
* convert. Falls back to the oldest root node's cwd (the ambient canvas root),
|
|
701
|
-
* then to this process's cwd. */
|
|
702
|
-
function ambientMigrationCwd(db) {
|
|
703
|
-
const root = db
|
|
704
|
-
.prepare('SELECT cwd FROM nodes WHERE parent IS NULL ORDER BY created LIMIT 1')
|
|
705
|
-
.get();
|
|
706
|
-
return (root !== undefined ? optionalColumn(root, 'cwd') : undefined) ?? process.cwd();
|
|
707
|
-
}
|
|
708
|
-
/** Best-effort reap of in-flight predicate evaluations before the table that
|
|
709
|
-
* records them is dropped. The retired cancel path killed the evaluation's
|
|
710
|
-
* process GROUP; without this the migration would orphan a running gate
|
|
711
|
-
* script with nothing left on disk that names it. */
|
|
712
|
-
function reapRunningPredicateEvaluations(db) {
|
|
713
|
-
let running;
|
|
714
|
-
try {
|
|
715
|
-
running = db
|
|
716
|
-
.prepare("SELECT eval_pid FROM triggers WHERE eval_state = 'running' AND eval_pid IS NOT NULL")
|
|
717
|
-
.all();
|
|
718
|
-
}
|
|
719
|
-
catch {
|
|
720
|
-
return; // a drifted table shape has no evaluations we can name; never fatal
|
|
721
|
-
}
|
|
722
|
-
for (const row of running) {
|
|
723
|
-
const pid = row['eval_pid'];
|
|
724
|
-
if (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 1)
|
|
725
|
-
continue;
|
|
726
|
-
try {
|
|
727
|
-
process.kill(-pid, 'SIGTERM');
|
|
728
|
-
}
|
|
729
|
-
catch {
|
|
730
|
-
/* the evaluation already exited, or the group is gone — nothing to reap */
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
/** v22 — migrate each scheduled action into a shell cron, preserving its id and
|
|
735
|
-
* execution context, then remove the superseded table.
|
|
736
|
-
*
|
|
737
|
-
* SKIP-AND-RECORD, never throw. A migration that hard-fails on data shape would
|
|
738
|
-
* block daemon startup. Rows the retired schema declared legal but this step
|
|
739
|
-
* cannot express (unknown action/timing pairs, a missing fire time, drifted
|
|
740
|
-
* JSON) are skipped, named in the `canvas_meta` ledger under
|
|
741
|
-
* `migration.v22.skipped`, and warned about — the schema always advances.
|
|
742
|
-
* `INSERT OR REPLACE` makes a re-run over already-converted ids converge rather
|
|
743
|
-
* than collide on the `cron_id` primary key. */
|
|
744
|
-
function migrateTriggersToCrons(db) {
|
|
745
|
-
const skipped = [];
|
|
746
|
-
// A db already wedged by an interrupted pre-atomicity run (crons committed,
|
|
747
|
-
// the table dropped, `user_version` still 21) re-runs this step with nothing
|
|
748
|
-
// left to convert; it must advance, not throw.
|
|
749
|
-
const hasTriggers = db
|
|
750
|
-
.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'triggers'")
|
|
751
|
-
.get() !== undefined;
|
|
752
|
-
if (hasTriggers)
|
|
753
|
-
reapRunningPredicateEvaluations(db);
|
|
754
|
-
let rows = [];
|
|
755
|
-
if (hasTriggers) {
|
|
756
|
-
try {
|
|
757
|
-
rows = db.prepare('SELECT * FROM triggers ORDER BY created, trigger_id').all();
|
|
758
|
-
}
|
|
759
|
-
catch (err) {
|
|
760
|
-
// A column-drifted table (no `created`/`trigger_id`) must not brick every
|
|
761
|
-
// open either: record that its rows were unreadable and advance.
|
|
762
|
-
skipped.push({
|
|
763
|
-
trigger_id: '<unreadable table>',
|
|
764
|
-
reason: `triggers table could not be read: ${err instanceof Error ? err.message : String(err)}`,
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
const fallbackCwd = ambientMigrationCwd(db);
|
|
769
|
-
const insert = db.prepare(`
|
|
216
|
+
`)}i(ge,"addCronsTables");function f(e){return`'${e.replace(/'/g,`'"'"'`)}'`}i(f,"shellSingleQuote");function Ce(e,n){let t=0;for(;;){const o=`${n}_${t}`;if(!e.split(`
|
|
217
|
+
`).includes(o))return o;t++}}i(Ce,"uniqueHeredocDelimiter");function W(e,n,t){const o=Ce(n,t);return`${e} <<'${o}'
|
|
218
|
+
${n}
|
|
219
|
+
${o}`}i(W,"heredocCommand");function De(e){if(typeof e!="string")return{};try{const n=JSON.parse(e);return typeof n!="object"||n===null||Array.isArray(n)?{}:n}catch{return{}}}i(De,"migrationPayload");function L(e,n,t){const o=e[n];if(typeof o!="string"||o.trim()==="")throw new Error(`trigger ${t} payload requires non-empty ${n}`);return o}i(L,"requiredString");function U(e,n){const t=e[n];return typeof t=="string"&&t.trim()!==""?t:void 0}i(U,"optionalString");function R(e,n){const t=e[n];return typeof t=="string"&&t.trim()!==""?t:void 0}i(R,"optionalColumn");function K(e,n,t,o){return W(`crtr node message send --to ${f(e)} --tier ${f(n)}`,t,`CRTR_MIGRATED_${o.replace(/[^A-Za-z0-9]/g,"_")}`)}i(K,"migratedMessageCommand");function he(e,n){return`printf '%s\\n' "$CRTR_GATE_STDOUT" | crtr node message send --to ${f(e)} --tier ${f(n)}`}i(he,"migratedGateStdoutMessageCommand");function we(e,n){const t=[`crtr node new --kind ${f(L(e,"kind",n))}`],o=[["mode","mode"],["cwd","cwd"],["name","name"],["parent","parent"],["worktreeBase","worktree"],["forkFrom","fork-from"],["model","model"],["profile","profile"],["situationalContext","situational-context"]];for(const[T,r]of o){const E=U(e,T);E!==void 0&&t.push(`--${r} ${f(E)}`)}e.root===!0&&t.push("--root");const s=L(e,"prompt",n);return W(t.join(" "),s,`CRTR_MIGRATED_${n.replace(/[^A-Za-z0-9]/g,"_")}`)}i(we,"migratedSpawnCommand");const q="migration.v22.skipped";function xe(e){const n=e.prepare("SELECT cwd FROM nodes WHERE parent IS NULL ORDER BY created LIMIT 1").get();return(n!==void 0?R(n,"cwd"):void 0)??process.cwd()}i(xe,"ambientMigrationCwd");function ve(e){let n;try{n=e.prepare("SELECT eval_pid FROM triggers WHERE eval_state = 'running' AND eval_pid IS NOT NULL").all()}catch{return}for(const t of n){const o=t.eval_pid;if(!(typeof o!="number"||!Number.isInteger(o)||o<=1))try{process.kill(-o,"SIGTERM")}catch{}}}i(ve,"reapRunningPredicateEvaluations");function Fe(e){const n=[],t=e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'triggers'").get()!==void 0;t&&ve(e);let o=[];if(t)try{o=e.prepare("SELECT * FROM triggers ORDER BY created, trigger_id").all()}catch(r){n.push({trigger_id:"<unreadable table>",reason:`triggers table could not be read: ${r instanceof Error?r.message:String(r)}`})}const s=xe(e),T=e.prepare(`
|
|
770
220
|
INSERT OR REPLACE INTO crons (
|
|
771
221
|
cron_id, name, created_by, command, fire_at, recur, tz, expires_at,
|
|
772
222
|
anchor_node, cancel_on_wake, cwd, env_json, profile, scope,
|
|
773
223
|
run_timeout_s, overlap, on_output, sink, tier, created, updated
|
|
774
|
-
) VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, NULL, ?, 'profile', ?, 'skip', 'on-failure', '{}', ?, ?, ?)`);
|
|
775
|
-
for (const row of rows) {
|
|
776
|
-
const triggerId = optionalColumn(row, 'trigger_id');
|
|
777
|
-
if (triggerId === undefined) {
|
|
778
|
-
skipped.push({ trigger_id: '<unidentified row>', reason: 'row carries no trigger_id' });
|
|
779
|
-
continue;
|
|
780
|
-
}
|
|
781
|
-
try {
|
|
782
|
-
convertTriggerRow(db, insert, row, triggerId, fallbackCwd);
|
|
783
|
-
}
|
|
784
|
-
catch (err) {
|
|
785
|
-
skipped.push({ trigger_id: triggerId, reason: err instanceof Error ? err.message : String(err) });
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
if (skipped.length > 0) {
|
|
789
|
-
db.prepare('INSERT INTO canvas_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(V22_SKIPPED_META_KEY, JSON.stringify(skipped));
|
|
790
|
-
console.warn(`[canvas migration v22] ${skipped.length} retired schedule(s) could not be converted to crons and were dropped; ` +
|
|
791
|
-
`see canvas_meta['${V22_SKIPPED_META_KEY}']: ` +
|
|
792
|
-
skipped.map((entry) => `${entry.trigger_id} (${entry.reason})`).join('; '));
|
|
793
|
-
}
|
|
794
|
-
db.exec(`
|
|
224
|
+
) VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, NULL, ?, 'profile', ?, 'skip', 'on-failure', '{}', ?, ?, ?)`);for(const r of o){const E=R(r,"trigger_id");if(E===void 0){n.push({trigger_id:"<unidentified row>",reason:"row carries no trigger_id"});continue}try{ye(e,T,r,E,s)}catch(d){n.push({trigger_id:E,reason:d instanceof Error?d.message:String(d)})}}n.length>0&&(e.prepare("INSERT INTO canvas_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(q,JSON.stringify(n)),console.warn(`[canvas migration v22] ${n.length} retired schedule(s) could not be converted to crons and were dropped; see canvas_meta['${q}']: `+n.map(r=>`${r.trigger_id} (${r.reason})`).join("; "))),e.exec(`
|
|
795
225
|
DROP INDEX IF EXISTS idx_triggers_fire;
|
|
796
226
|
DROP INDEX IF EXISTS idx_triggers_node;
|
|
797
227
|
DROP INDEX IF EXISTS idx_triggers_owner;
|
|
798
228
|
DROP INDEX IF EXISTS idx_triggers_eval;
|
|
799
229
|
DROP INDEX IF EXISTS idx_triggers_deadline;
|
|
800
230
|
DROP TABLE IF EXISTS triggers;
|
|
801
|
-
`);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
const cwd = (owner === undefined ? undefined : optionalColumn(owner, 'cwd')) ?? fallbackCwd;
|
|
812
|
-
const profile = owner === undefined ? null : optionalColumn(owner, 'profile_id') ?? null;
|
|
813
|
-
const nodeId = optionalColumn(row, 'node_id') ?? null;
|
|
814
|
-
const action = requiredString(row, 'action', triggerId);
|
|
815
|
-
const actionMode = requiredString(row, 'action_mode', triggerId);
|
|
816
|
-
const triggerType = requiredString(row, 'trigger_type', triggerId);
|
|
817
|
-
const payload = migrationPayload(row['payload']);
|
|
818
|
-
const created = optionalColumn(row, 'created') ?? new Date().toISOString();
|
|
819
|
-
const tier = actionMode === 'deadline_message' ? 'urgent' : optionalString(payload, 'tier') ?? 'normal';
|
|
820
|
-
const label = optionalString(payload, 'label');
|
|
821
|
-
let command;
|
|
822
|
-
let name;
|
|
823
|
-
// A `--when` schedule could legally omit its body: the retired daemon filled
|
|
824
|
-
// it from the gate's stdout at fire time. Such a row pipes the captured gate
|
|
825
|
-
// output into the send instead of carrying a heredoc.
|
|
826
|
-
let bodyFromGate = false;
|
|
827
|
-
if (action === 'msg' && (actionMode === 'inbox_message' || actionMode === 'deadline_message')) {
|
|
828
|
-
if (nodeId === null)
|
|
829
|
-
throw new Error('has no message target');
|
|
830
|
-
const body = optionalString(payload, 'body');
|
|
831
|
-
if (body !== undefined) {
|
|
832
|
-
command = migratedMessageCommand(nodeId, tier, body, triggerId);
|
|
833
|
-
}
|
|
834
|
-
else if (triggerType === 'when') {
|
|
835
|
-
bodyFromGate = true;
|
|
836
|
-
command = migratedGateStdoutMessageCommand(nodeId, tier);
|
|
837
|
-
}
|
|
838
|
-
else {
|
|
839
|
-
// Not expressible from a gate: synthesize the most informative body the
|
|
840
|
-
// row still holds rather than losing the enactment.
|
|
841
|
-
command = migratedMessageCommand(nodeId, tier, label ?? 'Scheduled message (no body was recorded when this schedule was armed).', triggerId);
|
|
842
|
-
}
|
|
843
|
-
name = label ?? (actionMode === 'deadline_message' ? 'deadline' : 'scheduled message');
|
|
844
|
-
}
|
|
845
|
-
else if (action === 'msg' && actionMode === 'fresh_revive') {
|
|
846
|
-
if (nodeId === null)
|
|
847
|
-
throw new Error('has no revive target');
|
|
848
|
-
command = `crtr node lifecycle revive ${shellSingleQuote(nodeId)} --fresh`;
|
|
849
|
-
name = label ?? 'scheduled fresh revive';
|
|
850
|
-
}
|
|
851
|
-
else if (action === 'new' && actionMode === 'node_birth') {
|
|
852
|
-
command = migratedSpawnCommand(payload, triggerId);
|
|
853
|
-
name = optionalString(payload, 'name') ?? `scheduled ${requiredString(payload, 'kind', triggerId)} node`;
|
|
854
|
-
}
|
|
855
|
-
else {
|
|
856
|
-
throw new Error(`has unsupported action ${action}/${actionMode}`);
|
|
857
|
-
}
|
|
858
|
-
let fireAt;
|
|
859
|
-
let recur;
|
|
860
|
-
let expiresAt = null;
|
|
861
|
-
if (triggerType === 'when') {
|
|
862
|
-
fireAt = requiredString(row, 'next_eval_at', triggerId);
|
|
863
|
-
// A when-row with no evaluation cadence would silently become a ONE-SHOT
|
|
864
|
-
// gate that evaporates on its first unsatisfied check; skip-and-record it.
|
|
865
|
-
recur = requiredString(row, 'eval_every', triggerId);
|
|
866
|
-
expiresAt = optionalColumn(row, 'timeout_at') ?? null;
|
|
867
|
-
const gate = requiredString(row, 'when_script', triggerId);
|
|
868
|
-
const open = bodyFromGate ? `if ! CRTR_GATE_STDOUT="$(\n${gate}\n)"; then` : `if ! (\n${gate}\n); then`;
|
|
869
|
-
// `&&`, not a newline: the run's exit status must be the ACTION's, so a
|
|
870
|
-
// failed enactment escalates through the cron's on-failure path and leaves
|
|
871
|
-
// the cron armed instead of silently self-cancelling on a lost message.
|
|
872
|
-
// The action is BRACE-GROUPED because it may be heredoc-shaped: a `&&`
|
|
873
|
-
// appended straight onto it would land on the heredoc's closing delimiter
|
|
874
|
-
// line, which then never terminates the document.
|
|
875
|
-
command = `${open}\n exit 0\nfi\n{\n${command}\n} && crtr cron cancel "$CRTR_CRON_ID"`;
|
|
876
|
-
}
|
|
877
|
-
else if (triggerType === 'at' || triggerType === 'every' || triggerType === 'until') {
|
|
878
|
-
fireAt = requiredString(row, 'fire_at', triggerId);
|
|
879
|
-
recur = triggerType === 'every' ? requiredString(row, 'recur', triggerId) : null;
|
|
880
|
-
}
|
|
881
|
-
else {
|
|
882
|
-
throw new Error(`has unknown timing type ${triggerType}`);
|
|
883
|
-
}
|
|
884
|
-
// `INSERT OR REPLACE` (the re-run convergence for a repeated `cron_id`) would
|
|
885
|
-
// ALSO silently evict a conflicting row on the ≤1-deadline-per-node partial
|
|
886
|
-
// index. Only drifted data can produce that shape, and it must be recorded,
|
|
887
|
-
// not resolved in silence: keep the earlier deadline, skip this one.
|
|
888
|
-
if (actionMode === 'deadline_message' && nodeId !== null) {
|
|
889
|
-
const rival = db
|
|
890
|
-
.prepare('SELECT cron_id FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1 AND cron_id <> ?')
|
|
891
|
-
.get(nodeId, triggerId);
|
|
892
|
-
if (rival !== undefined) {
|
|
893
|
-
throw new Error(`node ${nodeId} already has a migrated deadline (${String(rival['cron_id'])}); only one is allowed`);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
insert.run(triggerId, name, ownerId, command, fireAt, recur, expiresAt, nodeId, actionMode === 'deadline_message' ? 1 : 0, cwd, profile, 300,
|
|
897
|
-
// `tier` and `sink` are INERT for migrated rows: the delivery lives entirely
|
|
898
|
-
// inside `command` (which carries its own `--tier`), and `sink = '{}'`
|
|
899
|
-
// parses to "no sink armed". `tier` is preserved only as provenance of what
|
|
900
|
-
// the retired schedule would have sent.
|
|
901
|
-
tier, created, created);
|
|
902
|
-
}
|
|
903
|
-
/** v23 — pid-REUSE guard for the cron run lease: `crons.run_pid_identity` holds
|
|
904
|
-
* the `capturePidIdentities` fingerprint of the run's process, captured at lease
|
|
905
|
-
* acquisition beside `run_pid`. Every kill site (stale-lease recovery,
|
|
906
|
-
* `cancelCron`, `cancelCronsOnWake`, deadline displacement) re-captures the
|
|
907
|
-
* identity of the recorded pid and refuses to signal unless it MATCHES.
|
|
908
|
-
*
|
|
909
|
-
* Without it, a bare pid recorded by a daemon life that ended (SIGKILL, host
|
|
910
|
-
* reboot) is compared only with `isPidAlive` — after a reboot the pid comes
|
|
911
|
-
* from a dead kernel's pid space, a low pid is likely recycled, and the run's
|
|
912
|
-
* own timeout is trivially exceeded, so recovery SIGTERMs an unrelated user
|
|
913
|
-
* process group. Rows written before this column exist have NULL identity and
|
|
914
|
-
* therefore fall to the fail-closed path (release the lease, never signal). */
|
|
915
|
-
function addCronRunPidIdentityColumn(db) {
|
|
916
|
-
const columns = tableColumns(db, 'crons');
|
|
917
|
-
// A metadata-only harness db may have no `crons` table at all (PRAGMA returns
|
|
918
|
-
// no rows); there is nothing to alter and the version must still advance.
|
|
919
|
-
if (columns.size === 0 || columns.has('run_pid_identity'))
|
|
920
|
-
return;
|
|
921
|
-
db.exec('ALTER TABLE crons ADD COLUMN run_pid_identity TEXT;');
|
|
922
|
-
}
|
|
923
|
-
/** v24 — mark an OUT-OF-BAND run lease, and drop the never-implemented
|
|
924
|
-
* `crons.queued` column.
|
|
925
|
-
*
|
|
926
|
-
* `run_out_of_band` is set by `acquireCronRunLease` when the run is a `cron run`
|
|
927
|
-
* (the manual verify verb) rather than a scheduled fire. The overlap pass
|
|
928
|
-
* selects on `run_state = 'running'` alone, so without this marker a manual run
|
|
929
|
-
* that happens to straddle a real occurrence gets that occurrence advanced past
|
|
930
|
-
* (`overlap=skip` — a scheduled fire silently lost to a verification) or gets
|
|
931
|
-
* itself SIGTERMed (`overlap=replace`). The overlap pass now excludes it.
|
|
932
|
-
*
|
|
933
|
-
* `queued` was written by nothing and read by nothing: `overlap='queue'` is
|
|
934
|
-
* implemented purely by LEAVING `fire_at` past-due, so the depth is structural
|
|
935
|
-
* (one occurrence per row) and needs no counter. A column documenting a policy
|
|
936
|
-
* it does not implement misleads the next reader, so it goes. */
|
|
937
|
-
function addCronOutOfBandColumn(db) {
|
|
938
|
-
const columns = tableColumns(db, 'crons');
|
|
939
|
-
// A metadata-only harness db may have no `crons` table at all (PRAGMA returns
|
|
940
|
-
// no rows); there is nothing to alter and the version must still advance.
|
|
941
|
-
if (columns.size === 0)
|
|
942
|
-
return;
|
|
943
|
-
if (!columns.has('run_out_of_band')) {
|
|
944
|
-
db.exec('ALTER TABLE crons ADD COLUMN run_out_of_band INTEGER NOT NULL DEFAULT 0;');
|
|
945
|
-
}
|
|
946
|
-
if (columns.has('queued'))
|
|
947
|
-
db.exec('ALTER TABLE crons DROP COLUMN queued;');
|
|
948
|
-
}
|
|
949
|
-
/** v25 — the `warm_pool` table: the spare-node pool behind `prefer_warm`.
|
|
950
|
-
*
|
|
951
|
-
* A spare IS a real canvas node (its broker is already booted against a real
|
|
952
|
-
* node dir); the row here is the marker that it has not been handed to anyone
|
|
953
|
-
* yet. Membership in this table is what hides a node from every listing
|
|
954
|
-
* (`listNodes`/`rosterNodes`/`listResumableRoots`) — an unclaimed spare must
|
|
955
|
-
* never surface as a phantom empty conversation in a user's sidebar. Claiming
|
|
956
|
-
* is exactly the DELETE of this row, taken under the canvas write-lock, so two
|
|
957
|
-
* concurrent creates can never be handed the same spare.
|
|
958
|
-
*
|
|
959
|
-
* `recipe_key` is the frozen-tuple digest a claim must match exactly (see
|
|
960
|
-
* `runtime/warm-pool.ts`); the FK cascade reaps the marker when the node row
|
|
961
|
-
* goes away. */
|
|
962
|
-
function addWarmPoolTable(db) {
|
|
963
|
-
db.exec(`
|
|
231
|
+
`)}i(Fe,"migrateTriggersToCrons");function ye(e,n,t,o,s){const T=L(t,"owner_id",o),r=e.prepare("SELECT cwd, profile_id FROM nodes WHERE node_id = ?").get(T),E=(r===void 0?void 0:R(r,"cwd"))??s,d=r===void 0?null:R(r,"profile_id")??null,_=R(t,"node_id")??null,c=L(t,"action",o),N=L(t,"action_mode",o),u=L(t,"trigger_type",o),m=De(t.payload),M=R(t,"created")??new Date().toISOString(),C=N==="deadline_message"?"urgent":U(m,"tier")??"normal",x=U(m,"label");let p,D,G=!1;if(c==="msg"&&(N==="inbox_message"||N==="deadline_message")){if(_===null)throw new Error("has no message target");const O=U(m,"body");O!==void 0?p=K(_,C,O,o):u==="when"?(G=!0,p=he(_,C)):p=K(_,C,x??"Scheduled message (no body was recorded when this schedule was armed).",o),D=x??(N==="deadline_message"?"deadline":"scheduled message")}else if(c==="msg"&&N==="fresh_revive"){if(_===null)throw new Error("has no revive target");p=`crtr node lifecycle revive ${f(_)} --fresh`,D=x??"scheduled fresh revive"}else if(c==="new"&&N==="node_birth")p=we(m,o),D=U(m,"name")??`scheduled ${L(m,"kind",o)} node`;else throw new Error(`has unsupported action ${c}/${N}`);let v,F,B=null;if(u==="when"){v=L(t,"next_eval_at",o),F=L(t,"eval_every",o),B=R(t,"timeout_at")??null;const O=L(t,"when_script",o);p=`${G?`if ! CRTR_GATE_STDOUT="$(
|
|
232
|
+
${O}
|
|
233
|
+
)"; then`:`if ! (
|
|
234
|
+
${O}
|
|
235
|
+
); then`}
|
|
236
|
+
exit 0
|
|
237
|
+
fi
|
|
238
|
+
{
|
|
239
|
+
${p}
|
|
240
|
+
} && crtr cron cancel "$CRTR_CRON_ID"`}else if(u==="at"||u==="every"||u==="until")v=L(t,"fire_at",o),F=u==="every"?L(t,"recur",o):null;else throw new Error(`has unknown timing type ${u}`);if(N==="deadline_message"&&_!==null){const O=e.prepare("SELECT cron_id FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1 AND cron_id <> ?").get(_,o);if(O!==void 0)throw new Error(`node ${_} already has a migrated deadline (${String(O.cron_id)}); only one is allowed`)}n.run(o,D,T,p,v,F,B,_,N==="deadline_message"?1:0,E,d,300,C,M,M)}i(ye,"convertTriggerRow");function ke(e){const n=w(e,"crons");n.size===0||n.has("run_pid_identity")||e.exec("ALTER TABLE crons ADD COLUMN run_pid_identity TEXT;")}i(ke,"addCronRunPidIdentityColumn");function Me(e){const n=w(e,"crons");n.size!==0&&(n.has("run_out_of_band")||e.exec("ALTER TABLE crons ADD COLUMN run_out_of_band INTEGER NOT NULL DEFAULT 0;"),n.has("queued")&&e.exec("ALTER TABLE crons DROP COLUMN queued;"))}i(Me,"addCronOutOfBandColumn");function Ge(e){e.exec(`
|
|
964
241
|
CREATE TABLE IF NOT EXISTS warm_pool (
|
|
965
242
|
node_id TEXT PRIMARY KEY REFERENCES nodes(node_id) ON DELETE CASCADE,
|
|
966
243
|
recipe_key TEXT NOT NULL, -- frozen launch tuple this spare was minted for
|
|
967
244
|
created TEXT NOT NULL -- ISO 8601, mint time (oldest spare claimed first)
|
|
968
245
|
);
|
|
969
246
|
CREATE INDEX IF NOT EXISTS idx_warm_pool_recipe ON warm_pool(recipe_key, created);
|
|
970
|
-
`);
|
|
971
|
-
}
|
|
972
|
-
/** v26 — narrow `consult_outbox` for the humanloop absorption into
|
|
973
|
-
* `src/core/human/` (absorb-humanloop
|
|
974
|
-
* design, "The human-work receipt table"; Landing 2 Part E task E2). The
|
|
975
|
-
* five-column trust binding (`handler_command`, `handler_args_json`,
|
|
976
|
-
* `claim_token`, `generation_id`, `interaction_snapshot`) existed only to let
|
|
977
|
-
* crtrd re-verify that a Visual event arrived through crouter's own
|
|
978
|
-
* registered handler argv — that registry is deleted in this landing, so
|
|
979
|
-
* there is nothing left to bind. `dir`/`root` collapse into `ticket_node_id`,
|
|
980
|
-
* the bridge node id stored as `basename(dir)` in the input rows.
|
|
981
|
-
*
|
|
982
|
-
* THIS IS A TABLE REBUILD, NOT `ALTER TABLE … DROP COLUMN`: six of the nine
|
|
983
|
-
* existing indexes are on `dir` (`idx_consult_outbox_dir`,
|
|
984
|
-
* `idx_consult_outbox_dir_request_status`, `idx_consult_outbox_dir_status`
|
|
985
|
-
* from v18; `idx_consult_outbox_human_work_dir_status`,
|
|
986
|
-
* `idx_consult_outbox_human_work_request_status`, and the partial-unique
|
|
987
|
-
* `idx_consult_outbox_visual_request` from v19), and SQLite refuses
|
|
988
|
-
* `DROP COLUMN` on any indexed column. `ticket_node_id` cannot be a SQL
|
|
989
|
-
* DEFAULT either — SQLite has no `basename()` — so it is computed per row in
|
|
990
|
-
* JS: read every existing row through a prepared SELECT, insert each into a
|
|
991
|
-
* freshly created `consult_outbox_new` with `ticket_node_id = basename(dir)`,
|
|
992
|
-
* drop the old table (dropping its indexes with it), rename the new table
|
|
993
|
-
* into place, and recreate exactly five indexes on the narrowed shape. Every
|
|
994
|
-
* row is carried, including terminal ones, EXCEPT a row whose legacy `dir` is
|
|
995
|
-
* not a canonical direct child of its recorded `root`, or whose basename is
|
|
996
|
-
* not a safe node id — either would create an unaddressable or aliased ticket
|
|
997
|
-
* id once `root` is discarded. A warning names how many are dropped.
|
|
998
|
-
*
|
|
999
|
-
* THERE IS NO ROLLBACK. A sealed older runtime generation still running
|
|
1000
|
-
* against this canvas.db fails on the Visual lane (`INSERT INTO
|
|
1001
|
-
* consult_outbox (… dir, root, handler_command …)`) once this has run —
|
|
1002
|
-
* acceptable because this migration lands WITH a generation roll
|
|
1003
|
-
* (`npm run build && npm run install-runtime && crtr sys daemon restart`),
|
|
1004
|
-
* never alongside one. Not self-transactional: like every ordinary migration
|
|
1005
|
-
* it runs inside `migrate()`'s per-step `BEGIN IMMEDIATE`, so an interrupted
|
|
1006
|
-
* run leaves `consult_outbox` exactly as it was (SQLite DDL is transactional)
|
|
1007
|
-
* and a re-open resumes cleanly at the same step. */
|
|
1008
|
-
function narrowHumanWorkOutbox(db) {
|
|
1009
|
-
const rows = db
|
|
1010
|
-
.prepare('SELECT node_id, dir, root, request_id, work_kind, status, final_report, updated_at FROM consult_outbox')
|
|
1011
|
-
.all();
|
|
1012
|
-
db.exec(`
|
|
247
|
+
`)}i(Ge,"addWarmPoolTable");function Be(e){const n=e.prepare("SELECT node_id, dir, root, request_id, work_kind, status, final_report, updated_at FROM consult_outbox").all();e.exec(`
|
|
1013
248
|
CREATE TABLE consult_outbox_new (
|
|
1014
249
|
node_id TEXT PRIMARY KEY,
|
|
1015
250
|
ticket_node_id TEXT NOT NULL,
|
|
@@ -1019,24 +254,9 @@ CREATE TABLE consult_outbox_new (
|
|
|
1019
254
|
final_report TEXT,
|
|
1020
255
|
updated_at TEXT NOT NULL
|
|
1021
256
|
);
|
|
1022
|
-
`);
|
|
1023
|
-
const insert = db.prepare(`
|
|
257
|
+
`);const t=e.prepare(`
|
|
1024
258
|
INSERT INTO consult_outbox_new (node_id, ticket_node_id, request_id, work_kind, status, final_report, updated_at)
|
|
1025
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
1026
|
-
let dropped = 0;
|
|
1027
|
-
for (const row of rows) {
|
|
1028
|
-
const ticketNodeId = basename(row.dir);
|
|
1029
|
-
const directChild = row.root === resolve(row.root) && row.dir === join(row.root, ticketNodeId);
|
|
1030
|
-
if (!directChild || !isSafeNodeId(ticketNodeId)) {
|
|
1031
|
-
dropped += 1;
|
|
1032
|
-
continue;
|
|
1033
|
-
}
|
|
1034
|
-
insert.run(row.node_id, ticketNodeId, row.request_id, row.work_kind, row.status, row.final_report, row.updated_at);
|
|
1035
|
-
}
|
|
1036
|
-
if (dropped > 0) {
|
|
1037
|
-
console.warn(`[canvas migration v26] dropped ${dropped} consult_outbox row(s) whose legacy ticket path cannot safely map to a ticket node id`);
|
|
1038
|
-
}
|
|
1039
|
-
db.exec(`
|
|
259
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);let o=0;for(const s of n){const T=te(s.dir);if(!(s.root===H(s.root)&&s.dir===y(s.root,T))||!ie(T)){o+=1;continue}t.run(s.node_id,T,s.request_id,s.work_kind,s.status,s.final_report,s.updated_at)}o>0&&console.warn(`[canvas migration v26] dropped ${o} consult_outbox row(s) whose legacy ticket path cannot safely map to a ticket node id`),e.exec(`
|
|
1040
260
|
DROP TABLE consult_outbox;
|
|
1041
261
|
ALTER TABLE consult_outbox_new RENAME TO consult_outbox;
|
|
1042
262
|
|
|
@@ -1045,11 +265,7 @@ CREATE INDEX IF NOT EXISTS idx_consult_outbox_human_work_status ON consult_outbo
|
|
|
1045
265
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_ticket_status ON consult_outbox(ticket_node_id, work_kind, status);
|
|
1046
266
|
CREATE INDEX IF NOT EXISTS idx_consult_outbox_ticket_request_status ON consult_outbox(ticket_node_id, request_id, work_kind, status);
|
|
1047
267
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_consult_outbox_visual_request ON consult_outbox(ticket_node_id, request_id, work_kind) WHERE work_kind = 'visual';
|
|
1048
|
-
`);
|
|
1049
|
-
}
|
|
1050
|
-
/** v27 — the canonical daemon-owned review record. */
|
|
1051
|
-
function addReviewsTable(db) {
|
|
1052
|
-
db.exec(`
|
|
268
|
+
`)}i(Be,"narrowHumanWorkOutbox");function He(e){e.exec(`
|
|
1053
269
|
CREATE TABLE IF NOT EXISTS reviews (
|
|
1054
270
|
review_id TEXT PRIMARY KEY,
|
|
1055
271
|
idempotency_key TEXT NOT NULL UNIQUE,
|
|
@@ -1093,11 +309,7 @@ CREATE INDEX IF NOT EXISTS idx_reviews_state ON reviews(state);
|
|
|
1093
309
|
CREATE INDEX IF NOT EXISTS idx_reviews_origin ON reviews(origin_node_id);
|
|
1094
310
|
CREATE INDEX IF NOT EXISTS idx_reviews_file ON reviews(file);
|
|
1095
311
|
CREATE INDEX IF NOT EXISTS idx_reviews_bridge ON reviews(bridge_node_id);
|
|
1096
|
-
`);
|
|
1097
|
-
}
|
|
1098
|
-
/** v28 — current review-comment projection and append-only comment audit. */
|
|
1099
|
-
function addReviewCommentTables(db) {
|
|
1100
|
-
db.exec(`
|
|
312
|
+
`)}i(He,"addReviewsTable");function Pe(e){e.exec(`
|
|
1101
313
|
CREATE TABLE IF NOT EXISTS review_comments (
|
|
1102
314
|
comment_id TEXT PRIMARY KEY,
|
|
1103
315
|
review_id TEXT NOT NULL,
|
|
@@ -1142,43 +354,13 @@ CREATE INDEX IF NOT EXISTS idx_review_comment_events_review_seq
|
|
|
1142
354
|
ON review_comment_events(review_id, seq);
|
|
1143
355
|
CREATE INDEX IF NOT EXISTS idx_review_comment_events_comment_seq
|
|
1144
356
|
ON review_comment_events(comment_id, seq);
|
|
1145
|
-
`);
|
|
1146
|
-
}
|
|
1147
|
-
/** v29 — durable review-comment anchor disposition. v28 is already released, so this corrects both fresh and migrated databases without rewriting its historical schema. */
|
|
1148
|
-
function addReviewCommentAnchorState(db) {
|
|
1149
|
-
db.exec(`
|
|
357
|
+
`)}i(Pe,"addReviewCommentTables");function be(e){e.exec(`
|
|
1150
358
|
ALTER TABLE review_comments
|
|
1151
359
|
ADD COLUMN anchor_state TEXT NOT NULL DEFAULT 'live' CHECK (anchor_state IN ('live', 'detached'));
|
|
1152
|
-
`);
|
|
1153
|
-
}
|
|
1154
|
-
/** v30 — remove the retired human-work receipt table after every runtime reader is gone. */
|
|
1155
|
-
function dropConsultOutbox(db) {
|
|
1156
|
-
db.exec('DROP TABLE IF EXISTS consult_outbox');
|
|
1157
|
-
}
|
|
1158
|
-
/** v31 — a human's submit intent recorded on a still-open review, so the
|
|
1159
|
-
* approval can wait for the companion to stop working. Deliberately a column
|
|
1160
|
-
* and not a new `state` value: through the wait the review IS open — comments
|
|
1161
|
-
* still land, ranges still remap, and cancellation still applies. */
|
|
1162
|
-
function addReviewSubmitRequested(db) {
|
|
1163
|
-
db.exec('ALTER TABLE reviews ADD COLUMN submit_requested_at TEXT');
|
|
1164
|
-
}
|
|
1165
|
-
/** v32 — held crons (the exit-75 owed-gate disposition). `held` marks a row
|
|
1166
|
-
* whose last scheduled run exited 75 ("owed but not currently eligible"):
|
|
1167
|
-
* the occurrence was not spent and the row waits for an eligibility poke or
|
|
1168
|
-
* its natural backstop slot. `last_poke_at` records the most recent
|
|
1169
|
-
* `POST /v1/crons/poke` receipt on EVERY row, closing the race where a poke
|
|
1170
|
-
* lands while a gate check is in flight (the settling run compares its start
|
|
1171
|
-
* against it and re-dues instead of parking). Deliberately not part of the
|
|
1172
|
-
* due query: a held row is non-due by `fire_at`, never by a new predicate. */
|
|
1173
|
-
function addCronHeldColumns(db) {
|
|
1174
|
-
db.exec(`
|
|
360
|
+
`)}i(be,"addReviewCommentAnchorState");function Ye(e){e.exec("DROP TABLE IF EXISTS consult_outbox")}i(Ye,"dropConsultOutbox");function $e(e){e.exec("ALTER TABLE reviews ADD COLUMN submit_requested_at TEXT")}i($e,"addReviewSubmitRequested");function We(e){e.exec(`
|
|
1175
361
|
ALTER TABLE crons ADD COLUMN held INTEGER NOT NULL DEFAULT 0;
|
|
1176
362
|
ALTER TABLE crons ADD COLUMN last_poke_at TEXT;
|
|
1177
|
-
`);
|
|
1178
|
-
}
|
|
1179
|
-
/** v33 — durable, daemon-owned attempts to deliver settled human completions. */
|
|
1180
|
-
function addHumanActionDeliveries(db) {
|
|
1181
|
-
db.exec(`
|
|
363
|
+
`)}i(We,"addCronHeldColumns");function Ke(e){e.exec(`
|
|
1182
364
|
CREATE TABLE human_action_deliveries (
|
|
1183
365
|
request_id TEXT PRIMARY KEY,
|
|
1184
366
|
state TEXT NOT NULL,
|
|
@@ -1196,128 +378,18 @@ CREATE TABLE human_action_deliveries (
|
|
|
1196
378
|
updated_at INTEGER NOT NULL
|
|
1197
379
|
);
|
|
1198
380
|
CREATE INDEX idx_human_action_deliveries_due ON human_action_deliveries(state, next_attempt_at);
|
|
1199
|
-
`);
|
|
1200
|
-
}
|
|
1201
|
-
/** v34 — index the exact Pi session file coordinate used to recover fork
|
|
1202
|
-
* exposure provenance without hydrating every node meta. Meta remains authoritative;
|
|
1203
|
-
* normal identity upserts keep this projection current after the one-time backfill. */
|
|
1204
|
-
function addNodeSessionFileIndex(db) {
|
|
1205
|
-
const columns = nodeColumns(db);
|
|
1206
|
-
addNodeColumnIfMissing(db, columns, 'pi_session_file', 'ALTER TABLE nodes ADD COLUMN pi_session_file TEXT;');
|
|
1207
|
-
for (const entry of readdirSync(nodesRoot(), { withFileTypes: true })) {
|
|
1208
|
-
if (!entry.isDirectory())
|
|
1209
|
-
continue;
|
|
1210
|
-
try {
|
|
1211
|
-
const meta = JSON.parse(readFileSync(nodeMetaPath(entry.name), 'utf8'));
|
|
1212
|
-
if (typeof meta.pi_session_file === 'string') {
|
|
1213
|
-
db.prepare('UPDATE nodes SET pi_session_file = ? WHERE node_id = ?').run(meta.pi_session_file, entry.name);
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
catch {
|
|
1217
|
-
// Corrupt node metadata is ignored by the ordinary canvas rebuild too.
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
db.exec('CREATE INDEX IF NOT EXISTS idx_nodes_pi_session_file ON nodes(pi_session_file);');
|
|
1221
|
-
}
|
|
1222
|
-
/** Reproject the derived session-file index from authoritative node metadata.
|
|
1223
|
-
* v36 may resolve duplicate authoritative claimants because it runs before the
|
|
1224
|
-
* first UNIQUE index exists. v37 must retain every surviving meta claim: a
|
|
1225
|
-
* conflict at that later boundary is irreconcilable and fails instead. */
|
|
1226
|
-
function reconcileNodeSessionFileOwners(db, clearDuplicateMetaClaimants) {
|
|
1227
|
-
const canonical = (sessionFile) => {
|
|
1228
|
-
const absolute = resolve(sessionFile);
|
|
1229
|
-
return existsSync(absolute) ? realpathSync(absolute) : absolute;
|
|
1230
|
-
};
|
|
1231
|
-
const setFile = db.prepare('UPDATE nodes SET pi_session_file = ? WHERE node_id = ?');
|
|
1232
|
-
db.exec('DROP INDEX IF EXISTS idx_nodes_pi_session_file;');
|
|
1233
|
-
const rows = db.prepare('SELECT node_id FROM nodes ORDER BY created ASC, node_id ASC').all();
|
|
1234
|
-
for (const { node_id } of rows) {
|
|
1235
|
-
const metaPath = nodeMetaPath(node_id);
|
|
1236
|
-
// Missing or unreadable metadata has no authoritative coordinate. Avoid
|
|
1237
|
-
// taking a file lock there: old rows can outlive a removed node directory.
|
|
1238
|
-
if (readMetaObject(metaPath) === null) {
|
|
1239
|
-
setFile.run(null, node_id);
|
|
1240
|
-
continue;
|
|
1241
|
-
}
|
|
1242
|
-
const sessionFile = withMetaLock(metaPath, () => {
|
|
1243
|
-
const meta = readMetaObject(metaPath);
|
|
1244
|
-
if (meta === null)
|
|
1245
|
-
throw new Error(`node ${node_id} session metadata changed during ownership migration`);
|
|
1246
|
-
if (typeof meta['pi_session_file'] !== 'string')
|
|
1247
|
-
return null;
|
|
1248
|
-
const storedSessionFile = meta['pi_session_file'];
|
|
1249
|
-
const normalizedSessionFile = canonical(storedSessionFile);
|
|
1250
|
-
if (normalizedSessionFile !== storedSessionFile) {
|
|
1251
|
-
meta['pi_session_file'] = normalizedSessionFile;
|
|
1252
|
-
writeMetaObjectLocked(metaPath, meta);
|
|
1253
|
-
}
|
|
1254
|
-
return normalizedSessionFile;
|
|
1255
|
-
});
|
|
1256
|
-
// meta.json is authoritative: a crash after its write can leave this row
|
|
1257
|
-
// claiming another node's old session coordinate.
|
|
1258
|
-
setFile.run(sessionFile, node_id);
|
|
1259
|
-
}
|
|
1260
|
-
const duplicates = db.prepare(`
|
|
381
|
+
`)}i(Ke,"addHumanActionDeliveries");function qe(e){const n=l(e);a(e,n,"pi_session_file","ALTER TABLE nodes ADD COLUMN pi_session_file TEXT;");for(const t of X(S(),{withFileTypes:!0}))if(t.isDirectory())try{const o=JSON.parse(h(I(t.name),"utf8"));typeof o.pi_session_file=="string"&&e.prepare("UPDATE nodes SET pi_session_file = ? WHERE node_id = ?").run(o.pi_session_file,t.name)}catch{}e.exec("CREATE INDEX IF NOT EXISTS idx_nodes_pi_session_file ON nodes(pi_session_file);")}i(qe,"addNodeSessionFileIndex");function j(e,n){const t=i(E=>{const d=H(E);return A(d)?ne(d):d},"canonical"),o=e.prepare("UPDATE nodes SET pi_session_file = ? WHERE node_id = ?");e.exec("DROP INDEX IF EXISTS idx_nodes_pi_session_file;");const s=e.prepare("SELECT node_id FROM nodes ORDER BY created ASC, node_id ASC").all();for(const{node_id:E}of s){const d=I(E);if(P(d)===null){o.run(null,E);continue}const _=Te(d,()=>{const c=P(d);if(c===null)throw new Error(`node ${E} session metadata changed during ownership migration`);if(typeof c.pi_session_file!="string")return null;const N=c.pi_session_file,u=t(N);return u!==N&&(c.pi_session_file=u,Ee(d,c)),u});o.run(_,E)}const T=e.prepare(`
|
|
1261
382
|
SELECT pi_session_file
|
|
1262
383
|
FROM nodes
|
|
1263
384
|
WHERE pi_session_file IS NOT NULL
|
|
1264
385
|
GROUP BY pi_session_file
|
|
1265
386
|
HAVING COUNT(*) > 1
|
|
1266
|
-
`).all();
|
|
1267
|
-
if (!clearDuplicateMetaClaimants && duplicates.length > 0) {
|
|
1268
|
-
const coordinates = duplicates.map(({ pi_session_file }) => pi_session_file).join(', ');
|
|
1269
|
-
throw new Error(`cannot restore unique Pi session ownership: authoritative metadata has concurrent claimants for ${coordinates}`);
|
|
1270
|
-
}
|
|
1271
|
-
const clearRow = db.prepare('UPDATE nodes SET pi_session_file = NULL WHERE node_id = ?');
|
|
1272
|
-
for (const { pi_session_file } of duplicates) {
|
|
1273
|
-
const owners = db.prepare(`
|
|
387
|
+
`).all();if(!n&&T.length>0){const E=T.map(({pi_session_file:d})=>d).join(", ");throw new Error(`cannot restore unique Pi session ownership: authoritative metadata has concurrent claimants for ${E}`)}const r=e.prepare("UPDATE nodes SET pi_session_file = NULL WHERE node_id = ?");for(const{pi_session_file:E}of T){const d=e.prepare(`
|
|
1274
388
|
SELECT node_id
|
|
1275
389
|
FROM nodes
|
|
1276
390
|
WHERE pi_session_file = ?
|
|
1277
391
|
ORDER BY created ASC, node_id ASC
|
|
1278
|
-
`).all(pi_session_file);
|
|
1279
|
-
for (const { node_id } of owners.slice(1)) {
|
|
1280
|
-
// Clear both durable coordinates so a later reindex cannot restore the
|
|
1281
|
-
// duplicate projection. The checked write fails rather than erasing a
|
|
1282
|
-
// concurrent metadata change.
|
|
1283
|
-
const cleared = updateJsonFileDurably(nodeMetaPath(node_id), (meta) => {
|
|
1284
|
-
const currentSessionFile = meta['pi_session_file'];
|
|
1285
|
-
if (typeof currentSessionFile !== 'string' || canonical(currentSessionFile) !== pi_session_file) {
|
|
1286
|
-
throw new Error(`node ${node_id} session metadata changed during ownership migration`);
|
|
1287
|
-
}
|
|
1288
|
-
meta['pi_session_id'] = null;
|
|
1289
|
-
meta['pi_session_file'] = null;
|
|
1290
|
-
return true;
|
|
1291
|
-
});
|
|
1292
|
-
if (!cleared)
|
|
1293
|
-
throw new Error(`node ${node_id} session metadata changed during ownership migration`);
|
|
1294
|
-
clearRow.run(node_id);
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_nodes_pi_session_file ON nodes(pi_session_file);');
|
|
1298
|
-
}
|
|
1299
|
-
/** v36 — one Pi transcript may have exactly one node owner. This is the narrow
|
|
1300
|
-
* corrective body for clients below v36; it reprojects metadata before choosing
|
|
1301
|
-
* the earliest created duplicate claimant (node_id breaks equal timestamps). */
|
|
1302
|
-
function makeNodeSessionFileUnique(db) {
|
|
1303
|
-
reconcileNodeSessionFileOwners(db, true);
|
|
1304
|
-
}
|
|
1305
|
-
/** v37 — repair v0.3.250's already-applied v36 projection without inventing
|
|
1306
|
-
* coordinates v36 already cleared. Surviving authoritative metadata wins over
|
|
1307
|
-
* stale rows; concurrent surviving claims fail loudly rather than clearing one. */
|
|
1308
|
-
function repairNodeSessionFileUniqueIndex(db) {
|
|
1309
|
-
reconcileNodeSessionFileOwners(db, false);
|
|
1310
|
-
}
|
|
1311
|
-
/** v35 — durable node lifecycle execution state and terminal cause. */
|
|
1312
|
-
function addNodeLifecycleColumns(db) {
|
|
1313
|
-
const columns = nodeColumns(db);
|
|
1314
|
-
addNodeColumnIfMissing(db, columns, 'frozen_at', 'ALTER TABLE nodes ADD COLUMN frozen_at TEXT;');
|
|
1315
|
-
addNodeColumnIfMissing(db, columns, 'respawn_failures', 'ALTER TABLE nodes ADD COLUMN respawn_failures INTEGER NOT NULL DEFAULT 0;');
|
|
1316
|
-
addNodeColumnIfMissing(db, columns, 'respawn_not_before', 'ALTER TABLE nodes ADD COLUMN respawn_not_before TEXT;');
|
|
1317
|
-
addNodeColumnIfMissing(db, columns, 'launched_at', 'ALTER TABLE nodes ADD COLUMN launched_at TEXT;');
|
|
1318
|
-
addNodeColumnIfMissing(db, columns, 'last_settled_at', 'ALTER TABLE nodes ADD COLUMN last_settled_at TEXT;');
|
|
1319
|
-
addNodeColumnIfMissing(db, columns, 'terminal_reason', 'ALTER TABLE nodes ADD COLUMN terminal_reason TEXT;');
|
|
1320
|
-
db.exec(`
|
|
392
|
+
`).all(E);for(const{node_id:_}of d.slice(1)){if(!b(I(_),N=>{const u=N.pi_session_file;if(typeof u!="string"||t(u)!==E)throw new Error(`node ${_} session metadata changed during ownership migration`);return N.pi_session_id=null,N.pi_session_file=null,!0}))throw new Error(`node ${_} session metadata changed during ownership migration`);r.run(_)}}e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_nodes_pi_session_file ON nodes(pi_session_file);")}i(j,"reconcileNodeSessionFileOwners");function je(e){j(e,!0)}i(je,"makeNodeSessionFileUnique");function ze(e){j(e,!1)}i(ze,"repairNodeSessionFileUniqueIndex");function Je(e){const n=l(e);a(e,n,"frozen_at","ALTER TABLE nodes ADD COLUMN frozen_at TEXT;"),a(e,n,"respawn_failures","ALTER TABLE nodes ADD COLUMN respawn_failures INTEGER NOT NULL DEFAULT 0;"),a(e,n,"respawn_not_before","ALTER TABLE nodes ADD COLUMN respawn_not_before TEXT;"),a(e,n,"launched_at","ALTER TABLE nodes ADD COLUMN launched_at TEXT;"),a(e,n,"last_settled_at","ALTER TABLE nodes ADD COLUMN last_settled_at TEXT;"),a(e,n,"terminal_reason","ALTER TABLE nodes ADD COLUMN terminal_reason TEXT;"),e.exec(`
|
|
1321
393
|
UPDATE nodes SET terminal_reason = CASE
|
|
1322
394
|
WHEN status = 'done' AND final_report IS NOT NULL THEN 'finalized'
|
|
1323
395
|
WHEN status = 'done' AND intent = 'parked' THEN 'parked'
|
|
@@ -1326,51 +398,7 @@ UPDATE nodes SET terminal_reason = CASE
|
|
|
1326
398
|
WHEN status = 'dead' THEN 'crashed'
|
|
1327
399
|
END
|
|
1328
400
|
WHERE status IN ('done','canceled','dead') AND terminal_reason IS NULL;
|
|
1329
|
-
`);
|
|
1330
|
-
}
|
|
1331
|
-
/** v38 — mirror the two display-identity fields (`description`, `cycles`) that
|
|
1332
|
-
* lived ONLY in meta.json onto the row, completing the identity projection the
|
|
1333
|
-
* row index already is. Before this, every roster read that wanted a node's full
|
|
1334
|
-
* label had to open and parse each node's meta.json (a per-node disk read on a
|
|
1335
|
-
* path that already had all the other columns in one query). The backfill reads
|
|
1336
|
-
* each meta once; from here `upsertRow`/`seedRow` maintain them like any other
|
|
1337
|
-
* identity column, and `rebuildIndex` re-derives them. */
|
|
1338
|
-
function addNodeLabelColumns(db) {
|
|
1339
|
-
const columns = nodeColumns(db);
|
|
1340
|
-
addNodeColumnIfMissing(db, columns, 'description', 'ALTER TABLE nodes ADD COLUMN description TEXT;');
|
|
1341
|
-
addNodeColumnIfMissing(db, columns, 'cycles', 'ALTER TABLE nodes ADD COLUMN cycles INTEGER;');
|
|
1342
|
-
const root = nodesRoot();
|
|
1343
|
-
if (!existsSync(root))
|
|
1344
|
-
return;
|
|
1345
|
-
const upd = db.prepare('UPDATE nodes SET description = ?, cycles = ? WHERE node_id = ?');
|
|
1346
|
-
for (const id of readdirSync(root)) {
|
|
1347
|
-
const p = nodeMetaPath(id);
|
|
1348
|
-
if (!existsSync(p))
|
|
1349
|
-
continue;
|
|
1350
|
-
let meta;
|
|
1351
|
-
try {
|
|
1352
|
-
meta = JSON.parse(readFileSync(p, 'utf8'));
|
|
1353
|
-
}
|
|
1354
|
-
catch {
|
|
1355
|
-
continue; // a single unreadable meta never aborts the migration
|
|
1356
|
-
}
|
|
1357
|
-
const description = typeof meta['description'] === 'string' ? meta['description'] : null;
|
|
1358
|
-
const cycles = typeof meta['cycles'] === 'number' ? meta['cycles'] : null;
|
|
1359
|
-
upd.run(description, cycles, id);
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
/** v39 — durable terminal outcomes, spawn deadlines, and externally-owned
|
|
1363
|
-
* outcome-delivery attempts. The outcome columns live on `nodes` so the same
|
|
1364
|
-
* conditional terminal-status UPDATE can latch them atomically. */
|
|
1365
|
-
function addNodeOutcomeAndDeadline(db) {
|
|
1366
|
-
const columns = nodeColumns(db);
|
|
1367
|
-
addNodeColumnIfMissing(db, columns, 'outcome_kind', 'ALTER TABLE nodes ADD COLUMN outcome_kind TEXT;');
|
|
1368
|
-
addNodeColumnIfMissing(db, columns, 'outcome_reason', 'ALTER TABLE nodes ADD COLUMN outcome_reason TEXT;');
|
|
1369
|
-
addNodeColumnIfMissing(db, columns, 'outcome_at', 'ALTER TABLE nodes ADD COLUMN outcome_at TEXT;');
|
|
1370
|
-
addNodeColumnIfMissing(db, columns, 'outcome_revision', 'ALTER TABLE nodes ADD COLUMN outcome_revision INTEGER NOT NULL DEFAULT 0;');
|
|
1371
|
-
addNodeColumnIfMissing(db, columns, 'outcome_detail_json', 'ALTER TABLE nodes ADD COLUMN outcome_detail_json TEXT;');
|
|
1372
|
-
addNodeColumnIfMissing(db, columns, 'deadline_at', 'ALTER TABLE nodes ADD COLUMN deadline_at TEXT;');
|
|
1373
|
-
db.exec(`
|
|
401
|
+
`)}i(Je,"addNodeLifecycleColumns");function Qe(e){const n=l(e);a(e,n,"description","ALTER TABLE nodes ADD COLUMN description TEXT;"),a(e,n,"cycles","ALTER TABLE nodes ADD COLUMN cycles INTEGER;");const t=S();if(!A(t))return;const o=e.prepare("UPDATE nodes SET description = ?, cycles = ? WHERE node_id = ?");for(const s of X(t)){const T=I(s);if(!A(T))continue;let r;try{r=JSON.parse(h(T,"utf8"))}catch{continue}const E=typeof r.description=="string"?r.description:null,d=typeof r.cycles=="number"?r.cycles:null;o.run(E,d,s)}}i(Qe,"addNodeLabelColumns");function Ve(e){const n=l(e);a(e,n,"outcome_kind","ALTER TABLE nodes ADD COLUMN outcome_kind TEXT;"),a(e,n,"outcome_reason","ALTER TABLE nodes ADD COLUMN outcome_reason TEXT;"),a(e,n,"outcome_at","ALTER TABLE nodes ADD COLUMN outcome_at TEXT;"),a(e,n,"outcome_revision","ALTER TABLE nodes ADD COLUMN outcome_revision INTEGER NOT NULL DEFAULT 0;"),a(e,n,"outcome_detail_json","ALTER TABLE nodes ADD COLUMN outcome_detail_json TEXT;"),a(e,n,"deadline_at","ALTER TABLE nodes ADD COLUMN deadline_at TEXT;"),e.exec(`
|
|
1374
402
|
CREATE TABLE IF NOT EXISTS node_outcome_deliveries (
|
|
1375
403
|
node_id TEXT PRIMARY KEY,
|
|
1376
404
|
state TEXT NOT NULL,
|
|
@@ -1403,141 +431,4 @@ UPDATE nodes SET outcome_kind='failure',
|
|
|
1403
431
|
outcome_reason=COALESCE(terminal_reason,'crashed'),
|
|
1404
432
|
outcome_at=COALESCE(finalized_at, created), outcome_revision=1
|
|
1405
433
|
WHERE final_report IS NULL AND status IN ('done','dead','canceled') AND outcome_at IS NULL;
|
|
1406
|
-
`);
|
|
1407
|
-
}
|
|
1408
|
-
/** The journaled lane of the state-migration registry, adapted to this chain's
|
|
1409
|
-
* step shape. Registry order is preserved, so these versions stay stable as
|
|
1410
|
-
* long as the registry is append-only (same contract as the local list). */
|
|
1411
|
-
const JOURNALED_STATE_MIGRATIONS = STATE_MIGRATIONS
|
|
1412
|
-
.filter((m) => m.lane === 'journaled')
|
|
1413
|
-
.map((m) => (db) => m.apply(db, crtrHome()));
|
|
1414
|
-
/** The ordered migration list. Index `i` is migration version `i + 1`; the db's
|
|
1415
|
-
* `user_version` tracks how many have been applied. Append only. Journaled
|
|
1416
|
-
* entries from `src/migrations/registry.ts` follow the local steps, so a new
|
|
1417
|
-
* registry migration lands as the next version. */
|
|
1418
|
-
export const MIGRATIONS = [
|
|
1419
|
-
/* v1 */ baselineSchema,
|
|
1420
|
-
/* v2 */ addRuntimeColumns,
|
|
1421
|
-
/* v3 */ backfillRuntime,
|
|
1422
|
-
/* v4 */ edgesForeignKeyCascade,
|
|
1423
|
-
/* v5 */ addPaneColumn,
|
|
1424
|
-
/* v6 */ addFocusesTable,
|
|
1425
|
-
/* v7 */ appendWakeupsTable,
|
|
1426
|
-
/* v8 */ addHostKindColumn,
|
|
1427
|
-
/* v9 */ migrateWakeupsToTriggers,
|
|
1428
|
-
/* v10 */ addCanvasMetaTable,
|
|
1429
|
-
/* v11 */ addProfileIdColumn,
|
|
1430
|
-
/* v12 */ addPidIdentityColumn,
|
|
1431
|
-
/* v13 */ addMessageWaitColumn,
|
|
1432
|
-
/* v14 */ addCanonicalFinalColumns,
|
|
1433
|
-
/* v15 */ normalizePersistedLaunchExtensions,
|
|
1434
|
-
// Repair databases that reached v15 through the concurrent launch-metadata
|
|
1435
|
-
// migration before canonical finalization joined the ordered mainline.
|
|
1436
|
-
/* v16 */ addCanonicalFinalColumns,
|
|
1437
|
-
/* v17 */ addMessageWaitGenerationColumn,
|
|
1438
|
-
/* v18 */ addHumanWorkOutboxTable,
|
|
1439
|
-
/* v19 */ addHumanWorkColumns,
|
|
1440
|
-
/* v20 */ addNodeParentCreatedIndexes,
|
|
1441
|
-
/* v21 */ addCronsTables,
|
|
1442
|
-
/* v22 */ migrateTriggersToCrons,
|
|
1443
|
-
/* v23 */ addCronRunPidIdentityColumn,
|
|
1444
|
-
/* v24 */ addCronOutOfBandColumn,
|
|
1445
|
-
/* v25 */ addWarmPoolTable,
|
|
1446
|
-
/* v26 */ narrowHumanWorkOutbox,
|
|
1447
|
-
/* v27 */ addReviewsTable,
|
|
1448
|
-
/* v28 */ addReviewCommentTables,
|
|
1449
|
-
/* v29 */ addReviewCommentAnchorState,
|
|
1450
|
-
/* v30 */ dropConsultOutbox,
|
|
1451
|
-
/* v31 */ addReviewSubmitRequested,
|
|
1452
|
-
/* v32 */ addCronHeldColumns,
|
|
1453
|
-
/* v33 */ addHumanActionDeliveries,
|
|
1454
|
-
/* v34 */ addNodeSessionFileIndex,
|
|
1455
|
-
/* v35 */ addNodeLifecycleColumns,
|
|
1456
|
-
/* v36 */ makeNodeSessionFileUnique,
|
|
1457
|
-
/* v37 */ repairNodeSessionFileUniqueIndex,
|
|
1458
|
-
/* v38 */ addNodeLabelColumns,
|
|
1459
|
-
/* v39 */ addNodeOutcomeAndDeadline,
|
|
1460
|
-
...JOURNALED_STATE_MIGRATIONS,
|
|
1461
|
-
(db) => {
|
|
1462
|
-
importNodeSqlAuthority(db);
|
|
1463
|
-
migrateRecoveryWitnesses(db);
|
|
1464
|
-
migrateMessagingState(db);
|
|
1465
|
-
migrateHumanRequestsState(db);
|
|
1466
|
-
},
|
|
1467
|
-
];
|
|
1468
|
-
/** Migration indexes that manage their OWN transaction and therefore must not
|
|
1469
|
-
* be wrapped by `migrate()` — `node:sqlite` rejects a nested BEGIN. Index 3
|
|
1470
|
-
* (v4, the edges FK rebuild) both BEGINs internally and toggles
|
|
1471
|
-
* `PRAGMA foreign_keys`, which is a no-op inside a transaction. Its docblock
|
|
1472
|
-
* documents its own crash-safety: a partial rebuild rolls back and a re-run
|
|
1473
|
-
* over an already-rebuilt table is idempotent. (Entering `migrate()` from
|
|
1474
|
-
* INSIDE a caller's transaction with `user_version` still at 3 would make that
|
|
1475
|
-
* internal BEGIN nest and throw; daemon startup calls it in autocommit.) */
|
|
1476
|
-
const SELF_TRANSACTIONAL_MIGRATIONS = new Set([3]);
|
|
1477
|
-
function currentUserVersion(db) {
|
|
1478
|
-
return db.prepare('PRAGMA user_version').get().user_version;
|
|
1479
|
-
}
|
|
1480
|
-
function applyMigration(db, v) {
|
|
1481
|
-
MIGRATIONS[v](db);
|
|
1482
|
-
// `user_version` takes no bound parameters; v is a controlled integer.
|
|
1483
|
-
db.exec(`PRAGMA user_version = ${v + 1}`);
|
|
1484
|
-
}
|
|
1485
|
-
/** Bring `db` up to the latest schema version. Reads `user_version`, runs each
|
|
1486
|
-
* pending migration in order, and bumps `user_version` after each so the work
|
|
1487
|
-
* is gated and idempotent: re-running is a no-op once `user_version` reaches
|
|
1488
|
-
* `MIGRATIONS.length`. Forward-only.
|
|
1489
|
-
*
|
|
1490
|
-
* ATOMIC AND RESTARTABLE: each step AND its `user_version` bump run inside one
|
|
1491
|
-
* `BEGIN IMMEDIATE`/`COMMIT` (SQLite journals `user_version` with the
|
|
1492
|
-
* transaction, so a rollback restores it too). An interrupted or failing step
|
|
1493
|
-
* therefore leaves the db exactly at the previous version with none of its
|
|
1494
|
-
* writes committed — a half-applied step can never wedge every later open. The
|
|
1495
|
-
* write lock also serializes concurrent openers; the version is re-read after
|
|
1496
|
-
* acquiring it so a step another process just applied is skipped rather than
|
|
1497
|
-
* re-run. */
|
|
1498
|
-
export function migrate(db) {
|
|
1499
|
-
const version = currentUserVersion(db);
|
|
1500
|
-
if (version > MIGRATIONS.length) {
|
|
1501
|
-
throw new Error(`unsupported canvas schema version ${version} (latest supported ${MIGRATIONS.length})`);
|
|
1502
|
-
}
|
|
1503
|
-
if (version === MIGRATIONS.length)
|
|
1504
|
-
return;
|
|
1505
|
-
// Pending work: a step now holds the write lock for its whole duration, and
|
|
1506
|
-
// the fs-heavy legacy steps (v3/v14/v15) can outlast the ordinary 5s busy
|
|
1507
|
-
// timeout. Let concurrent openers WAIT for the migration rather than fail.
|
|
1508
|
-
const priorTimeout = db.prepare('PRAGMA busy_timeout').get().timeout;
|
|
1509
|
-
db.exec('PRAGMA busy_timeout = 60000;');
|
|
1510
|
-
try {
|
|
1511
|
-
runPendingMigrations(db);
|
|
1512
|
-
}
|
|
1513
|
-
finally {
|
|
1514
|
-
db.exec(`PRAGMA busy_timeout = ${priorTimeout};`);
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
function runPendingMigrations(db) {
|
|
1518
|
-
for (;;) {
|
|
1519
|
-
const v = currentUserVersion(db);
|
|
1520
|
-
if (v >= MIGRATIONS.length)
|
|
1521
|
-
return;
|
|
1522
|
-
// Already inside a caller's transaction (or a self-transactional step):
|
|
1523
|
-
// run bare rather than nesting a BEGIN node:sqlite would reject.
|
|
1524
|
-
if (db.isTransaction || SELF_TRANSACTIONAL_MIGRATIONS.has(v)) {
|
|
1525
|
-
applyMigration(db, v);
|
|
1526
|
-
continue;
|
|
1527
|
-
}
|
|
1528
|
-
db.exec('BEGIN IMMEDIATE');
|
|
1529
|
-
try {
|
|
1530
|
-
// Another process may have applied this step while we waited on the lock.
|
|
1531
|
-
if (currentUserVersion(db) === v)
|
|
1532
|
-
applyMigration(db, v);
|
|
1533
|
-
db.exec('COMMIT');
|
|
1534
|
-
}
|
|
1535
|
-
catch (err) {
|
|
1536
|
-
try {
|
|
1537
|
-
db.exec('ROLLBACK');
|
|
1538
|
-
}
|
|
1539
|
-
catch { /* transaction was already closed */ }
|
|
1540
|
-
throw err;
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
434
|
+
`)}i(Ve,"addNodeOutcomeAndDeadline");const Ze=re.filter(e=>e.lane==="journaled").map(e=>n=>e.apply(n,oe())),g=[ae,de,_e,ce,Ne,ue,le,pe,Le,Oe,Ae,fe,Re,$,me,$,Ie,Xe,Se,Ue,ge,Fe,ke,Me,Ge,Be,He,Pe,be,Ye,$e,We,Ke,qe,Je,je,ze,Qe,Ve,...Ze,e=>{Q(e),V(e),Z(e),ee(e)}],en=new Set([3]);function k(e){return e.prepare("PRAGMA user_version").get().user_version}i(k,"currentUserVersion");function z(e,n){g[n](e),e.exec(`PRAGMA user_version = ${n+1}`)}i(z,"applyMigration");function ln(e){const n=k(e);if(n>g.length)throw new Error(`unsupported canvas schema version ${n} (latest supported ${g.length})`);if(n===g.length)return;const t=e.prepare("PRAGMA busy_timeout").get().timeout;e.exec("PRAGMA busy_timeout = 60000;");try{nn(e)}finally{e.exec(`PRAGMA busy_timeout = ${t};`)}}i(ln,"migrate");function nn(e){for(;;){const n=k(e);if(n>=g.length)return;if(e.isTransaction||en.has(n)){z(e,n);continue}e.exec("BEGIN IMMEDIATE");try{k(e)===n&&z(e,n),e.exec("COMMIT")}catch(t){try{e.exec("ROLLBACK")}catch{}throw t}}}i(nn,"runPendingMigrations");export{g as MIGRATIONS,ln as migrate};
|