@north-light/crouter 0.3.318 → 0.3.320
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 +6 -4
- package/runtime.lock.json +5 -5
- package/scripts/pack-minify.mjs +108 -0
- 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,933 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
// worktrees are SQL-authoritative. Node directories hold only artifacts.
|
|
3
|
-
import { envNodeId } from '../../shared/env.js';
|
|
4
|
-
import { existsSync, realpathSync, rmSync, statSync } from 'node:fs';
|
|
5
|
-
import { join, resolve } from 'node:path';
|
|
6
|
-
import { openDb, withCanvasWrite } from './db.js';
|
|
7
|
-
import { activateArmedExternalActionDelivery, armExternalActionDelivery } from './deliveries.js';
|
|
8
|
-
import { findNodeBySessionFileSql } from './sessions.js';
|
|
9
|
-
import { readFault, readLiveTurn } from './recovery.js';
|
|
10
|
-
import { hasUnreconciledWorktree, openWorktree, readWorktree } from './worktrees.js';
|
|
11
|
-
import { isPidAlive, recordedPidLiveness } from './pid.js';
|
|
12
|
-
import { ensureHome, ensureNodeDirs, jobDir, nodeDir } from './paths.js';
|
|
13
|
-
function jsonValue(value, field) {
|
|
14
|
-
if (value === undefined || value === null)
|
|
15
|
-
return null;
|
|
16
|
-
const encoded = JSON.stringify(value);
|
|
17
|
-
if (encoded === undefined)
|
|
18
|
-
throw new TypeError(`${field} must be JSON-serializable`);
|
|
19
|
-
return encoded;
|
|
20
|
-
}
|
|
21
|
-
function insertArmedOutcomeDelivery(db, nodeId, delivery) {
|
|
22
|
-
armExternalActionDelivery(db, {
|
|
23
|
-
destinationId: delivery.actionName,
|
|
24
|
-
adapter: {
|
|
25
|
-
adapter: 'subprocess', argv: delivery.argv, cwd: delivery.cwd,
|
|
26
|
-
config_origin: delivery.configOrigin, payload: delivery.payload ?? null,
|
|
27
|
-
},
|
|
28
|
-
idempotencyKey: `node-outcome:${nodeId}`,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
function seedRow(meta, db) {
|
|
32
|
-
db.prepare(`INSERT INTO nodes (node_id, name, description, title, icon, cycles, kind, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, status, intent, waiting_for, final_report, finalized_at, deadline_at, "window", tmux_session, pane) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
33
|
-
.run(meta.node_id, meta.name, meta.description ?? null, meta.title ?? null, meta.icon ?? null, meta.cycles ?? null, meta.kind, meta.mode, meta.lifecycle, meta.cwd, meta.host_kind ?? null, meta.profile_id ?? null, meta.parent ?? null, meta.spawned_by ?? null, meta.creator ?? null, meta.fork_from ?? null, meta.fork_source_file ?? null, meta.created, meta.passive_default === true ? 1 : 0, meta.cycle_pending === true ? 1 : 0, meta.model_override ?? null, jsonValue(meta.persona_ack, 'persona_ack'), jsonValue(meta.review_binding, 'review_binding'), jsonValue(meta.launch, 'launch'), meta.status ?? 'active', meta.intent ?? null, meta.waiting_for ?? null, meta.final_report ?? null, meta.finalized_at ?? null, meta.deadline_at ?? null, meta.window ?? null, meta.tmux_session ?? null, meta.pane ?? null);
|
|
34
|
-
}
|
|
35
|
-
function rowFrom(r) {
|
|
36
|
-
const node = {
|
|
37
|
-
node_id: r['node_id'],
|
|
38
|
-
name: r['name'],
|
|
39
|
-
description: r['description'] ?? undefined,
|
|
40
|
-
cycles: r['cycles'] ?? undefined,
|
|
41
|
-
kind: r['kind'],
|
|
42
|
-
mode: r['mode'],
|
|
43
|
-
lifecycle: r['lifecycle'],
|
|
44
|
-
status: r['status'],
|
|
45
|
-
cwd: r['cwd'],
|
|
46
|
-
host_kind: r['host_kind'] ?? null,
|
|
47
|
-
profile_id: r['profile_id'] ?? null,
|
|
48
|
-
parent: r['parent'] ?? null,
|
|
49
|
-
created: r['created'],
|
|
50
|
-
intent: r['intent'] ?? null,
|
|
51
|
-
waiting_for: r['waiting_for'] ?? null,
|
|
52
|
-
frozen_at: r['frozen_at'] ?? null,
|
|
53
|
-
respawn_failures: r['respawn_failures'] ?? 0,
|
|
54
|
-
respawn_not_before: r['respawn_not_before'] ?? null,
|
|
55
|
-
launched_at: r['launched_at'] ?? null,
|
|
56
|
-
last_settled_at: r['last_settled_at'] ?? null,
|
|
57
|
-
terminal_reason: r['terminal_reason'] ?? null,
|
|
58
|
-
final_report: r['final_report'] ?? null,
|
|
59
|
-
finalized_at: r['finalized_at'] ?? null,
|
|
60
|
-
outcome_kind: r['outcome_kind'] ?? null,
|
|
61
|
-
outcome_reason: r['outcome_reason'] ?? null,
|
|
62
|
-
outcome_at: r['outcome_at'] ?? null,
|
|
63
|
-
outcome_revision: r['outcome_revision'] ?? 0,
|
|
64
|
-
outcome_detail_json: r['outcome_detail_json'] ?? null,
|
|
65
|
-
deadline_at: r['deadline_at'] ?? null,
|
|
66
|
-
pi_pid: r['pi_pid'] ?? null,
|
|
67
|
-
pi_pid_identity: r['pi_pid_identity'] ?? null,
|
|
68
|
-
window: r['window'] ?? null,
|
|
69
|
-
tmux_session: r['tmux_session'] ?? null,
|
|
70
|
-
pane: r['pane'] ?? null,
|
|
71
|
-
fault: null,
|
|
72
|
-
streaming: false,
|
|
73
|
-
};
|
|
74
|
-
const fault = readFault(node.node_id);
|
|
75
|
-
node.fault = fault?.link === 'pi→provider' && fault.retry.by === 'daemon' && fault.retry.disposition === 'auto' && !isPidAlive(node.pi_pid)
|
|
76
|
-
? null
|
|
77
|
-
: fault;
|
|
78
|
-
node.streaming = readLiveTurn(node.node_id)?.busy === true && isPidAlive(node.pi_pid);
|
|
79
|
-
return node;
|
|
80
|
-
}
|
|
81
|
-
// Nodes
|
|
82
|
-
/** Create a SQL-authoritative node, then ensure its artifact directories exist. */
|
|
83
|
-
export function createNode(meta, opts = {}) {
|
|
84
|
-
ensureHome();
|
|
85
|
-
withCanvasWrite((db) => {
|
|
86
|
-
seedRow(meta, db);
|
|
87
|
-
if (meta.managed_worktree !== undefined && meta.managed_worktree !== null)
|
|
88
|
-
openWorktree(meta.node_id, meta.managed_worktree, db);
|
|
89
|
-
if (opts.outcomeDelivery !== undefined)
|
|
90
|
-
insertArmedOutcomeDelivery(db, meta.node_id, opts.outcomeDelivery);
|
|
91
|
-
});
|
|
92
|
-
ensureNodeDirs(meta.node_id);
|
|
93
|
-
return getNode(meta.node_id);
|
|
94
|
-
}
|
|
95
|
-
/** The canonical node record, hydrated from SQL. Null if unknown. */
|
|
96
|
-
export function getNode(nodeId) {
|
|
97
|
-
const row = openDb().prepare('SELECT * FROM node_rows WHERE node_id = ?').get(nodeId);
|
|
98
|
-
if (row === undefined)
|
|
99
|
-
return null;
|
|
100
|
-
const worktree = readWorktree(nodeId);
|
|
101
|
-
return {
|
|
102
|
-
...rowFrom(row),
|
|
103
|
-
title: row['title'] ?? undefined,
|
|
104
|
-
icon: row['icon'] ?? undefined,
|
|
105
|
-
spawned_by: row['spawned_by'] ?? null,
|
|
106
|
-
creator: row['creator'] ?? null,
|
|
107
|
-
fork_from: row['fork_from'] ?? null,
|
|
108
|
-
fork_source_file: row['fork_source_file'] ?? null,
|
|
109
|
-
passive_default: row['passive_default'] === 1,
|
|
110
|
-
cycle_pending: row['cycle_pending'] === 1,
|
|
111
|
-
model_override: row['model_override'] ?? null,
|
|
112
|
-
persona_ack: row['persona_ack_json'] == null ? undefined : JSON.parse(row['persona_ack_json']),
|
|
113
|
-
review_binding: row['review_binding_json'] == null ? undefined : JSON.parse(row['review_binding_json']),
|
|
114
|
-
launch: row['launch_config_json'] == null ? undefined : JSON.parse(row['launch_config_json']),
|
|
115
|
-
pi_session_id: row['pi_session_id'] ?? null,
|
|
116
|
-
pi_session_file: row['pi_session_file'] ?? null,
|
|
117
|
-
...(worktree === null ? {} : { managed_worktree: worktree }),
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
export function canonicalSessionFile(sessionFile) {
|
|
121
|
-
const absolute = resolve(sessionFile);
|
|
122
|
-
return existsSync(absolute) ? realpathSync(absolute) : absolute;
|
|
123
|
-
}
|
|
124
|
-
/** Resolve the crouter node that owns one exact Pi session file. */
|
|
125
|
-
export function findNodeBySessionFile(sessionFile) {
|
|
126
|
-
const nodeId = findNodeBySessionFileSql(sessionFile);
|
|
127
|
-
return nodeId === null ? null : getNode(nodeId);
|
|
128
|
-
}
|
|
129
|
-
/** The indexed row (from the db) — cheap for queries that don't need full meta. */
|
|
130
|
-
export function getRow(nodeId) {
|
|
131
|
-
const r = openDb().prepare('SELECT * FROM node_rows WHERE node_id = ?').get(nodeId);
|
|
132
|
-
return r ? rowFrom(r) : null;
|
|
133
|
-
}
|
|
134
|
-
/** The node row whose durable LOCATION pane is `pane`, or null. Lets placement
|
|
135
|
-
* resolve "who sits in this pane" by the first-class `%pane_id` handle (e.g.
|
|
136
|
-
* to adopt a caller's pane as a focus). pane is not UNIQUE in the schema, but a
|
|
137
|
-
* live pane backs at most one node, so this returns the single match. */
|
|
138
|
-
export function getRowByPane(pane) {
|
|
139
|
-
const r = openDb().prepare('SELECT * FROM node_rows WHERE pane = ?').get(pane);
|
|
140
|
-
return r ? rowFrom(r) : null;
|
|
141
|
-
}
|
|
142
|
-
/** Nodes whose persisted spawn deadline has elapsed and that remain live work. */
|
|
143
|
-
export function dueNodeDeadlines(nowIso) {
|
|
144
|
-
return openDb().prepare(`SELECT * FROM node_rows
|
|
1
|
+
var x=Object.defineProperty;var o=(e,n)=>x(e,"name",{value:n,configurable:!0});import{envNodeId as O}from"../../shared/env.js";import{existsSync as W,realpathSync as k,rmSync as N,statSync as H}from"node:fs";import{join as F,resolve as M}from"node:path";import{openDb as s,withCanvasWrite as p}from"./db.js";import{activateArmedExternalActionDelivery as U,armExternalActionDelivery as j}from"./deliveries.js";import{findNodeBySessionFileSql as I}from"./sessions.js";import{readFault as P,readLiveTurn as C}from"./recovery.js";import{hasUnreconciledWorktree as $,openWorktree as B,readWorktree as z}from"./worktrees.js";import{isPidAlive as g,recordedPidLiveness as J}from"./pid.js";import{ensureHome as Y,ensureNodeDirs as q,jobDir as V,nodeDir as S}from"./paths.js";function E(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}o(E,"jsonValue");function h(e,n,t){j(e,{destinationId:t.actionName,adapter:{adapter:"subprocess",argv:t.argv,cwd:t.cwd,config_origin:t.configOrigin,payload:t.payload??null},idempotencyKey:`node-outcome:${n}`})}o(h,"insertArmedOutcomeDelivery");function G(e,n){n.prepare('INSERT INTO nodes (node_id, name, description, title, icon, cycles, kind, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, status, intent, waiting_for, final_report, finalized_at, deadline_at, "window", tmux_session, pane) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').run(e.node_id,e.name,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.kind,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,E(e.persona_ack,"persona_ack"),E(e.review_binding,"review_binding"),E(e.launch,"launch"),e.status??"active",e.intent??null,e.waiting_for??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null)}o(G,"seedRow");function _(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=P(n.node_id);return n.fault=t?.link==="pi\u2192provider"&&t.retry.by==="daemon"&&t.retry.disposition==="auto"&&!g(n.pi_pid)?null:t,n.streaming=C(n.node_id)?.busy===!0&&g(n.pi_pid),n}o(_,"rowFrom");function ce(e,n={}){return Y(),p(t=>{G(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&B(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&h(t,e.node_id,n.outcomeDelivery)}),q(e.node_id),f(e.node_id)}o(ce,"createNode");function f(e){const n=s().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);if(n===void 0)return null;const t=z(e);return{..._(n),title:n.title??void 0,icon:n.icon??void 0,spawned_by:n.spawned_by??null,creator:n.creator??null,fork_from:n.fork_from??null,fork_source_file:n.fork_source_file??null,passive_default:n.passive_default===1,cycle_pending:n.cycle_pending===1,model_override:n.model_override??null,persona_ack:n.persona_ack_json==null?void 0:JSON.parse(n.persona_ack_json),review_binding:n.review_binding_json==null?void 0:JSON.parse(n.review_binding_json),launch:n.launch_config_json==null?void 0:JSON.parse(n.launch_config_json),pi_session_id:n.pi_session_id??null,pi_session_file:n.pi_session_file??null,...t===null?{}:{managed_worktree:t}}}o(f,"getNode");function pe(e){const n=M(e);return W(n)?k(n):n}o(pe,"canonicalSessionFile");function _e(e){const n=I(e);return n===null?null:f(n)}o(_e,"findNodeBySessionFile");function fe(e){const n=s().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?_(n):null}o(fe,"getRow");function Ee(e){const n=s().prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?_(n):null}o(Ee,"getRowByPane");function me(e){return s().prepare(`SELECT * FROM node_rows
|
|
145
2
|
WHERE deadline_at IS NOT NULL AND outcome_at IS NULL
|
|
146
3
|
AND deadline_at <= ? AND status IN ('active','idle') AND kind != 'human'
|
|
147
|
-
ORDER BY deadline_at, created, node_id`).all(
|
|
148
|
-
}
|
|
149
|
-
/** Write a claimed warm spare's deadline before it is handed to its caller. */
|
|
150
|
-
export function setNodeDeadline(nodeId, deadlineAt) {
|
|
151
|
-
return Number(openDb().prepare('UPDATE nodes SET deadline_at = ? WHERE node_id = ?').run(deadlineAt, nodeId).changes) === 1;
|
|
152
|
-
}
|
|
153
|
-
/** Shift active/idle profile deadlines by a completed profile pause duration. */
|
|
154
|
-
export function shiftProfileNodeDeadlines(profileId, pauseDurationMs) {
|
|
155
|
-
if (!Number.isFinite(pauseDurationMs) || pauseDurationMs <= 0)
|
|
156
|
-
return 0;
|
|
157
|
-
return withCanvasWrite((db) => {
|
|
158
|
-
const rows = db.prepare(`SELECT node_id, deadline_at FROM nodes
|
|
159
|
-
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(profileId);
|
|
160
|
-
const update = db.prepare('UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?');
|
|
161
|
-
let shifted = 0;
|
|
162
|
-
for (const row of rows) {
|
|
163
|
-
const at = Date.parse(row.deadline_at);
|
|
164
|
-
if (Number.isNaN(at))
|
|
165
|
-
continue;
|
|
166
|
-
shifted += Number(update.run(new Date(at + pauseDurationMs).toISOString(), row.node_id, row.deadline_at).changes);
|
|
167
|
-
}
|
|
168
|
-
return shifted;
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
function sqlInput(value, field) {
|
|
172
|
-
if (value === null || value === undefined)
|
|
173
|
-
return null;
|
|
174
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint' || value instanceof Uint8Array)
|
|
175
|
-
return value;
|
|
176
|
-
throw new TypeError(`${field} must be a SQLite scalar`);
|
|
177
|
-
}
|
|
178
|
-
/** Update node identity/configuration columns. Sessions and worktrees have named stores. */
|
|
179
|
-
export function updateNode(nodeId, patch) {
|
|
180
|
-
const fields = [];
|
|
181
|
-
const add = (key, column = key) => {
|
|
182
|
-
if (Object.prototype.hasOwnProperty.call(patch, key))
|
|
183
|
-
fields.push([column, sqlInput(patch[key], key)]);
|
|
184
|
-
};
|
|
185
|
-
add('name');
|
|
186
|
-
add('description');
|
|
187
|
-
add('title');
|
|
188
|
-
add('icon');
|
|
189
|
-
add('cycles');
|
|
190
|
-
add('kind');
|
|
191
|
-
add('mode');
|
|
192
|
-
add('lifecycle');
|
|
193
|
-
add('cwd');
|
|
194
|
-
add('host_kind');
|
|
195
|
-
add('profile_id');
|
|
196
|
-
add('parent');
|
|
197
|
-
add('spawned_by');
|
|
198
|
-
add('creator');
|
|
199
|
-
add('fork_from');
|
|
200
|
-
add('fork_source_file');
|
|
201
|
-
add('model_override');
|
|
202
|
-
if (Object.prototype.hasOwnProperty.call(patch, 'passive_default'))
|
|
203
|
-
fields.push(['passive_default', patch.passive_default === true ? 1 : 0]);
|
|
204
|
-
if (Object.prototype.hasOwnProperty.call(patch, 'cycle_pending'))
|
|
205
|
-
fields.push(['cycle_pending', patch.cycle_pending === true ? 1 : 0]);
|
|
206
|
-
if (Object.prototype.hasOwnProperty.call(patch, 'persona_ack'))
|
|
207
|
-
fields.push(['persona_ack_json', jsonValue(patch.persona_ack, 'persona_ack')]);
|
|
208
|
-
if (Object.prototype.hasOwnProperty.call(patch, 'review_binding'))
|
|
209
|
-
fields.push(['review_binding_json', jsonValue(patch.review_binding, 'review_binding')]);
|
|
210
|
-
if (Object.prototype.hasOwnProperty.call(patch, 'launch'))
|
|
211
|
-
fields.push(['launch_config_json', jsonValue(patch.launch, 'launch')]);
|
|
212
|
-
if (fields.length === 0) {
|
|
213
|
-
const existing = getNode(nodeId);
|
|
214
|
-
if (existing === null)
|
|
215
|
-
throw new Error(`unknown node: ${nodeId}`);
|
|
216
|
-
return existing;
|
|
217
|
-
}
|
|
218
|
-
const result = openDb().prepare(`UPDATE nodes SET ${fields.map(([column]) => `${column} = ?`).join(', ')} WHERE node_id = ?`).run(...fields.map(([, value]) => value), nodeId);
|
|
219
|
-
if (result.changes !== 1)
|
|
220
|
-
throw new Error(`unknown node: ${nodeId}`);
|
|
221
|
-
return getNode(nodeId);
|
|
222
|
-
}
|
|
223
|
-
// Atomic runtime setters — each one a single-statement UPDATE on the WAL'd row,
|
|
224
|
-
// the authoritative store for live state. No read-modify-write, so concurrent
|
|
225
|
-
// writers of DIFFERENT fields (the daemon stamping pi_pid while a node flips
|
|
226
|
-
// status) can never clobber each other: WAL serializes the two statements.
|
|
227
|
-
// `"window"` is quoted defensively — it is a SQLite keyword.
|
|
228
|
-
/** Set a node's status. Atomic single-column write. */
|
|
229
|
-
export function setStatus(nodeId, status) {
|
|
230
|
-
openDb().prepare('UPDATE nodes SET status = ? WHERE node_id = ?').run(status, nodeId);
|
|
231
|
-
}
|
|
232
|
-
/** Set a node's exit intent. Atomic single-column write. */
|
|
233
|
-
export function setIntent(nodeId, intent) {
|
|
234
|
-
openDb().prepare('UPDATE nodes SET intent = ? WHERE node_id = ?').run(intent ?? null, nodeId);
|
|
235
|
-
}
|
|
236
|
-
/** Atomically write status and/or intent, gated on an optional from-status set
|
|
237
|
-
* and/or on the row carrying no committed final_report. The lifecycle state
|
|
238
|
-
* machine (runtime/lifecycle.ts) is the one caller: it owns the legality
|
|
239
|
-
* table and the unknown-node/illegal-move/already-finalized-cancel branching,
|
|
240
|
-
* this only performs the single conditional UPDATE it needs. A PRESENT key in
|
|
241
|
-
* `fields` (even `intent: null`) writes that column; an ABSENT key leaves it
|
|
242
|
-
* unchanged. Returns the row-changed count so the caller can distinguish "no
|
|
243
|
-
* such node", "gate failed", and "already applied" without a second query. */
|
|
244
|
-
export function transitionStatusIntent(nodeId, fields, opts = {}) {
|
|
245
|
-
// Keep the ordinary lifecycle write exactly as its pre-outcome form: one
|
|
246
|
-
// conditional UPDATE and no transaction boundary.
|
|
247
|
-
if (opts.outcome === undefined) {
|
|
248
|
-
const assignments = [];
|
|
249
|
-
const values = [];
|
|
250
|
-
if (Object.prototype.hasOwnProperty.call(fields, 'status')) {
|
|
251
|
-
assignments.push('status = ?');
|
|
252
|
-
values.push(fields.status ?? null);
|
|
253
|
-
}
|
|
254
|
-
if (Object.prototype.hasOwnProperty.call(fields, 'intent')) {
|
|
255
|
-
assignments.push('intent = ?');
|
|
256
|
-
values.push(fields.intent ?? null);
|
|
257
|
-
}
|
|
258
|
-
if (Object.prototype.hasOwnProperty.call(fields, 'terminal_reason')) {
|
|
259
|
-
assignments.push('terminal_reason = ?');
|
|
260
|
-
values.push(fields.terminal_reason ?? null);
|
|
261
|
-
}
|
|
262
|
-
const predicates = ['node_id = ?'];
|
|
263
|
-
values.push(nodeId);
|
|
264
|
-
if (opts.fromStatuses !== undefined) {
|
|
265
|
-
predicates.push(`status IN (${opts.fromStatuses.map(() => '?').join(', ')})`);
|
|
266
|
-
values.push(...opts.fromStatuses);
|
|
267
|
-
}
|
|
268
|
-
if (opts.requireNoFinalReport === true)
|
|
269
|
-
predicates.push('final_report IS NULL');
|
|
270
|
-
const result = openDb()
|
|
271
|
-
.prepare(`UPDATE nodes SET ${assignments.join(', ')} WHERE ${predicates.join(' AND ')}`)
|
|
272
|
-
.run(...values);
|
|
273
|
-
return Number(result.changes);
|
|
274
|
-
}
|
|
275
|
-
const outcome = opts.outcome;
|
|
276
|
-
return withCanvasWrite((db) => {
|
|
277
|
-
const assignments = [];
|
|
278
|
-
const values = [];
|
|
279
|
-
if (Object.prototype.hasOwnProperty.call(fields, 'status')) {
|
|
280
|
-
assignments.push('status = ?');
|
|
281
|
-
values.push(fields.status ?? null);
|
|
282
|
-
}
|
|
283
|
-
if (Object.prototype.hasOwnProperty.call(fields, 'intent')) {
|
|
284
|
-
assignments.push('intent = ?');
|
|
285
|
-
values.push(fields.intent ?? null);
|
|
286
|
-
}
|
|
287
|
-
if (Object.prototype.hasOwnProperty.call(fields, 'terminal_reason')) {
|
|
288
|
-
assignments.push('terminal_reason = ?');
|
|
289
|
-
values.push(fields.terminal_reason ?? null);
|
|
290
|
-
}
|
|
291
|
-
const outcomeValue = (value, column) => outcome.supersede === true ? '?' : `CASE WHEN outcome_at IS NULL THEN ? ELSE ${column} END`;
|
|
292
|
-
assignments.push(`outcome_kind = ${outcomeValue(outcome.kind, 'outcome_kind')}`, `outcome_reason = ${outcomeValue(outcome.reason, 'outcome_reason')}`, `outcome_detail_json = ${outcomeValue(outcome.detailJson, 'outcome_detail_json')}`, `outcome_revision = ${outcome.supersede === true ? 'outcome_revision + 1' : 'CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END'}`, `outcome_at = ${outcomeValue(outcome.at, 'outcome_at')}`);
|
|
293
|
-
values.push(outcome.kind, outcome.reason, outcome.detailJson, outcome.at);
|
|
294
|
-
const predicates = ['node_id = ?'];
|
|
295
|
-
values.push(nodeId);
|
|
296
|
-
if (opts.fromStatuses !== undefined) {
|
|
297
|
-
predicates.push(`status IN (${opts.fromStatuses.map(() => '?').join(', ')})`);
|
|
298
|
-
values.push(...opts.fromStatuses);
|
|
299
|
-
}
|
|
300
|
-
if (opts.requireNoFinalReport === true)
|
|
301
|
-
predicates.push('final_report IS NULL');
|
|
302
|
-
const result = db.prepare(`UPDATE nodes SET ${assignments.join(', ')} WHERE ${predicates.join(' AND ')}`).run(...values);
|
|
303
|
-
if (Number(result.changes) === 0)
|
|
304
|
-
return 0;
|
|
305
|
-
const latched = db.prepare('SELECT outcome_at FROM nodes WHERE node_id = ?').get(nodeId);
|
|
306
|
-
if ((outcome.supersede === true || latched.outcome_at === outcome.at) && outcome.documentJson !== null && outcome.documentJson !== undefined) {
|
|
307
|
-
activateArmedExternalActionDelivery(db, {
|
|
308
|
-
idempotencyKey: `node-outcome:${nodeId}`,
|
|
309
|
-
label: nodeId,
|
|
310
|
-
bodyJson: outcome.documentJson,
|
|
311
|
-
supersede: outcome.supersede === true,
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
return Number(result.changes);
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
/** Read a node's committed-final latch pointer. Pure read, no side effect. */
|
|
318
|
-
export function getFinalReport(nodeId) {
|
|
319
|
-
const row = openDb().prepare('SELECT final_report FROM nodes WHERE node_id = ?').get(nodeId);
|
|
320
|
-
return row?.final_report ?? null;
|
|
321
|
-
}
|
|
322
|
-
/** CAS-clear a node's finalization latch (final_report + finalized_at) —
|
|
323
|
-
* retract-pointer-only. Gated on the exact final_report value the caller
|
|
324
|
-
* observed via getFinalReport, so a concurrent clear/refinalize can never be
|
|
325
|
-
* clobbered. Returns true iff the CAS matched and cleared. */
|
|
326
|
-
export function clearFinalReportIfMatches(nodeId, expectedFinalReport) {
|
|
327
|
-
const result = openDb()
|
|
328
|
-
.prepare('UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?')
|
|
329
|
-
.run(nodeId, expectedFinalReport);
|
|
330
|
-
return result.changes > 0;
|
|
331
|
-
}
|
|
332
|
-
/** Set a node's tmux presence in one atomic write: the durable LOCATION anchor
|
|
333
|
-
* `pane` (the `%pane_id`) plus its derived cache (`tmux_session` + `window`).
|
|
334
|
-
* All three move together — `pane` joins the others inside the single UPDATE so
|
|
335
|
-
* a move never half-writes the location. `pane` is optional: a caller that does
|
|
336
|
-
* not yet track it (every caller, until the placement layer lands) writes null,
|
|
337
|
-
* which is harmless because nothing reads `pane` yet. */
|
|
338
|
-
export function setPresence(nodeId, presence) {
|
|
339
|
-
openDb()
|
|
340
|
-
.prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?')
|
|
341
|
-
.run(presence.tmux_session ?? null, presence.window ?? null, presence.pane ?? null, nodeId);
|
|
342
|
-
}
|
|
343
|
-
export function recordLaunch(nodeId, at) {
|
|
344
|
-
openDb()
|
|
345
|
-
.prepare('UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?')
|
|
346
|
-
.run(at, nodeId);
|
|
347
|
-
}
|
|
348
|
-
export function recordSettledTurn(nodeId, at) {
|
|
349
|
-
openDb().prepare('UPDATE nodes SET last_settled_at = ? WHERE node_id = ?').run(at, nodeId);
|
|
350
|
-
}
|
|
351
|
-
export function setFrozen(nodeId, at) {
|
|
352
|
-
openDb().prepare('UPDATE nodes SET frozen_at = ? WHERE node_id = ?').run(at, nodeId);
|
|
353
|
-
}
|
|
354
|
-
export function clearFrozen(nodeId) {
|
|
355
|
-
openDb().prepare('UPDATE nodes SET frozen_at = NULL WHERE node_id = ?').run(nodeId);
|
|
356
|
-
}
|
|
357
|
-
export function recordRespawnAttempt(nodeId, attempt) {
|
|
358
|
-
openDb()
|
|
359
|
-
.prepare('UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?')
|
|
360
|
-
.run(attempt.failures, attempt.notBefore, nodeId);
|
|
361
|
-
}
|
|
362
|
-
/** The one clause that hides unclaimed warm-pool spares from every listing.
|
|
363
|
-
* A spare is a real node with a booted broker, but nobody has been handed it
|
|
364
|
-
* yet — surfacing it would put a phantom empty conversation in the user's
|
|
365
|
-
* sidebar. Claiming deletes the marker, which is what makes the node visible. */
|
|
366
|
-
const NOT_A_SPARE = 'node_id NOT IN (SELECT node_id FROM warm_pool)';
|
|
367
|
-
/** Every hydrated node whose durable profile identity equals `profileId`.
|
|
368
|
-
* Unlike `listNodes`, this includes unclaimed warm-pool spares: profile
|
|
369
|
-
* deletion owns every matching row, whether or not it is user-visible. */
|
|
370
|
-
export function listNodesByProfile(profileId) {
|
|
371
|
-
const ids = openDb()
|
|
372
|
-
.prepare('SELECT node_id FROM nodes WHERE profile_id = ? ORDER BY created')
|
|
373
|
-
.all(profileId);
|
|
374
|
-
return ids.map(({ node_id }) => {
|
|
375
|
-
const meta = getNode(node_id);
|
|
376
|
-
if (meta === null) {
|
|
377
|
-
throw new Error(`profile deletion cannot hydrate indexed node ${node_id}`);
|
|
378
|
-
}
|
|
379
|
-
return meta;
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
/** All rows, optionally filtered by status and terminal execution traces. Unclaimed warm spares are excluded. */
|
|
383
|
-
/** Every node's durable memory-resolution coordinates, including unclaimed warm-pool spares. */
|
|
384
|
-
export function listNodeMemoryTargets() {
|
|
385
|
-
return openDb()
|
|
386
|
-
.prepare('SELECT node_id, cwd, profile_id FROM nodes ORDER BY created')
|
|
387
|
-
.all()
|
|
388
|
-
.map((row) => {
|
|
389
|
-
const node = row;
|
|
390
|
-
return { nodeId: node.node_id, cwd: node.cwd, profileId: node.profile_id };
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
export function listNodes(filter) {
|
|
394
|
-
const clauses = [NOT_A_SPARE];
|
|
395
|
-
const params = [];
|
|
396
|
-
if (filter?.status !== undefined) {
|
|
397
|
-
const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
398
|
-
clauses.push(`status IN (${statuses.map(() => '?').join(',')})`);
|
|
399
|
-
params.push(...statuses);
|
|
400
|
-
}
|
|
401
|
-
if (filter?.withRecordedPid === true)
|
|
402
|
-
clauses.push('pi_pid IS NOT NULL');
|
|
403
|
-
if (filter?.withRecordedPidOrFrozen === true)
|
|
404
|
-
clauses.push('(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)');
|
|
405
|
-
const rows = openDb()
|
|
406
|
-
.prepare(`SELECT * FROM node_rows WHERE ${clauses.join(' AND ')} ORDER BY created`)
|
|
407
|
-
.all(...params);
|
|
408
|
-
return rows.map(rowFrom);
|
|
409
|
-
}
|
|
410
|
-
/** Identity-only projection of every user-visible row: the broker's report
|
|
411
|
-
* resolver needs only "does this sender exist, and what is it called", and a
|
|
412
|
-
* three-column read stays cheap against a canvas of thousands of rows where a
|
|
413
|
-
* full `listNodes()` hydration does not. */
|
|
414
|
-
export function listNodeIdentities() {
|
|
415
|
-
return openDb()
|
|
416
|
-
.prepare(`SELECT node_id, name, created FROM nodes WHERE ${NOT_A_SPARE} ORDER BY created`)
|
|
417
|
-
.all();
|
|
418
|
-
}
|
|
419
|
-
// Warm pool — spare booted roots awaiting a `prefer_warm` claim (see
|
|
420
|
-
// `runtime/warm-pool.ts` for the recipe key and the mint/refill policy).
|
|
421
|
-
/** Mark an already-spawned node as an unclaimed spare for `recipeKey`. Hides it
|
|
422
|
-
* from every listing until it is claimed. */
|
|
423
|
-
export function registerWarmSpare(nodeId, recipeKey) {
|
|
424
|
-
withCanvasWrite((db) => {
|
|
425
|
-
db.prepare('INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)')
|
|
426
|
-
.run(nodeId, recipeKey, new Date().toISOString());
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
/** Take a parked spare OUT of the pool without claiming it — the reaper's
|
|
430
|
-
* first move. Returns false when the marker was already gone (a concurrent
|
|
431
|
-
* claim won it), which is the reaper's signal to leave that node alone: it is
|
|
432
|
-
* somebody's live conversation now, not a spare. Deleting the marker under the
|
|
433
|
-
* write lock is exactly what `claimWarmSpare` does, so the two can never both
|
|
434
|
-
* succeed on the same node. */
|
|
435
|
-
export function unregisterWarmSpare(nodeId) {
|
|
436
|
-
return withCanvasWrite((db) => db.prepare('DELETE FROM warm_pool WHERE node_id = ?').run(nodeId).changes > 0);
|
|
437
|
-
}
|
|
438
|
-
function warmSpareRowsFor(db, recipeKey) {
|
|
439
|
-
const sql = `SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
|
|
4
|
+
ORDER BY deadline_at, created, node_id`).all(e).map(_)}o(me,"dueNodeDeadlines");function we(e,n){return Number(s().prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e).changes)===1}o(we,"setNodeDeadline");function Re(e,n){return!Number.isFinite(n)||n<=0?0:p(t=>{const r=t.prepare(`SELECT node_id, deadline_at FROM nodes
|
|
5
|
+
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let d=0;for(const a of r){const u=Date.parse(a.deadline_at);Number.isNaN(u)||(d+=Number(i.run(new Date(u+n).toISOString(),a.node_id,a.deadline_at).changes))}return d})}o(Re,"shiftProfileNodeDeadlines");function Q(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}o(Q,"sqlInput");function Ne(e,n){const t=[],r=o((d,a=d)=>{Object.prototype.hasOwnProperty.call(n,d)&&t.push([a,Q(n[d],d)])},"add");if(r("name"),r("description"),r("title"),r("icon"),r("cycles"),r("kind"),r("mode"),r("lifecycle"),r("cwd"),r("host_kind"),r("profile_id"),r("parent"),r("spawned_by"),r("creator"),r("fork_from"),r("fork_source_file"),r("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]),t.length===0){const d=f(e);if(d===null)throw new Error(`unknown node: ${e}`);return d}if(s().prepare(`UPDATE nodes SET ${t.map(([d])=>`${d} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,d])=>d),e).changes!==1)throw new Error(`unknown node: ${e}`);return f(e)}o(Ne,"updateNode");function ge(e,n){s().prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}o(ge,"setStatus");function Se(e,n){s().prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}o(Se,"setIntent");function ye(e,n,t={}){if(t.outcome===void 0){const i=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(i.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(i.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(i.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const a=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(a.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&a.push("final_report IS NULL");const u=s().prepare(`UPDATE nodes SET ${i.join(", ")} WHERE ${a.join(" AND ")}`).run(...d);return Number(u.changes)}const r=t.outcome;return p(i=>{const d=[],a=[];Object.prototype.hasOwnProperty.call(n,"status")&&(d.push("status = ?"),a.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(d.push("intent = ?"),a.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(d.push("terminal_reason = ?"),a.push(n.terminal_reason??null));const u=o((Z,v)=>r.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${v} END`,"outcomeValue");d.push(`outcome_kind = ${u(r.kind,"outcome_kind")}`,`outcome_reason = ${u(r.reason,"outcome_reason")}`,`outcome_detail_json = ${u(r.detailJson,"outcome_detail_json")}`,`outcome_revision = ${r.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${u(r.at,"outcome_at")}`),a.push(r.kind,r.reason,r.detailJson,r.at);const c=["node_id = ?"];a.push(e),t.fromStatuses!==void 0&&(c.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),a.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&c.push("final_report IS NULL");const l=i.prepare(`UPDATE nodes SET ${d.join(", ")} WHERE ${c.join(" AND ")}`).run(...a);if(Number(l.changes)===0)return 0;const R=i.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(r.supersede===!0||R.outcome_at===r.at)&&r.documentJson!==null&&r.documentJson!==void 0&&U(i,{idempotencyKey:`node-outcome:${e}`,label:e,bodyJson:r.documentJson,supersede:r.supersede===!0}),Number(l.changes)})}o(ye,"transitionStatusIntent");function Oe(e){return s().prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e)?.final_report??null}o(Oe,"getFinalReport");function he(e,n){return s().prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n).changes>0}o(he,"clearFinalReportIfMatches");function Te(e,n){s().prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}o(Te,"setPresence");function De(e,n){s().prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}o(De,"recordLaunch");function Le(e,n){s().prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}o(Le,"recordSettledTurn");function Ae(e,n){s().prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}o(Ae,"setFrozen");function be(e){s().prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}o(be,"clearFrozen");function ve(e,n){s().prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}o(ve,"recordRespawnAttempt");const m="node_id NOT IN (SELECT node_id FROM warm_pool)";function xe(e){return s().prepare("SELECT node_id FROM nodes WHERE profile_id = ? ORDER BY created").all(e).map(({node_id:t})=>{const r=f(t);if(r===null)throw new Error(`profile deletion cannot hydrate indexed node ${t}`);return r})}o(xe,"listNodesByProfile");function We(){return s().prepare("SELECT node_id, cwd, profile_id FROM nodes ORDER BY created").all().map(e=>{const n=e;return{nodeId:n.node_id,cwd:n.cwd,profileId:n.profile_id}})}o(We,"listNodeMemoryTargets");function K(e){const n=[m],t=[];if(e?.status!==void 0){const i=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${i.map(()=>"?").join(",")})`),t.push(...i)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),s().prepare(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t).map(_)}o(K,"listNodes");function ke(){return s().prepare(`SELECT node_id, name, created FROM nodes WHERE ${m} ORDER BY created`).all()}o(ke,"listNodeIdentities");function He(e,n){p(t=>{t.prepare("INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)").run(e,n,new Date().toISOString())})}o(He,"registerWarmSpare");function Fe(e){return p(n=>n.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e).changes>0)}o(Fe,"unregisterWarmSpare");function y(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
|
|
440
6
|
n.status AS status, n.pi_pid AS pi_pid, n.pi_pid_identity AS pi_pid_identity
|
|
441
|
-
FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`
|
|
442
|
-
|
|
443
|
-
' ORDER BY w.created';
|
|
444
|
-
const rows = (recipeKey === undefined ? db.prepare(sql).all() : db.prepare(sql).all(recipeKey));
|
|
445
|
-
return rows.map((r) => ({
|
|
446
|
-
node_id: r['node_id'],
|
|
447
|
-
recipe_key: r['recipe_key'],
|
|
448
|
-
created: r['created'],
|
|
449
|
-
status: r['status'],
|
|
450
|
-
pi_pid: r['pi_pid'] ?? null,
|
|
451
|
-
pi_pid_identity: r['pi_pid_identity'] ?? null,
|
|
452
|
-
}));
|
|
453
|
-
}
|
|
454
|
-
/** Every parked spare, oldest first — what the reaper (`runtime/warm-pool.ts`
|
|
455
|
-
* `reapStaleSpares`) sweeps. Deliberately NOT filtered by liveness: judging a
|
|
456
|
-
* spare is the caller's job. */
|
|
457
|
-
export function listWarmSpares() {
|
|
458
|
-
return warmSpareRowsFor(openDb());
|
|
459
|
-
}
|
|
460
|
-
/** True while `nodeId` is an UNCLAIMED spare — nobody owns this conversation
|
|
461
|
-
* yet. `registerWarmSpare` runs the instant the row exists and BEFORE the
|
|
462
|
-
* broker launch, and a claim deletes the marker atomically, so this is a
|
|
463
|
-
* reliable read from inside the booting engine (the context-intro extension
|
|
464
|
-
* asks it at `session_start` to withhold bearings that would otherwise assert
|
|
465
|
-
* the spare's placeholder persona instead of its eventual claimant's). */
|
|
466
|
-
export function isWarmSpare(nodeId) {
|
|
467
|
-
const row = openDb().prepare('SELECT 1 FROM warm_pool WHERE node_id = ?').get(nodeId);
|
|
468
|
-
return row !== undefined;
|
|
469
|
-
}
|
|
470
|
-
/** A spare is claimable only when its broker is CONFIRMED alive. Status alone
|
|
471
|
-
* is not enough: a broker torn down by a daemon handover leaves the row at
|
|
472
|
-
* `active`/`idle` with a dead pid, and handing that out would answer a create
|
|
473
|
-
* with a node that has no engine behind it. The probe is identity-aware, so a
|
|
474
|
-
* recycled pid never reads as alive; `indeterminate` (probe failed) is treated
|
|
475
|
-
* as not-claimable — a cold spawn is cheap, a broken node is not. */
|
|
476
|
-
function spareIsClaimable(row) {
|
|
477
|
-
if (row.status !== 'active' && row.status !== 'idle')
|
|
478
|
-
return false;
|
|
479
|
-
return recordedPidLiveness(row.pi_pid, row.pi_pid_identity) === 'alive';
|
|
480
|
-
}
|
|
481
|
-
/** Hand out the oldest CLAIMABLE spare matching `recipeKey`, or null when the
|
|
482
|
-
* pool has none. The select+delete run inside ONE canvas write-lock
|
|
483
|
-
* transaction, so two concurrent creates can never be handed the same spare.
|
|
484
|
-
* A spare whose broker is gone is skipped here and reaped by
|
|
485
|
-
* `reapStaleSpares` — nothing ever resumes a spare (the daemon's row query
|
|
486
|
-
* hides them), so a dead spare is garbage, not a parked one.
|
|
487
|
-
*
|
|
488
|
-
* The claim also restamps the row's `created` to `created` — birth time is a
|
|
489
|
-
* spare's MINT time, and consumers sort conversations on it, so an hour-old
|
|
490
|
-
* spare must not sort as an hour-old conversation. This is the one sanctioned
|
|
491
|
-
* write of `created` after birth. */
|
|
492
|
-
export function claimWarmSpare(recipeKey, created, opts = {}) {
|
|
493
|
-
return withCanvasWrite((db) => {
|
|
494
|
-
const row = warmSpareRowsFor(db, recipeKey).find(spareIsClaimable);
|
|
495
|
-
if (row === undefined)
|
|
496
|
-
return null;
|
|
497
|
-
const res = db.prepare('DELETE FROM warm_pool WHERE node_id = ?').run(row.node_id);
|
|
498
|
-
if (res.changes === 0)
|
|
499
|
-
return null;
|
|
500
|
-
db.prepare('UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?')
|
|
501
|
-
.run(created, opts.deadlineAt ?? null, row.node_id);
|
|
502
|
-
if (opts.outcomeDelivery !== undefined)
|
|
503
|
-
insertArmedOutcomeDelivery(db, row.node_id, opts.outcomeDelivery);
|
|
504
|
-
return row.node_id;
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
/** How many CLAIMABLE spares are parked for `recipeKey` (the depth check a
|
|
508
|
-
* refill reads before minting). Uses the same liveness test as the claim, so a
|
|
509
|
-
* spare the claim would skip can never hold the pool at depth 1 and starve
|
|
510
|
-
* every later create of a warm start. */
|
|
511
|
-
export function warmSpareCount(recipeKey) {
|
|
512
|
-
return warmSpareRowsFor(openDb(), recipeKey).filter(spareIsClaimable).length;
|
|
513
|
-
}
|
|
514
|
-
/** Direct children of `id`, oldest first — an indexed point query
|
|
515
|
-
* (`idx_nodes_parent`) instead of a full-table `listNodes()` scan. */
|
|
516
|
-
export function childrenOf(id) {
|
|
517
|
-
return openDb()
|
|
518
|
-
.prepare('SELECT node_id FROM nodes WHERE parent = ? ORDER BY created')
|
|
519
|
-
.all(id).map((r) => r.node_id);
|
|
520
|
-
}
|
|
521
|
-
/** Every node's lean roster row, oldest first — a single scan indexed by
|
|
522
|
-
* `idx_nodes_created`, with no per-row hydration or N+1 query. */
|
|
523
|
-
export function rosterNodes() {
|
|
524
|
-
return openDb()
|
|
525
|
-
.prepare(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created
|
|
526
|
-
FROM nodes WHERE ${NOT_A_SPARE} ORDER BY created`)
|
|
527
|
-
.all().map((r) => ({
|
|
528
|
-
node_id: r['node_id'],
|
|
529
|
-
name: r['name'],
|
|
530
|
-
kind: r['kind'],
|
|
531
|
-
mode: r['mode'],
|
|
532
|
-
lifecycle: r['lifecycle'],
|
|
533
|
-
status: r['status'],
|
|
534
|
-
cwd: r['cwd'],
|
|
535
|
-
host_kind: r['host_kind'] ?? null,
|
|
536
|
-
parent: r['parent'] ?? null,
|
|
537
|
-
created: r['created'],
|
|
538
|
-
}));
|
|
539
|
-
}
|
|
540
|
-
/** Every `subscribes_to` edge (passive + multiple preserved, never collapsed) —
|
|
541
|
-
* a single scan indexed by `idx_edges_from`/`idx_edges_to` (composite
|
|
542
|
-
* `(type, from_id|to_id)`, so a bare `type` predicate still uses one of
|
|
543
|
-
* them). Paired with `rosterNodes()` as the roster's exactly-two-query
|
|
544
|
-
* contract. */
|
|
545
|
-
export function rosterEdges() {
|
|
546
|
-
return openDb()
|
|
547
|
-
.prepare(`SELECT from_id, to_id, active, created FROM edges WHERE type = 'subscribes_to' ORDER BY created`)
|
|
548
|
-
.all().map((r) => ({
|
|
549
|
-
from_id: r['from_id'],
|
|
550
|
-
to_id: r['to_id'],
|
|
551
|
-
active: r['active'] === 1,
|
|
552
|
-
created: r['created'],
|
|
553
|
-
}));
|
|
554
|
-
}
|
|
555
|
-
/** Resumable ROOT conversations pinned to `cwd`, most-recently-created first.
|
|
556
|
-
* A "root" is the top of a spine (`parent IS NULL`) that is a real
|
|
557
|
-
* conversation (not a `kind:'human'` ask) and still resumable (`active`/`idle`,
|
|
558
|
-
* never a `done`/`dead`/`canceled` node). This backs the front-door
|
|
559
|
-
* `crtr -c`/`-r` resume: cwd is the key (the Claude-Code mental model — "my
|
|
560
|
-
* last session HERE"), so it never teleports across projects. */
|
|
561
|
-
export function listResumableRoots(cwd) {
|
|
562
|
-
const rows = openDb()
|
|
563
|
-
.prepare(`SELECT * FROM node_rows
|
|
7
|
+
FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}o(y,"warmSpareRowsFor");function Me(){return y(s())}o(Me,"listWarmSpares");function Ue(e){return s().prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}o(Ue,"isWarmSpare");function T(e){return e.status!=="active"&&e.status!=="idle"?!1:J(e.pi_pid,e.pi_pid_identity)==="alive"}o(T,"spareIsClaimable");function je(e,n,t={}){return p(r=>{const i=y(r,e).find(T);return i===void 0||r.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(i.node_id).changes===0?null:(r.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,i.node_id),t.outcomeDelivery!==void 0&&h(r,i.node_id,t.outcomeDelivery),i.node_id)})}o(je,"claimWarmSpare");function Ie(e){return y(s(),e).filter(T).length}o(Ie,"warmSpareCount");function Pe(e){return s().prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e).map(n=>n.node_id)}o(Pe,"childrenOf");function Ce(){return s().prepare(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created
|
|
8
|
+
FROM nodes WHERE ${m} ORDER BY created`).all().map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created}))}o(Ce,"rosterNodes");function $e(){return s().prepare("SELECT from_id, to_id, active, created FROM edges WHERE type = 'subscribes_to' ORDER BY created").all().map(e=>({from_id:e.from_id,to_id:e.to_id,active:e.active===1,created:e.created}))}o($e,"rosterEdges");function Be(e){return s().prepare(`SELECT * FROM node_rows
|
|
564
9
|
WHERE parent IS NULL AND kind != 'human'
|
|
565
10
|
AND status IN ('active','idle') AND cwd = ?
|
|
566
|
-
AND ${
|
|
567
|
-
ORDER BY created DESC`)
|
|
568
|
-
.all(cwd);
|
|
569
|
-
return rows.map(rowFrom);
|
|
570
|
-
}
|
|
571
|
-
// Edges
|
|
572
|
-
function addEdge(type, from, to, active) {
|
|
573
|
-
openDb()
|
|
574
|
-
.prepare(`INSERT INTO edges (type, from_id, to_id, active, created)
|
|
11
|
+
AND ${m}
|
|
12
|
+
ORDER BY created DESC`).all(e).map(_)}o(Be,"listResumableRoots");function D(e,n,t,r){s().prepare(`INSERT INTO edges (type, from_id, to_id, active, created)
|
|
575
13
|
VALUES (?, ?, ?, ?, ?)
|
|
576
|
-
ON CONFLICT(type, from_id, to_id) DO UPDATE SET active=excluded.active`)
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
/** Record `A subscribes_to B` — A receives B's output. active=true wakes A on
|
|
580
|
-
* emit; passive accumulates pointers without a wake. Mutable; callable by anyone. */
|
|
581
|
-
export function subscribe(subscriber, publisher, active = true) {
|
|
582
|
-
addEdge('subscribes_to', subscriber, publisher, active);
|
|
583
|
-
}
|
|
584
|
-
/** Drop a subscription edge. */
|
|
585
|
-
export function unsubscribe(subscriber, publisher) {
|
|
586
|
-
openDb()
|
|
587
|
-
.prepare('DELETE FROM edges WHERE type = ? AND from_id = ? AND to_id = ?')
|
|
588
|
-
.run('subscribes_to', subscriber, publisher);
|
|
589
|
-
}
|
|
590
|
-
/** Flip an existing subscription's wake behavior. */
|
|
591
|
-
export function setSubscriptionActive(subscriber, publisher, active) {
|
|
592
|
-
openDb()
|
|
593
|
-
.prepare('UPDATE edges SET active = ? WHERE type = ? AND from_id = ? AND to_id = ?')
|
|
594
|
-
.run(active ? 1 : 0, 'subscribes_to', subscriber, publisher);
|
|
595
|
-
}
|
|
596
|
-
/** Record the audit-only `child spawned_by parent` edge. */
|
|
597
|
-
export function recordSpawn(child, parent) {
|
|
598
|
-
addEdge('spawned_by', child, parent, true);
|
|
599
|
-
}
|
|
600
|
-
/** Who subscribes to `publisher` — the targets a push fans out to. */
|
|
601
|
-
export function subscribersOf(publisher) {
|
|
602
|
-
return openDb()
|
|
603
|
-
.prepare(`SELECT from_id AS node_id, active, created FROM edges
|
|
604
|
-
WHERE type = 'subscribes_to' AND to_id = ? ORDER BY created`)
|
|
605
|
-
.all(publisher).map((r) => ({
|
|
606
|
-
node_id: r['node_id'],
|
|
607
|
-
active: r['active'] === 1,
|
|
608
|
-
created: r['created'],
|
|
609
|
-
}));
|
|
610
|
-
}
|
|
611
|
-
/** Who `subscriber` subscribes to — its reports / the nodes feeding it. */
|
|
612
|
-
export function subscriptionsOf(subscriber) {
|
|
613
|
-
return openDb()
|
|
614
|
-
.prepare(`SELECT to_id AS node_id, active, created FROM edges
|
|
615
|
-
WHERE type = 'subscribes_to' AND from_id = ? ORDER BY created`)
|
|
616
|
-
.all(subscriber).map((r) => ({
|
|
617
|
-
node_id: r['node_id'],
|
|
618
|
-
active: r['active'] === 1,
|
|
619
|
-
created: r['created'],
|
|
620
|
-
}));
|
|
621
|
-
}
|
|
622
|
-
// Graph queries
|
|
623
|
-
/** A "view": every node whose output cascades up to `root` via subscriptions —
|
|
624
|
-
* the subscription sub-DAG reachable downward (root → its reports → theirs …).
|
|
625
|
-
* Returns ids excluding root, in BFS order. Cycle-safe. */
|
|
626
|
-
export function view(root) {
|
|
627
|
-
const seen = new Set([root]);
|
|
628
|
-
const out = [];
|
|
629
|
-
const queue = subscriptionsOf(root).map((s) => s.node_id);
|
|
630
|
-
while (queue.length > 0) {
|
|
631
|
-
const id = queue.shift();
|
|
632
|
-
if (seen.has(id))
|
|
633
|
-
continue;
|
|
634
|
-
seen.add(id);
|
|
635
|
-
out.push(id);
|
|
636
|
-
for (const s of subscriptionsOf(id)) {
|
|
637
|
-
if (!seen.has(s.node_id))
|
|
638
|
-
queue.push(s.node_id);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
return out;
|
|
642
|
-
}
|
|
643
|
-
/** Stop-guard primitive: does this node hold an *active* subscription to a node
|
|
644
|
-
* that's still live (active|idle) — i.e. something that can actually wake it?
|
|
645
|
-
* If so, stopping is a legitimate await; if not, it must finish or escalate. */
|
|
646
|
-
export function hasActiveLiveSubscription(nodeId) {
|
|
647
|
-
const r = openDb()
|
|
648
|
-
.prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.to_id
|
|
14
|
+
ON CONFLICT(type, from_id, to_id) DO UPDATE SET active=excluded.active`).run(e,n,t,r?1:0,new Date().toISOString())}o(D,"addEdge");function ze(e,n,t=!0){D("subscribes_to",e,n,t)}o(ze,"subscribe");function Je(e,n){s().prepare("DELETE FROM edges WHERE type = ? AND from_id = ? AND to_id = ?").run("subscribes_to",e,n)}o(Je,"unsubscribe");function Ye(e,n,t){s().prepare("UPDATE edges SET active = ? WHERE type = ? AND from_id = ? AND to_id = ?").run(t?1:0,"subscribes_to",e,n)}o(Ye,"setSubscriptionActive");function qe(e,n){D("spawned_by",e,n,!0)}o(qe,"recordSpawn");function Ve(e){return s().prepare(`SELECT from_id AS node_id, active, created FROM edges
|
|
15
|
+
WHERE type = 'subscribes_to' AND to_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(Ve,"subscribersOf");function L(e){return s().prepare(`SELECT to_id AS node_id, active, created FROM edges
|
|
16
|
+
WHERE type = 'subscribes_to' AND from_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(L,"subscriptionsOf");function Ge(e){const n=new Set([e]),t=[],r=L(e).map(i=>i.node_id);for(;r.length>0;){const i=r.shift();if(!n.has(i)){n.add(i),t.push(i);for(const d of L(i))n.has(d.node_id)||r.push(d.node_id)}}return t}o(Ge,"view");function Qe(e){return s().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.to_id
|
|
649
17
|
WHERE e.type = 'subscribes_to' AND e.from_id = ? AND e.active = 1
|
|
650
|
-
AND n.status IN ('active', 'idle') LIMIT 1`)
|
|
651
|
-
.get(nodeId);
|
|
652
|
-
return r !== undefined;
|
|
653
|
-
}
|
|
654
|
-
/** Whether a LIVE node still subscribes to this one. The mirror of
|
|
655
|
-
* `hasActiveLiveSubscription`: that asks what can still wake this node, this
|
|
656
|
-
* asks what this node still owes — a subscriber that is itself active or idle
|
|
657
|
-
* is waiting on a report this node has not delivered. */
|
|
658
|
-
export function hasLiveSubscriber(nodeId) {
|
|
659
|
-
const r = openDb()
|
|
660
|
-
.prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.from_id
|
|
18
|
+
AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(Qe,"hasActiveLiveSubscription");function Ke(e){return s().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.from_id
|
|
661
19
|
WHERE e.type = 'subscribes_to' AND e.to_id = ? AND e.active = 1
|
|
662
|
-
AND n.status IN ('active', 'idle') LIMIT 1`)
|
|
663
|
-
.get(nodeId);
|
|
664
|
-
return r !== undefined;
|
|
665
|
-
}
|
|
666
|
-
/** Whether a node explicitly awaits a controller that can still deliver. A
|
|
667
|
-
* parent relationship never implies this wait; the node must declare it. */
|
|
668
|
-
export function hasLiveMessageWait(nodeId) {
|
|
669
|
-
const controller = getNode(nodeId)?.waiting_for;
|
|
670
|
-
if (controller == null)
|
|
671
|
-
return false;
|
|
672
|
-
const target = getNode(controller);
|
|
673
|
-
return target !== null && (target.status === 'active' || target.status === 'idle');
|
|
674
|
-
}
|
|
675
|
-
/** Settle an explicit message wait before appending the qualifying delivery.
|
|
676
|
-
* This ordering makes the delivery's one wake observe cleared durable state. */
|
|
677
|
-
export function setMessageWait(nodeId, controller) {
|
|
678
|
-
openDb().prepare('UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?').run(controller, nodeId);
|
|
679
|
-
}
|
|
680
|
-
/** Append a qualifying delivery and settle its matching wait while holding the
|
|
681
|
-
* canvas write lock. A concurrent `node wait controller` runs before or after this whole
|
|
682
|
-
* boundary, never between the durable inbox append and its compare-and-clear. */
|
|
683
|
-
export function deliverAndSettleMessageWait(nodeId, from, deliver) {
|
|
684
|
-
return withCanvasWrite((db) => {
|
|
685
|
-
const armed = db.prepare('SELECT waiting_for_generation FROM nodes WHERE node_id = ? AND waiting_for = ?').get(nodeId, from);
|
|
686
|
-
const result = deliver();
|
|
687
|
-
if (from !== null && armed !== undefined) {
|
|
688
|
-
db.prepare('UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?').run(nodeId, from, armed.waiting_for_generation);
|
|
689
|
-
}
|
|
690
|
-
return result;
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
/** Write one controller-death notice and settle only the still-current dead
|
|
694
|
-
* wait. The check, notice append, and clear share one canvas write boundary. */
|
|
695
|
-
export function settleDeadMessageWait(nodeId, controller, deliver) {
|
|
696
|
-
return withCanvasWrite((db) => {
|
|
697
|
-
const row = db.prepare(`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
|
|
20
|
+
AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(Ke,"hasLiveSubscriber");function Xe(e){const n=f(e)?.waiting_for;if(n==null)return!1;const t=f(n);return t!==null&&(t.status==="active"||t.status==="idle")}o(Xe,"hasLiveMessageWait");function Ze(e,n){s().prepare("UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?").run(n,e)}o(Ze,"setMessageWait");function en(e,n,t){return p(r=>{const i=r.prepare("SELECT waiting_for_generation FROM nodes WHERE node_id = ? AND waiting_for = ?").get(e,n),d=t();return n!==null&&i!==void 0&&r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),d})}o(en,"deliverAndSettleMessageWait");function nn(e,n,t){return p(r=>{const i=r.prepare(`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
|
|
698
21
|
FROM nodes AS waiter LEFT JOIN nodes AS target ON target.node_id = waiter.waiting_for
|
|
699
|
-
WHERE waiter.node_id = ?`).get(
|
|
700
|
-
const live = row?.controller_status === 'active' || row?.controller_status === 'idle';
|
|
701
|
-
if (row?.waiting_for !== controller || live)
|
|
702
|
-
return null;
|
|
703
|
-
const result = deliver();
|
|
704
|
-
db.prepare('UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?').run(nodeId, controller, row.waiting_for_generation);
|
|
705
|
-
return result;
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
/** Close the TOCTOU between checking a target has a natural cycle ahead
|
|
709
|
-
* of it and the write that depends on that (for example, a deferred inbox
|
|
710
|
-
* append). Fresh-reads `nodeId`'s
|
|
711
|
-
* (status, final_report, frozen_at) and either runs `body` (a write) or short-circuits
|
|
712
|
-
* with a `'terminal'`/`'missing'` outcome — the read and `body`'s write share
|
|
713
|
-
* ONE canvas write-lock boundary (`withCanvasWrite`'s `BEGIN IMMEDIATE`), so
|
|
714
|
-
* a concurrent finish/cancel/finalization/deletion either commits entirely
|
|
715
|
-
* before this reads (observed here, `body` never runs) or entirely after
|
|
716
|
-
* (`body` completes uncontested) — never in the gap a separate check-then-
|
|
717
|
-
* write left open. Pass the shared `hasNoNaturalCycle` predicate rather than
|
|
718
|
-
* a bespoke one so the two never drift.
|
|
719
|
-
*
|
|
720
|
-
* A dangling `nodeId` — the row deleted after the
|
|
721
|
-
* caller's own selection but before this guard's fresh read — MUST NEVER run
|
|
722
|
-
* `body`. Reporting `'missing'` distinctly from `'terminal'` (rather than
|
|
723
|
-
* folding it into either the terminal branch or a fabricated "safe" empty
|
|
724
|
-
* snapshot) keeps the two failure shapes from being conflated: a terminal
|
|
725
|
-
* target has a real `status`/`final_report` to report and its own
|
|
726
|
-
* `deferred_no_natural_cycle`-style rejection, while a missing target has
|
|
727
|
-
* nothing to report and belongs to the caller's own not-found contract. */
|
|
728
|
-
export function withFreshTerminalGuard(nodeId, isTerminal, body) {
|
|
729
|
-
return withCanvasWrite((db) => {
|
|
730
|
-
const row = db
|
|
731
|
-
.prepare('SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?')
|
|
732
|
-
.get(nodeId);
|
|
733
|
-
if (row === undefined) {
|
|
734
|
-
return { kind: 'missing' };
|
|
735
|
-
}
|
|
736
|
-
if (isTerminal(row)) {
|
|
737
|
-
return { kind: 'terminal', status: row.status, final_report: row.final_report };
|
|
738
|
-
}
|
|
739
|
-
return { kind: 'ran', result: body() };
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
|
-
/** True when this node's identity is still required to own a managed checkout.
|
|
743
|
-
*
|
|
744
|
-
* Ownership outlives the OPEN state. A closed record whose cleanup is still
|
|
745
|
-
* pending names a checkout and a branch that are physically still there, and
|
|
746
|
-
* this node record is the only proof of who they belong to — deleting it turns
|
|
747
|
-
* a retained residual into an ownerless orphan the daemon sweep can never
|
|
748
|
-
* safely reclaim, because it must never guess at a worktree it cannot prove it
|
|
749
|
-
* created. So prune may take this node only once cleanup is COMPLETE. A
|
|
750
|
-
* historical closed record written before the cleanup field existed carries no
|
|
751
|
-
* such proof and counts as incomplete.
|
|
752
|
-
*
|
|
753
|
-
* An abandoned record is deliberately NOT protected: abandon already removed
|
|
754
|
-
* the checkout and retains its branch for a person on purpose, so there is no
|
|
755
|
-
* residual for the sweep to own. */
|
|
756
|
-
function hasUnreconciledManagedWorktree(nodeId) {
|
|
757
|
-
return hasUnreconciledWorktree(nodeId);
|
|
758
|
-
}
|
|
759
|
-
/** Whether a row may be removed by an automatic collection sweep. */
|
|
760
|
-
export function isCollectible(row, opts = {}) {
|
|
761
|
-
if (!['done', 'dead', 'canceled'].includes(row.status)
|
|
762
|
-
|| row.pi_pid !== null
|
|
763
|
-
|| row.frozen_at !== null
|
|
764
|
-
|| hasUnreconciledManagedWorktree(row.node_id)
|
|
765
|
-
|| row.node_id === envNodeId())
|
|
766
|
-
return false;
|
|
767
|
-
return opts.pastTtl === true || !['crashed', 'stranded', null].includes(row.terminal_reason ?? null);
|
|
768
|
-
}
|
|
769
|
-
/** Hard-delete ONE node: drop its row (the edges→nodes FK, ON DELETE CASCADE,
|
|
770
|
-
* GCs its edges) and remove its on-disk `nodes/<id>/` dir. The single-node
|
|
771
|
-
* analogue of {@link pruneNodes}, for IMMEDIATE reaping — e.g. an empty node the
|
|
772
|
-
* user closed or detached from. An open managed worktree is never deleted: its
|
|
773
|
-
* node retains the ownership needed for `node worktree close`. Pure persisted-state
|
|
774
|
-
* removal: the caller MUST have already torn down the broker engine +
|
|
775
|
-
* viewer (this does not signal any process). The node row and its FK-coupled
|
|
776
|
-
* state are removed in one canvas write boundary. Best-effort dir removal
|
|
777
|
-
* follows the commit. */
|
|
778
|
-
export function deleteNode(nodeId) {
|
|
779
|
-
if (hasUnreconciledManagedWorktree(nodeId))
|
|
780
|
-
return { deleted: false };
|
|
781
|
-
const result = withCanvasWrite((db) => {
|
|
782
|
-
db.prepare('DELETE FROM nodes WHERE node_id = ?').run(nodeId);
|
|
783
|
-
return { deleted: true };
|
|
784
|
-
});
|
|
785
|
-
rmSync(nodeDir(nodeId), { recursive: true, force: true });
|
|
786
|
-
return result;
|
|
787
|
-
}
|
|
788
|
-
/** Hard-delete a validated set of nodes in one row transaction, then remove
|
|
789
|
-
* their directories. The caller must tear down engines and viewers first. */
|
|
790
|
-
export function deleteNodes(nodeIds) {
|
|
791
|
-
const ids = [...new Set(nodeIds)];
|
|
792
|
-
if (ids.length === 0)
|
|
793
|
-
return [];
|
|
794
|
-
const blocked = ids.filter(hasUnreconciledManagedWorktree);
|
|
795
|
-
if (blocked.length > 0) {
|
|
796
|
-
throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${blocked.join(', ')}`);
|
|
797
|
-
}
|
|
798
|
-
const placeholders = ids.map(() => '?').join(',');
|
|
799
|
-
const deleted = withCanvasWrite((db) => {
|
|
800
|
-
const existing = db
|
|
801
|
-
.prepare(`SELECT node_id FROM nodes WHERE node_id IN (${placeholders}) ORDER BY created`)
|
|
802
|
-
.all(...ids).map(({ node_id }) => node_id);
|
|
803
|
-
db.prepare(`DELETE FROM nodes WHERE node_id IN (${placeholders})`).run(...ids);
|
|
804
|
-
return existing;
|
|
805
|
-
});
|
|
806
|
-
for (const id of deleted)
|
|
807
|
-
rmSync(nodeDir(id), { recursive: true, force: true });
|
|
808
|
-
return deleted;
|
|
809
|
-
}
|
|
810
|
-
/** Retention sweep: remove TERMINAL nodes (status dead | done | canceled) whose
|
|
811
|
-
* `created` is older than `ttlDays`, bounding the otherwise-unbounded growth of
|
|
812
|
-
* node rows + dirs. Open managed-worktree nodes are retained so their checkout
|
|
813
|
-
* remains owned until `node worktree close`. The edges→nodes FK (`ON DELETE
|
|
814
|
-
* CASCADE`, migration v4) GCs each pruned node's edges automatically; the
|
|
815
|
-
* on-disk `nodes/<id>/` dir is removed too.
|
|
816
|
-
*
|
|
817
|
-
* With `includeStale`, ALSO prunes nominally-live (active | idle) nodes past the
|
|
818
|
-
* TTL whose process is provably gone — `pi_pid` is NULL or no longer alive. This
|
|
819
|
-
* reaps stale roots (a bare `crtr` whose pi died without the row transitioning),
|
|
820
|
-
* which the daemon's supervision never reconciled. A genuinely-running node keeps
|
|
821
|
-
* a live `pi_pid`, so it is protected, as is the CALLER ($CRTR_NODE_ID). Without
|
|
822
|
-
* the flag, active | idle are NEVER touched (the daemon's domain).
|
|
823
|
-
*
|
|
824
|
-
* Row deletes run in ONE transaction, so the sweep is all-or-nothing. Dir
|
|
825
|
-
* removals follow after COMMIT — the fs isn't transactional, and by then
|
|
826
|
-
* the rows are gone, so a re-run never re-finds a half-deleted node. `dryRun`
|
|
827
|
-
* reports the candidate set and deletes NOTHING. */
|
|
828
|
-
export function pruneNodes(opts) {
|
|
829
|
-
const dryRun = opts.dryRun ?? false;
|
|
830
|
-
const includeStale = opts.includeStale ?? false;
|
|
831
|
-
const cutoff = new Date(Date.now() - opts.ttlDays * 86_400_000).toISOString();
|
|
832
|
-
const selfId = envNodeId() ?? '';
|
|
833
|
-
const db = openDb();
|
|
834
|
-
const terminal = db
|
|
835
|
-
.prepare(`SELECT * FROM node_rows
|
|
22
|
+
WHERE waiter.node_id = ?`).get(e),d=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||d)return null;const a=t();return r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),a})}o(nn,"settleDeadMessageWait");function tn(e,n,t){return p(r=>{const i=r.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return i===void 0?{kind:"missing"}:n(i)?{kind:"terminal",status:i.status,final_report:i.final_report}:{kind:"ran",result:t()}})}o(tn,"withFreshTerminalGuard");function w(e){return $(e)}o(w,"hasUnreconciledManagedWorktree");function A(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||w(e.node_id)||e.node_id===O()?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}o(A,"isCollectible");function rn(e){if(w(e))return{deleted:!1};const n=p(t=>(t.prepare("DELETE FROM nodes WHERE node_id = ?").run(e),{deleted:!0}));return N(S(e),{recursive:!0,force:!0}),n}o(rn,"deleteNode");function on(e){const n=[...new Set(e)];if(n.length===0)return[];const t=n.filter(w);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const r=n.map(()=>"?").join(","),i=p(d=>{const a=d.prepare(`SELECT node_id FROM nodes WHERE node_id IN (${r}) ORDER BY created`).all(...n).map(({node_id:u})=>u);return d.prepare(`DELETE FROM nodes WHERE node_id IN (${r})`).run(...n),a});for(const d of i)N(S(d),{recursive:!0,force:!0});return i}o(on,"deleteNodes");function dn(e){const n=e.dryRun??!1,t=e.includeStale??!1,r=new Date(Date.now()-e.ttlDays*864e5).toISOString(),i=O()??"",d=s(),a=d.prepare(`SELECT * FROM node_rows
|
|
836
23
|
WHERE status IN ('dead', 'done', 'canceled') AND created < ?
|
|
837
|
-
ORDER BY created`)
|
|
838
|
-
.all(cutoff)
|
|
839
|
-
.map(rowFrom)
|
|
840
|
-
.filter((row) => isCollectible(row, { pastTtl: true }))
|
|
841
|
-
.map((row) => ({ node_id: row.node_id, status: row.status, created: row.created }));
|
|
842
|
-
// Stale non-terminal sweep (opt-in): active | idle past the TTL whose process
|
|
843
|
-
// is provably gone (pi_pid NULL or not alive). Never the caller itself.
|
|
844
|
-
const stale = !includeStale ? [] : db
|
|
845
|
-
.prepare(`SELECT node_id, status, created, pi_pid FROM node_rows
|
|
24
|
+
ORDER BY created`).all(r).map(_).filter(l=>A(l,{pastTtl:!0})).map(l=>({node_id:l.node_id,status:l.status,created:l.created})),u=t?d.prepare(`SELECT node_id, status, created, pi_pid FROM node_rows
|
|
846
25
|
WHERE status IN ('active', 'idle') AND created < ?
|
|
847
|
-
ORDER BY created`)
|
|
848
|
-
.all(cutoff)
|
|
849
|
-
.filter((r) => {
|
|
850
|
-
if (r['node_id'] === selfId)
|
|
851
|
-
return false;
|
|
852
|
-
const pid = r['pi_pid'];
|
|
853
|
-
return !isPidAlive(pid);
|
|
854
|
-
})
|
|
855
|
-
.map((r) => ({
|
|
856
|
-
node_id: r['node_id'],
|
|
857
|
-
status: r['status'],
|
|
858
|
-
created: r['created'],
|
|
859
|
-
}))
|
|
860
|
-
.filter((node) => !hasUnreconciledManagedWorktree(node.node_id));
|
|
861
|
-
const candidates = [...terminal, ...stale];
|
|
862
|
-
if (dryRun || candidates.length === 0)
|
|
863
|
-
return { pruned: candidates, dryRun };
|
|
864
|
-
deletePrunedNodes(candidates);
|
|
865
|
-
return { pruned: candidates, dryRun };
|
|
866
|
-
}
|
|
867
|
-
/** Hard-delete a set of pruned nodes in one transaction (the edges→nodes and
|
|
868
|
-
* anchored-crons FKs cascade their coupled state), followed by best-effort
|
|
869
|
-
* on-disk `nodes/<id>/` removal. Shared by TTL and count pruning so their
|
|
870
|
-
* delete semantics never drift. */
|
|
871
|
-
function deletePrunedNodes(candidates) {
|
|
872
|
-
if (candidates.length === 0)
|
|
873
|
-
return;
|
|
874
|
-
withCanvasWrite((db) => {
|
|
875
|
-
const del = db.prepare('DELETE FROM nodes WHERE node_id = ?');
|
|
876
|
-
for (const c of candidates)
|
|
877
|
-
del.run(c.node_id);
|
|
878
|
-
});
|
|
879
|
-
for (const c of candidates) {
|
|
880
|
-
rmSync(nodeDir(c.node_id), { recursive: true, force: true });
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
/** "Most recent activity" sort key (epoch ms) read CHEAPLY: a `statSync` (no file
|
|
884
|
-
* read, no parse) of the node's `job/telemetry.json` — rewritten on every
|
|
885
|
-
* turn_end at a deterministic path, so it tracks last-message recency without a
|
|
886
|
-
* meta read. Falls back to `created`'s epoch when a node never ran a turn.
|
|
887
|
-
* Mirrors render.ts's `sessionMtime` (the same key the snapshot roster surfaces
|
|
888
|
-
* as `last_activity`). Never throws. */
|
|
889
|
-
function recencyMs(nodeId, created) {
|
|
890
|
-
try {
|
|
891
|
-
const st = statSync(join(jobDir(nodeId), 'telemetry.json'), { throwIfNoEntry: false });
|
|
892
|
-
if (st !== undefined)
|
|
893
|
-
return st.mtimeMs;
|
|
894
|
-
}
|
|
895
|
-
catch {
|
|
896
|
-
/* fall through to created */
|
|
897
|
-
}
|
|
898
|
-
const t = Date.parse(created);
|
|
899
|
-
return Number.isNaN(t) ? 0 : t;
|
|
900
|
-
}
|
|
901
|
-
/** Count-based retention sweep: retain the `maxNodes` MOST-RECENTLY-ACTIVE
|
|
902
|
-
* nodes plus every row the collection authority retains, so the real retained
|
|
903
|
-
* floor is `max(maxNodes, retainedCount)`. Bounds the otherwise-unbounded growth
|
|
904
|
-
* the TTL sweep can't (a canvas that never crosses the TTL still grows without
|
|
905
|
-
* limit).
|
|
906
|
-
*
|
|
907
|
-
* Algorithm: order ALL nodes by recency DESC (telemetry.json mtime, falling back
|
|
908
|
-
* to `created`); `target = max(maxNodes, retainedCount)`; delete every node
|
|
909
|
-
* ranked beyond `target` (0-indexed rank >= target) that is collectible.
|
|
910
|
-
*
|
|
911
|
-
* Mirrors {@link pruneNodes} exactly for the delete (shared `deletePrunedNodes`:
|
|
912
|
-
* transactioned row sweep + FK edge cascade + best-effort dir removal). `dryRun`
|
|
913
|
-
* reports the candidate set and deletes NOTHING. */
|
|
914
|
-
export function pruneToLimit(opts) {
|
|
915
|
-
const dryRun = opts.dryRun ?? false;
|
|
916
|
-
const rows = listNodes();
|
|
917
|
-
const ranked = rows
|
|
918
|
-
.map((row) => ({
|
|
919
|
-
row,
|
|
920
|
-
recency: recencyMs(row.node_id, row.created),
|
|
921
|
-
retained: !isCollectible(row),
|
|
922
|
-
}))
|
|
923
|
-
.sort((a, b) => b.recency - a.recency);
|
|
924
|
-
const retainedCount = ranked.filter((r) => r.retained).length;
|
|
925
|
-
const target = Math.max(opts.maxNodes, retainedCount);
|
|
926
|
-
const candidates = ranked
|
|
927
|
-
.filter((r, rank) => rank >= target && !r.retained)
|
|
928
|
-
.map(({ row }) => ({ node_id: row.node_id, status: row.status, created: row.created }));
|
|
929
|
-
if (dryRun || candidates.length === 0)
|
|
930
|
-
return { pruned: candidates, dryRun };
|
|
931
|
-
deletePrunedNodes(candidates);
|
|
932
|
-
return { pruned: candidates, dryRun };
|
|
933
|
-
}
|
|
26
|
+
ORDER BY created`).all(r).filter(l=>{if(l.node_id===i)return!1;const R=l.pi_pid;return!g(R)}).map(l=>({node_id:l.node_id,status:l.status,created:l.created})).filter(l=>!w(l.node_id)):[],c=[...a,...u];return n||c.length===0?{pruned:c,dryRun:n}:(b(c),{pruned:c,dryRun:n})}o(dn,"pruneNodes");function b(e){if(e.length!==0){p(n=>{const t=n.prepare("DELETE FROM nodes WHERE node_id = ?");for(const r of e)t.run(r.node_id)});for(const n of e)N(S(n.node_id),{recursive:!0,force:!0})}}o(b,"deletePrunedNodes");function X(e,n){try{const r=H(F(V(e),"telemetry.json"),{throwIfNoEntry:!1});if(r!==void 0)return r.mtimeMs}catch{}const t=Date.parse(n);return Number.isNaN(t)?0:t}o(X,"recencyMs");function sn(e){const n=e.dryRun??!1,r=K().map(u=>({row:u,recency:X(u.node_id,u.created),retained:!A(u)})).sort((u,c)=>c.recency-u.recency),i=r.filter(u=>u.retained).length,d=Math.max(e.maxNodes,i),a=r.filter((u,c)=>c>=d&&!u.retained).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created}));return n||a.length===0?{pruned:a,dryRun:n}:(b(a),{pruned:a,dryRun:n})}o(sn,"pruneToLimit");export{pe as canonicalSessionFile,Pe as childrenOf,je as claimWarmSpare,he as clearFinalReportIfMatches,be as clearFrozen,ce as createNode,rn as deleteNode,on as deleteNodes,en as deliverAndSettleMessageWait,me as dueNodeDeadlines,_e as findNodeBySessionFile,Oe as getFinalReport,f as getNode,fe as getRow,Ee as getRowByPane,Qe as hasActiveLiveSubscription,Xe as hasLiveMessageWait,Ke as hasLiveSubscriber,A as isCollectible,Ue as isWarmSpare,ke as listNodeIdentities,We as listNodeMemoryTargets,K as listNodes,xe as listNodesByProfile,Be as listResumableRoots,Me as listWarmSpares,dn as pruneNodes,sn as pruneToLimit,De as recordLaunch,ve as recordRespawnAttempt,Le as recordSettledTurn,qe as recordSpawn,He as registerWarmSpare,$e as rosterEdges,Ce as rosterNodes,Ae as setFrozen,Se as setIntent,Ze as setMessageWait,we as setNodeDeadline,Te as setPresence,ge as setStatus,Ye as setSubscriptionActive,nn as settleDeadMessageWait,Re as shiftProfileNodeDeadlines,ze as subscribe,Ve as subscribersOf,L as subscriptionsOf,ye as transitionStatusIntent,Fe as unregisterWarmSpare,Je as unsubscribe,Ne as updateNode,Ge as view,Ie as warmSpareCount,tn as withFreshTerminalGuard};
|