@north-light/cli 0.3.561 → 0.3.563
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +27 -4
- package/dist/api/client.js +3 -3
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/bash-jobs.d.ts +5 -1
- package/dist/api/dto/broker-ops.d.ts +25 -1
- package/dist/api/dto/charges.d.ts +9 -2
- package/dist/api/dto/delivery.d.ts +26 -2
- package/dist/api/dto/execution-start.d.ts +57 -0
- package/dist/api/dto/execution-start.js +0 -0
- package/dist/api/dto/modelauth.d.ts +5 -0
- package/dist/api/dto/node-records.d.ts +16 -0
- package/dist/api/dto/objects.d.ts +1 -1
- package/dist/api/dto/reports.d.ts +0 -3
- package/dist/api/dto/run-events.d.ts +7 -1
- package/dist/api/dto/settings.d.ts +55 -0
- package/dist/api/dto/settings.js +0 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +11 -0
- package/dist/api/routes.js +1 -1
- package/dist/build-root.d.ts +1 -0
- package/dist/build-root.js +1 -1
- package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
- package/dist/cli.js +7 -7
- package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
- package/dist/clients/attach/chrome/bash-jobs.js +1 -1
- package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +6 -4
- package/dist/clients/attach/overlays/auth.js +2 -2
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/viewer.js +550 -567
- package/dist/commands/canvas-config.js +2 -2
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human.js +2 -2
- package/dist/commands/node/bash.js +3 -3
- package/dist/commands/node/create.js +2 -2
- package/dist/commands/person-settings.d.ts +1 -0
- package/dist/commands/person-settings.js +1 -0
- package/dist/commands/pkg/market-manage.d.ts +2 -2
- package/dist/commands/pkg/market-manage.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +13 -13
- package/dist/commands/pkg/shared.js +1 -1
- package/dist/commands/profile/default.js +1 -1
- package/dist/commands/push.js +2 -3
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/connect.js +1 -1
- package/dist/commands/sys/context/sysprompt.js +2 -2
- package/dist/commands/sys/doctor.js +1 -1
- package/dist/commands/sys/join.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
- package/dist/commands/sys/panels/keybindings-panel.js +1 -1
- package/dist/commands/sys/panels/models-panel.d.ts +8 -2
- package/dist/commands/sys/panels/models-panel.js +1 -1
- package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
- package/dist/commands/sys/panels/prefs-panel.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/provider-login.js +5 -5
- package/dist/commands/sys/setup-core.js +3 -3
- package/dist/commands/sys/setup-settings-runner.js +1 -1
- package/dist/commands/sys/spend.js +3 -3
- package/dist/commands/sys/update.js +1 -1
- package/dist/core/auth-file.d.ts +11 -19
- package/dist/core/auth-file.js +1 -2
- package/dist/core/auto-update.d.ts +1 -1
- package/dist/core/auto-update.js +4 -4
- package/dist/core/bash-jobs.d.ts +29 -71
- package/dist/core/bash-jobs.js +9 -10
- package/dist/core/blobs/directory.d.ts +3 -0
- package/dist/core/blobs/directory.js +1 -0
- package/dist/core/blobs/fault.d.ts +3 -0
- package/dist/core/blobs/fault.js +1 -0
- package/dist/core/blobs/index.d.ts +21 -0
- package/dist/core/blobs/index.js +1 -0
- package/dist/core/blobs/r2.d.ts +9 -0
- package/dist/core/blobs/r2.js +4 -0
- package/dist/core/bootstrap.d.ts +1 -1
- package/dist/core/bootstrap.js +2 -2
- package/dist/core/canvas/canvas.d.ts +9 -7
- package/dist/core/canvas/canvas.js +8 -8
- package/dist/core/canvas/crons.d.ts +3 -2
- package/dist/core/canvas/crons.js +3 -3
- package/dist/core/canvas/daemon-owner.d.ts +5 -0
- package/dist/core/canvas/daemon-owner.js +1 -1
- package/dist/core/canvas/db.d.ts +10 -9
- package/dist/core/canvas/db.js +4 -4
- package/dist/core/canvas/executions.d.ts +100 -4
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/export-sqlite.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -0
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
- package/dist/core/canvas/node-tokens.d.ts +1 -4
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/paths.d.ts +0 -1
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/person-state.d.ts +26 -0
- package/dist/core/canvas/person-state.js +1 -0
- package/dist/core/canvas/person.d.ts +3 -10
- package/dist/core/canvas/person.js +7 -7
- package/dist/core/canvas/reconciler-leases.d.ts +12 -0
- package/dist/core/canvas/reconciler-leases.js +8 -0
- package/dist/core/canvas/recovery.d.ts +4 -0
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
- package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
- package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
- package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
- package/dist/core/canvas/schema-version.d.ts +1 -1
- package/dist/core/canvas/schema-version.js +1 -1
- package/dist/core/canvas/sessions.d.ts +8 -11
- package/dist/core/canvas/sessions.js +1 -4
- package/dist/core/canvas/tree.d.ts +4 -2
- package/dist/core/canvas/tree.js +6 -6
- package/dist/core/canvas/types.d.ts +7 -0
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/command-plugins/bundle.d.ts +1 -1
- package/dist/core/command-plugins/bundle.js +1 -1
- package/dist/core/command-plugins/compose.d.ts +1 -1
- package/dist/core/command-plugins/discovery.d.ts +0 -1
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command-plugins/help-addenda.js +1 -1
- package/dist/core/command-plugins/presence.d.ts +2 -0
- package/dist/core/command-plugins/presence.js +1 -1
- package/dist/core/config.d.ts +16 -15
- package/dist/core/config.js +1 -1
- package/dist/core/conversation-store/client-worker.js +1 -1
- package/dist/core/conversation-store/client.js +2 -2
- package/dist/core/conversation-store/index.d.ts +9 -11
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/conversation-store/row-store.d.ts +14 -0
- package/dist/core/conversation-store/row-store.js +13 -0
- package/dist/core/directory/join.d.ts +5 -3
- package/dist/core/directory/join.js +1 -1
- package/dist/core/env-name.d.ts +1 -0
- package/dist/core/env-name.js +1 -1
- package/dist/core/environment-recipe.d.ts +15 -0
- package/dist/core/environment-recipe.js +1 -0
- package/dist/core/environments.js +1 -1
- package/dist/core/events/emit.js +2 -2
- package/dist/core/events/run-event-chunks.d.ts +25 -0
- package/dist/core/events/run-event-chunks.js +5 -0
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/grants/mirror.d.ts +15 -0
- package/dist/core/grants/mirror.js +15 -3
- package/dist/core/grants/on-sync.d.ts +9 -5
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.d.ts +1 -6
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/grants/watch.d.ts +15 -9
- package/dist/core/grants/watch.js +1 -1
- package/dist/core/graph/custom.js +8 -8
- package/dist/core/graph/jobs.d.ts +83 -5
- package/dist/core/graph/jobs.js +11 -2
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/names.js +7 -7
- package/dist/core/graph/objects.d.ts +5 -1
- package/dist/core/graph/objects.js +11 -11
- package/dist/core/graph/reader.d.ts +3 -0
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/repo-sync/identity.d.ts +3 -1
- package/dist/core/graph/repo-sync/identity.js +1 -1
- package/dist/core/graph/repo-sync/repos.d.ts +1 -1
- package/dist/core/graph/repo-sync/repos.js +2 -2
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/installed-plugins.js +1 -1
- package/dist/core/keybindings/persistence.d.ts +1 -1
- package/dist/core/keybindings/persistence.js +1 -1
- package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
- package/dist/core/layout-migrate/loose-keys.js +1 -1
- package/dist/core/ledger/account.d.ts +12 -0
- package/dist/core/ledger/account.js +2 -0
- package/dist/core/ledger/charges.d.ts +2 -2
- package/dist/core/ledger/charges.js +1 -1
- package/dist/core/ledger/check.d.ts +5 -1
- package/dist/core/ledger/check.js +1 -7
- package/dist/core/ledger/chunks.d.ts +8 -0
- package/dist/core/ledger/chunks.js +2 -0
- package/dist/core/ledger/index.d.ts +2 -1
- package/dist/core/ledger/index.js +1 -1
- package/dist/core/ledger/infra-allowance.d.ts +9 -0
- package/dist/core/ledger/infra-allowance.js +1 -0
- package/dist/core/ledger/limits.js +3 -3
- package/dist/core/ledger/payer.d.ts +1 -1
- package/dist/core/ledger/payer.js +1 -1
- package/dist/core/ledger/read.d.ts +14 -4
- package/dist/core/ledger/read.js +2 -3
- package/dist/core/ledger/totals.d.ts +5 -16
- package/dist/core/ledger/totals.js +4 -4
- package/dist/core/ledger/types.d.ts +12 -3
- package/dist/core/llm/run.js +2 -2
- package/dist/core/managed-providers.d.ts +72 -0
- package/dist/core/managed-providers.js +1 -0
- package/dist/core/model-auth/api-credential-store.d.ts +10 -0
- package/dist/core/model-auth/api-credential-store.js +1 -0
- package/dist/core/model-auth/daemon-login.d.ts +1 -1
- package/dist/core/model-auth/daemon-login.js +1 -1
- package/dist/core/model-auth/flows.d.ts +5 -4
- package/dist/core/model-auth/flows.js +1 -1
- package/dist/core/model-auth/handoff-jti.d.ts +3 -4
- package/dist/core/model-auth/handoff-jti.js +1 -1
- package/dist/core/model-auth/readiness.js +1 -1
- package/dist/core/model-config.d.ts +1 -1
- package/dist/core/model-config.js +1 -1
- package/dist/core/model-routes-pool.d.ts +14 -0
- package/dist/core/model-routes-pool.js +1 -0
- package/dist/core/model-routes.d.ts +11 -16
- package/dist/core/model-routes.js +1 -1
- package/dist/core/peer/ingest.d.ts +2 -0
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/stubs.d.ts +8 -0
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/permissions/evaluator.d.ts +7 -2
- package/dist/core/permissions/evaluator.js +2 -2
- package/dist/core/plugin-env.js +1 -1
- package/dist/core/pool-credential-store.d.ts +2 -5
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/profiles/app-env-store.d.ts +5 -5
- package/dist/core/profiles/app-env-store.js +1 -2
- package/dist/core/profiles/default-binding.d.ts +5 -5
- package/dist/core/profiles/default-binding.js +1 -1
- package/dist/core/profiles/env-store.d.ts +10 -21
- package/dist/core/profiles/env-store.js +1 -2
- package/dist/core/profiles/manifest.d.ts +14 -18
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/profiles/relocate.js +1 -1
- package/dist/core/profiles/select.js +21 -21
- package/dist/core/provider-credential.d.ts +1 -1
- package/dist/core/provider-credential.js +1 -1
- package/dist/core/provider-management.d.ts +3 -4
- package/dist/core/provider-management.js +1 -1
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +3 -34
- package/dist/core/providers/description.d.ts +34 -0
- package/dist/core/providers/description.js +0 -0
- package/dist/core/providers/token-cache.d.ts +14 -14
- package/dist/core/providers/token-cache.js +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +1 -1
- package/dist/core/runs/events.d.ts +7 -5
- package/dist/core/runs/events.js +2 -6
- package/dist/core/runs/operations.d.ts +1 -1
- package/dist/core/runs/operations.js +6 -6
- package/dist/core/runtime/bearings.js +1 -1
- package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
- package/dist/core/runtime/broker/attachments-fetch.js +1 -0
- package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
- package/dist/core/runtime/broker/bash-job-launch.js +1 -1
- package/dist/core/runtime/broker/boot-state.d.ts +9 -0
- package/dist/core/runtime/broker/boot-state.js +1 -0
- package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
- package/dist/core/runtime/broker/cli-relay.js +1 -1
- package/dist/core/runtime/broker/client-registry.d.ts +3 -3
- package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-engine-control.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
- package/dist/core/runtime/broker/job-reporter.js +2 -0
- package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
- package/dist/core/runtime/broker/model-adapter.js +3 -2
- package/dist/core/runtime/broker/signal-stream.js +1 -1
- package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
- package/dist/core/runtime/broker/spilled-body.js +1 -0
- package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
- package/dist/core/runtime/broker/summaries-post.js +1 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
- package/dist/core/runtime/broker/tool-groups.js +1 -1
- package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
- package/dist/core/runtime/broker/turn-replies.js +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -2
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/first-boot-rows.d.ts +8 -0
- package/dist/core/runtime/first-boot-rows.js +2 -0
- package/dist/core/runtime/fleet.d.ts +13 -12
- package/dist/core/runtime/front-door-login.js +1 -1
- package/dist/core/runtime/front-door.js +6 -6
- package/dist/core/runtime/headless-pi.js +1 -1
- package/dist/core/runtime/host.d.ts +14 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/invocation.d.ts +6 -0
- package/dist/core/runtime/kickoff.d.ts +2 -14
- package/dist/core/runtime/kickoff.js +17 -19
- package/dist/core/runtime/launch-config-worker.js +1 -1
- package/dist/core/runtime/launch.js +2 -2
- package/dist/core/runtime/model-registry.js +1 -1
- package/dist/core/runtime/node-read.d.ts +4 -6
- package/dist/core/runtime/node-read.js +3 -3
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +0 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/output-result.d.ts +15 -0
- package/dist/core/runtime/output-result.js +5 -0
- package/dist/core/runtime/placement.d.ts +17 -1
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
- package/dist/core/runtime/provider-credential-gate.js +2 -2
- package/dist/core/runtime/recovery-hold.d.ts +21 -2
- package/dist/core/runtime/recovery-hold.js +2 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive.d.ts +2 -2
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
- package/dist/core/runtime/runner/blaxel/client.js +1 -0
- package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
- package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
- package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
- package/dist/core/runtime/runner/blaxel/runner.js +3 -0
- package/dist/core/runtime/runner/index.d.ts +8 -0
- package/dist/core/runtime/runner/index.js +1 -0
- package/dist/core/runtime/runner/process.d.ts +11 -0
- package/dist/core/runtime/runner/process.js +1 -0
- package/dist/core/runtime/runner/types.d.ts +95 -0
- package/dist/core/runtime/runner/types.js +0 -0
- package/dist/core/runtime/situational-context.d.ts +3 -6
- package/dist/core/runtime/situational-context.js +2 -2
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
- package/dist/core/runtime/spawn-env-rows.js +1 -0
- package/dist/core/runtime/spawn-env.d.ts +4 -18
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +2 -8
- package/dist/core/runtime/structured-output.d.ts +0 -67
- package/dist/core/runtime/structured-output.js +3 -8
- package/dist/core/runtime/tmux-driver.d.ts +8 -0
- package/dist/core/runtime/tmux-driver.js +6 -6
- package/dist/core/runtime/view-socket.d.ts +20 -0
- package/dist/core/runtime/view-socket.js +3 -1
- package/dist/core/runtime/warm-pool.d.ts +13 -1
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
- package/dist/core/scoped-state/legacy-profiles.js +1 -0
- package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
- package/dist/core/scoped-state/materialized-plugins.js +1 -0
- package/dist/core/scoped-state/migrate.d.ts +8 -1
- package/dist/core/scoped-state/migrate.js +3 -3
- package/dist/core/scoped-state/person-rows.d.ts +10 -0
- package/dist/core/scoped-state/person-rows.js +6 -0
- package/dist/core/scoped-state/person-store.d.ts +72 -0
- package/dist/core/scoped-state/person-store.js +1 -0
- package/dist/core/secrets/blaxel-launch.d.ts +24 -0
- package/dist/core/secrets/blaxel-launch.js +4 -0
- package/dist/core/secrets/blaxel-register.d.ts +2 -0
- package/dist/core/secrets/blaxel-register.js +1 -0
- package/dist/core/secrets/env-rows.d.ts +17 -0
- package/dist/core/secrets/env-rows.js +4 -0
- package/dist/core/secrets/environment-owner.d.ts +8 -0
- package/dist/core/secrets/environment-owner.js +1 -0
- package/dist/core/secrets/environment-secrets.d.ts +14 -0
- package/dist/core/secrets/environment-secrets.js +1 -0
- package/dist/core/secrets/index.d.ts +2 -0
- package/dist/core/secrets/index.js +1 -0
- package/dist/core/secrets/key.d.ts +3 -0
- package/dist/core/secrets/key.js +2 -0
- package/dist/core/secrets/seal.d.ts +18 -0
- package/dist/core/secrets/seal.js +1 -0
- package/dist/core/spaces/mounts.d.ts +1 -1
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/stop.d.ts +7 -5
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +2 -1
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +11 -8
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/tables.d.ts +4 -0
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/subscription-state.d.ts +34 -72
- package/dist/core/subscription-state.js +1 -4
- package/dist/core/substrate/delivery/plan.js +1 -1
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/app-listener.js +10 -10
- package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
- package/dist/daemon/api/auth/person-bearer.js +1 -0
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/document-listener.js +3 -3
- package/dist/daemon/api/environment-of.d.ts +18 -0
- package/dist/daemon/api/environment-of.js +5 -0
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
- package/dist/daemon/api/handlers/app-profiles.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/charges.d.ts +1 -1
- package/dist/daemon/api/handlers/charges.js +1 -1
- package/dist/daemon/api/handlers/conversations.d.ts +2 -0
- package/dist/daemon/api/handlers/conversations.js +3 -0
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/delivery.d.ts +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/exec.js +1 -1
- package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
- package/dist/daemon/api/handlers/execution-start.js +2 -0
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
- package/dist/daemon/api/handlers/git-credential.js +1 -0
- package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/messages.js +1 -1
- package/dist/daemon/api/handlers/model-config.js +1 -1
- package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-events.d.ts +6 -0
- package/dist/daemon/api/handlers/node-events.js +3 -3
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.js +3 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/reports.js +9 -13
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/settings.d.ts +2 -0
- package/dist/daemon/api/handlers/settings.js +1 -0
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
- package/dist/daemon/api/handlers/vendor-status.js +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/reader.d.ts +8 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +4 -2
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.d.ts +15 -3
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +2 -1
- package/dist/daemon/api/vendor-signin.js +19 -19
- package/dist/daemon/api/viewer-presence.d.ts +20 -6
- package/dist/daemon/api/viewer-presence.js +2 -1
- package/dist/daemon/boot-settings.d.ts +3 -0
- package/dist/daemon/boot-settings.js +1 -0
- package/dist/daemon/broker-signals/bus.d.ts +48 -11
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/live-runs.d.ts +6 -0
- package/dist/daemon/cron/live-runs.js +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.d.ts +10 -0
- package/dist/daemon/crtrd.js +18 -17
- package/dist/daemon/delivery/run-delivery.d.ts +1 -1
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +1 -1
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.js +7 -6
- package/dist/daemon/fleet.d.ts +6 -6
- package/dist/daemon/fleet.js +9 -9
- package/dist/daemon/park-activity.d.ts +2 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/park-pending.d.ts +20 -13
- package/dist/daemon/park-pending.js +3 -1
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
- package/dist/daemon/reconcilers/bash-deadline.js +1 -3
- package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
- package/dist/daemon/reconcilers/grant-effects.js +1 -0
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
- package/dist/daemon/reconcilers/ledger-r2.js +7 -0
- package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
- package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
- package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
- package/dist/daemon/reconcilers/ledger-storage.js +5 -0
- package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
- package/dist/daemon/reconcilers/recipe-image.js +7 -0
- package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
- package/dist/daemon/reconcilers/row-claim.js +2 -0
- package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
- package/dist/daemon/reconcilers/storage-due-work.js +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
- package/dist/daemon/reconcilers/throttled-lane.js +1 -0
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/run-notices.d.ts +3 -0
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +4 -1
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +3 -2
- package/dist/daemon/runs/observer.js +3 -2
- package/dist/daemon/runs/view-transport.d.ts +19 -0
- package/dist/daemon/runs/view-transport.js +1 -0
- package/dist/daemon/structured-requests/boot.d.ts +2 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.d.ts +4 -3
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/notifier.d.ts +2 -0
- package/dist/daemon/structured-requests/notifier.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/launcher/validate.js +1 -1
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +3 -3
- package/dist/pi-extensions/broker-local.js +1 -2
- package/dist/pi-extensions/canvas-bash-valve.js +6 -6
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-elapsed.js +2 -2
- package/dist/pi-extensions/canvas-goal-capture.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
- package/dist/pi-extensions/canvas-review-boundary.js +3 -3
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
- package/dist/pi-extensions/canvas-structured-output.js +6 -11
- package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
- package/dist/pi-extensions/canvas-tool-guide.js +6 -6
- package/dist/shared/inbox-entry-body.js +7 -7
- package/dist/types.d.ts +12 -0
- package/docs/sdk/release-notes.md +4 -0
- package/package.json +7 -4
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/scripts/git-credential-crtr +33 -0
- package/scripts/sandbox-bootstrap.sh +54 -0
- package/scripts/sandbox-start.mjs +320 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
- package/dist/core/conversation-store/file-store.d.ts +0 -37
- package/dist/core/conversation-store/file-store.js +0 -9
- package/dist/core/conversation-store/listener.d.ts +0 -4
- package/dist/core/conversation-store/listener.js +0 -8
- package/dist/core/scoped-state/profiles.d.ts +0 -27
- package/dist/core/scoped-state/profiles.js +0 -1
- package/dist/core/scoped-state/providers.d.ts +0 -24
- package/dist/core/scoped-state/providers.js +0 -1
- package/dist/core/scoped-state/settings.d.ts +0 -28
- package/dist/core/scoped-state/settings.js +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var we=Object.defineProperty;var d=(e,o)=>we(e,"name",{value:o,configurable:!0});import{accessSync as me,constants as he}from"node:fs";import{isAbsolute as pe,resolve as ke,join as _e}from"node:path";import{appSpace as ve}from"../layout.js";import{ApiError as Q}from"../../api/errors.js";import{spawnNode as ye,forkSourceNode as ge,currentNodeContext as be,rootOfSpine as xe,newNodeId as Ce,preflightNodeId as Ee}from"./nodes.js";import{resolveProfileOperand as Re}from"../profiles/manifest.js";import{selectProfileForCwd as Se,selectProfileForCwdReadOnly as $e}from"../profiles/select.js";import{buildLaunchSpecAsync as Z,buildPiArgv as Fe}from"./launch.js";import{runsOnBlaxel as Oe,sandboxWorktreeRequest as Ie}from"../../daemon/api/environment-of.js";import{createManagedWorktreeAsync as Be,rollbackManagedWorktreeAsync as Ne}from"../worktree-mutation-async.js";import{usage as u,brokerLaunchFailed as B}from"../errors.js";import{writeGoal as Pe}from"./kickoff.js";import{appendSituationalContext as De,formatSituationalProse as Te}from"./situational-context.js";import{ensureRoadmap as Le}from"./roadmap.js";import{buildWakeBearings as Ae}from"./bearings.js";import{encodeKickoffOrigin as Me,KICKOFF_ORIGIN_ENV as We}from"./stamp/protocol.js";import{ExecutionCapReached as je,beginExecution as He,crtrHome as ze,getNode as f,fullName as ee,jobDir as Ke,recordExecutionPid as Ge,abortExecution as M,setFrozen as ne}from"../canvas/index.js";import{contextDir as W,nodeAgentDir as j}from"../canvas/node-agent-paths.js";import{copyTreeBeneath as Ue}from"../spaces/open-beneath.js";import{conversationIdFromPath as N,conversationStore as E}from"../conversation-store/index.js";import{appMemoryTooSmall as Ve,boundFleet as Xe,brokerThresholdsForDaemon as oe}from"./fleet.js";import{admitBrokerMemory as qe}from"./memory-admission.js";import{emitEvent as re}from"../events/emit.js";import{openViewerWindow as Ye,focusOf as Je,windowOfPane as Qe}from"./placement.js";import{waitForBrokerViewSocket as Ze}from"./placement-tmux.js";import{transition as _}from"./lifecycle.js";import{beginBootFaultAttempt as en}from"../canvas/recovery.js";import{headlessBrokerHost as H}from"./host.js";import{ensureDaemon as nn}from"../../daemon/manage.js";import{readConfig as on}from"../config.js";import{modelRequestFromConfig as rn,unregisteredConcreteModel as tn}from"../model-routes.js";import{openModelRegistry as an}from"./model-registry.js";import{MODEL_SPEC_NEXT as dn}from"./model-selection.js";import{forkNodeLedger as sn}from"./ledger.js";import{appRungForGrant as cn}from"../llm/app-rungs.js";import{APP_FAMILY as z}from"../model-routes.js";import{discoverLifecycleHookRegistry as ln}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as fn}from"../command-hooks/transport/exec-lifecycle.js";import{someAsync as un}from"../async-array.js";import{checkStart as wn}from"./start-check.js";function v(e){return{detail:{schema:"crtr.node-outcome-detail/v1",message:e instanceof Error?e.message:String(e)}}}d(v,"launchFailureOutcome");async function mn(e,o,a){try{return await H.launch(e,o,a)}catch(i){try{await _(e,"crash",{reason:"launch_failed",outcome:v(i)})}catch{}const t=i.message;throw B(t.startsWith("[broker]")?t:`[broker] refusing to launch ${e}: ${t}`,"Inspect the cause above, fix the launch recipe or environment, then retry.")}}d(mn,"launchBrokerOrCrash");async function hn(e,o){try{await _(e,"crash",{reason:"launch_failed",outcome:v(o)})}catch{}try{H.teardown(e)}catch{}}d(hn,"crashAndTearDown");async function pn(e){const o=(await E().list()).map(({conversation_id:t,path:s})=>({id:t,path:s})),a=o.filter(t=>t.id===e),i=a.length>0?a:o.filter(t=>t.id.startsWith(e));if(i.length===0)throw u(`--fork-from '${e}': no pi session with that id found.`,{next:"Pass a live node id, a real session uuid/prefix, or an absolute .jsonl session path."});if(i.length>1)throw u(`--fork-from '${e}': ambiguous \u2014 ${i.length} sessions match that id prefix; pass the full id or the .jsonl path.`,{next:"Pass the full session uuid or an absolute .jsonl path to disambiguate."});return i[0].path}d(pn,"resolveSessionUuid");async function ie(e){const o=e.trim();if(o==="")throw u("--fork-from requires a node id, session file, or session uuid.",{next:"Pass a live node id, an absolute .jsonl session path, or a session uuid/prefix."});if(o.includes("/")||o.endsWith(".jsonl")){const i=N(pe(o)?o:ke(process.cwd(),o));if(i===null)throw u(`--fork-from '${o}': invalid conversation path.`,{next:"Pass a conversation file path or id."});return(await E().header(i)).path}const a=await f(o);if(a!==null){const i=a.pi_session_file;if(i==null||i==="")throw u(`node ${o} has no pi session yet \u2014 it has not captured a session FILE to fork from (the broker forks a .jsonl path, not a bare id).`,{next:"Pick a node that has captured a session, or drop --fork-from."});const t=N(i);if(t===null)throw u(`node ${o} has no valid conversation id.`,{next:"Pick a node with a captured conversation."});return(await E().header(t)).path}return await pn(o)}d(ie,"resolveForkSource");async function kn(e,o,a,i={}){return e===null?null:e!==void 0&&e!==""?Re(e).profileId:o!==null?(await f(o))?.profile_id??null:i.readOnlySelection===!0?$e(a):Se(a)}d(kn,"resolveProfileId");function te(e){const o=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return rn(e.model,o,e.modelExact===!0)}d(te,"requestFromLaunch");async function ae(e,o,a){const i=a??(e.modelIntent?`${e.modelIntent.family}/${e.modelIntent.strength}`:e.model),t=await cn(o,i,e.modelExact===!0);if(t===null)return e;const{CRTR_MODEL_INTENT:s,...c}=e.env??{};return{...e,model:t.model,modelIntent:{family:z,strength:t.strength},modelExact:void 0,env:{...c,CRTR_MODEL_INTENT:`${z}/${t.strength}`}}}d(ae,"appPaidLaunch");async function de(e,o,a){if(e===void 0||e.kind==="logical"&&e.family!==z)return;const i=await tn(e.kind==="logical"?{kind:"concrete",spec:e.spec}:e,a??await an(),o);if(i!==void 0)throw u(`model '${i.request.spec}' is not registered in this daemon.`,{received:i.request.spec,next:dn})}d(de,"assertLaunchModelRegistered");function _n(e,o,a){const i=e??o??null;if(!a&&i===null)throw new Error("spawnChild requires a calling node (CRTR_NODE_ID) or an explicit parent");return i}d(_n,"resolveSpawner");async function se(e,o,a){try{nn()}catch{}const i=be(),t=e.root===!0,s=_n(e.parent,i.nodeId??null,t),c=e.mode??"base",y=e.rootLifecycle??(t?"resident":"terminal"),ce=t&&y==="resident",S=s===null?null:await f(s),K=e.creator===void 0||e.creator===null?null:await f(e.creator);e.nodeId!==void 0&&await Ee(e.nodeId);const g=e.forkFrom!==void 0?await ie(e.forkFrom):void 0,P=g===void 0?null:await ge(g),D=await un([S,K,P],async l=>l?.isolated===!0||l?.run_id!=null&&(await f(l.run_id))?.isolated===!0);if(D&&e.isolated===!1)throw new Q(403,"isolated_run","isolation cannot be turned off under an isolated run",{param:"isolated"});const $=D||e.isolated===!0;if($&&e.worktree===!0)throw new Q(400,"invalid_request","isolated nodes cannot use a worktree",{param:"worktree"});const R=e.worktree===!0,w=$||R?e.nodeId??await Ce():e.nodeId,F=$?e.run!==void 0&&t&&!D?e.cwd:_e(ve(e.run?.grantee??S?.grantee??"app:terminal").nodes,w):e.cwd,m=await kn(e.profile,s,F),G=e.run?.grant_id??S?.grant_id??null,U=await ae((await Z(e.kind,c,{lifecycle:y,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:F,profileId:m})).launch,G,e.model);await de(te(U),{cwd:F,profileId:m});const T=e.run??K??S??P;await wn({grantee:T?.grantee??"app:terminal",sub:T?.sub,grant_id:T?.grant_id});const V=P?.node_id??null;let b,O=F;const L=R&&await Oe(m)?await Ie(m,e.worktreeCwd??e.cwd,w,e.worktreeBase):void 0;try{R&&L===void 0&&(b=await Be(e.worktreeCwd??e.cwd,w,e.worktreeBase),O=b.path);const l=R?await ae((await Z(e.kind,c,{lifecycle:y,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:O,profileId:m})).launch,G,e.model):U;L!==void 0&&(l.worktree=L),R&&await de(te(l),{cwd:O,profileId:m});const n=await ye({kind:e.kind,mode:c,lifecycle:y,cwd:O,name:e.name??e.kind,description:e.description,parent:t?null:s,creator:e.creator,...e.actor===void 0?{}:{actor:e.actor},forkSourceNode:V,spawnedBy:t?s??void 0:void 0,profile_id:m,...e.scopes===void 0?{}:{scopes:e.scopes},isolated:$,...e.run===void 0?{}:{run:e.run},...e.causedBy===void 0?{}:{causedBy:e.causedBy},...e.withinCreate===void 0?{}:{withinCreate:e.withinCreate},forkFrom:e.forkFrom,forkSourceFile:g,modelOverride:e.model===void 0?void 0:l.model,...b!==void 0?{managedWorktree:b}:{},...w!==void 0?{nodeId:w}:{},...e.reviewBinding===void 0?{}:{reviewBinding:e.reviewBinding},...e.deadlineAt===void 0?{}:{deadlineAt:e.deadlineAt},...e.outcomeDelivery===void 0?{}:{outcomeDelivery:e.outcomeDelivery},launch:l});if(a?.(n.node_id),e.forkFrom!==void 0)try{await sn(n.node_id,V??null)}catch(r){throw await _(n.node_id,"crash",{reason:"launch_failed",outcome:v(r)}),r}if(await Pe(n.node_id,e.prompt),e.situationalContext!==void 0&&await De(n.node_id,Te(e.situationalContext)),o!==void 0)try{o(n.node_id)}catch(r){throw await _(n.node_id,"crash",{reason:"launch_failed",outcome:v(r)}),r}const A=e.prompt!=="",le=`${A&&e.wakeOrigin!==void 0?`${Ae(e.wakeOrigin)}
|
|
2
2
|
|
|
3
|
-
`:""}${e.prompt}`;c==="orchestrator"&&await
|
|
3
|
+
`:""}${e.prompt}`;c==="orchestrator"&&await Le(n.node_id,{goal:e.prompt.trim()}),await vn(n);let X;if(g!==void 0)try{const r=N(g);if(r===null)throw new Error(`invalid fork source ${g}`);const k=await E().fork(r,n.node_id);X=(await E().header(k)).path}catch(r){throw await _(n.node_id,"crash",{reason:"launch_failed",outcome:v(r)}),r}const x=Fe(n,{prompt:le,resumeSessionPath:X});if(x.env={...x.env,CRTR_SUBTREE:await xe(n.node_id)},A){const r=e.wakeOrigin!==void 0?{type:"runtime",kind:"wake",wake:e.wakeOrigin}:{type:"runtime",kind:"kickoff",...n.spawned_by!=null&&n.spawned_by!==""?{spawnedBy:n.spawned_by}:{}};x.env[We]=Me(r)}const h=Xe(),q=await h.reserveSlot(n.node_id),p=q?await qe(n.node_id):null;if(p?.verdict==="too_small"){h.releaseReservation(n.node_id);const r=Ve(p);throw await _(n.node_id,"crash",{reason:"launch_failed",outcome:v(r)}),r}if(!q||p?.verdict==="denied")return p?.verdict==="denied"&&h.releaseReservation(n.node_id),await ne(n.node_id,new Date().toISOString()),re({level:"info",event:"broker.frozen",node_id:n.node_id,fields:p?.verdict==="denied"?{reason:"app_memory",free_bytes:p.free_bytes,needed_bytes:p.needed_bytes}:{reason:"broker_cap",live_count:await h.occupancy(),hard_cap:oe().automaticReviveCap}}),{node:await f(n.node_id),frozen:!0,window:null,session:null};const fe=await en(n.node_id),{automaticReviveCap:ue}=oe();let C;try{C=await He(n.node_id,{daemonEpoch:h.epoch(),cap:ue})}catch(r){if(!(r instanceof je))throw r;return h.releaseReservation(n.node_id),await ne(n.node_id,new Date().toISOString()),re({level:"info",event:"broker.frozen",node_id:n.node_id,fields:{reason:"broker_cap",live_count:r.live,hard_cap:r.cap}}),{node:await f(n.node_id),frozen:!0,window:null,session:null}}x.env={...x.env,CRTR_EXECUTION_ID:C};let I;try{I=await mn(n.node_id,x,{cwd:n.cwd,name:ee(n),resuming:!1})}catch(r){throw await M(C,{reason:"launch_failed"}),r}finally{h.releaseReservation(n.node_id)}if(I.pid===null){const r=new Error(`broker host returned no pid for ${n.node_id}`);throw await M(C,{reason:"launch_failed"}),await _(n.node_id,"crash",{reason:"launch_failed",outcome:v(r)}),B(`failed to launch the broker engine for ${n.node_id} (${n.name}) \u2014 the node was not started.`,`Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then verify the pi engine can start in this environment.`)}if(await Ge(C,n.node_id,I.pid)==="shutdown")throw await M(C,{reason:"superseded"}),H.teardown(n.node_id),B(`broker execution was superseded for ${n.node_id}`,"Retry spawning the node.");if(ce&&e.readiness==="await"&&!await Ze(n.node_id,I.exited)){const r=await fe.explanation();throw await hn(n.node_id,new Error(r??`broker view socket never bound for ${n.node_id}`)),B(r!==null?`the root broker ${n.node_id} could not start \u2014 ${r}`:`the root broker ${n.node_id} never bound its view socket \u2014 it was not started.`,r!==null?"Resolve the cause named above, then retry.":`The broker engine exited before binding its view socket. Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then retry.`)}let Y=null,J=null;if(!t&&s!==null&&on("user").auto_open_child_viewers)try{const r=await Je(s);if(r!==null&&r.pane!==null&&r.pane!==""){const k=await Ye(n.node_id,r.session??"",{name:ee(n),cwd:e.cwd,besidePane:r.pane,waitForBroker:!0,initialWhip:A});k!==null&&k.pane!==null&&k.pane!==""&&(J=k.session,Y=Qe(k.pane))}}catch{}return{node:await f(n.node_id),frozen:!1,window:Y,session:J}}catch(l){throw b!==void 0&&w!==void 0&&await f(w)===null&&await Ne(b),l}}d(se,"spawnChildPrepared");async function fo(e){return se(e)}d(fo,"spawnChild");async function vn(e){const o=ln(e.cwd,e.profile_id).plans.get("node:start")??[];await fn(o,{node:{id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,cwd:e.cwd,nodeDir:await j(e.node_id),contextDir:await W(e.node_id),jobDir:Ke(e.node_id)},runtime:{isBirth:!0,canvasHome:ze(),profile:e.profile_id??null}})}d(vn,"invokeBirthLifecycleHooks");const yn=new Set(["initial-prompt.md","yield-message.md","result.json","jobs"]);async function uo(e,o,a){const i=await f(e);if(i===null)throw u(`unknown node: ${e}`,{received:e,next:"List nodes and pass the id of a node with a captured pi session."});const t=await ie(e),s=await W(e);try{await E().header(N(t)),me(s,he.R_OK)}catch(c){throw new Error(`cannot fork ${e}: its conversation or context is unreadable \u2014 ${c.message}`)}return se({kind:i.kind,mode:"base",cwd:i.cwd,prompt:"",root:!0,readiness:"await",forkFrom:e,...a===void 0?{}:{actor:a},profile:i.profile_id,model:i.model_override??void 0,...o===void 0?{}:{scopes:o}},async c=>{const y=await W(c);Ue(await j(e),s,await j(c),y,yn)})}d(uo,"forkNode");export{ae as appPaidLaunch,de as assertLaunchModelRegistered,uo as forkNode,vn as invokeBirthLifecycleHooks,ie as resolveForkSource,kn as resolveProfileId,_n as resolveSpawner,fo as spawnChild,se as spawnChildPrepared};
|
|
@@ -28,4 +28,4 @@ export type StopAction = {
|
|
|
28
28
|
/** Decide what to do when a node stops. crtrd supplies every current-canvas
|
|
29
29
|
* fact; the broker contributes only whether its Pi-owned background job registry
|
|
30
30
|
* is still running work. */
|
|
31
|
-
export declare function evaluateStop(nodeId: string, signals: StopSignals
|
|
31
|
+
export declare function evaluateStop(nodeId: string, signals: StopSignals): Promise<StopAction>;
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
var g=Object.defineProperty;var
|
|
2
|
-
WHERE d.destination_id = ? AND d.wake = 1 AND m.kind IN ('message', 'completed') AND d.created_at > ? LIMIT 1`).get(t,
|
|
3
|
-
|
|
4
|
-
You have two options:
|
|
5
|
-
1. Remove the invalid file (the output-schema.json in your node directory has been corrupted)
|
|
6
|
-
2. Fix the corruption if you know the original request schema
|
|
7
|
-
|
|
8
|
-
After resolving the file, call the \`submit_result\` tool again (with \`decline\` when the schema cannot be honestly satisfied). If this is unexpected, escalate to the user using \`crtr human send\`.`)}a(T,"formatInvalidStructuredOutputReprompt");async function s(t,e){return await v(t)?"scheduled":await _(t)||await S(t)||await y(t)||await O(t)||e?"awaiting":null}a(s,"wakeCapableWait");async function J(t,e,i){if(i??=f(await m(t)).length>0,e.pushedFinal)return{action:"allow",reason:"finished"};const n=d(t);if(n.state==="valid"){const l=await s(t,i);if(l!==null)return{action:"allow",reason:l};const c=await p(t);return c!==null&&w(c)&&!await E(t)?{action:"allow",reason:"dormant"}:{action:"reprompt",reason:"stalled",message:P(n.request.request_id,n.request.schema)}}if(n.state==="invalid")return{action:"reprompt",reason:"stalled",message:T(n.error)};const r=await p(t);if(r!==null&&(r.final_report!=null||r.status==="done"||r.status==="dead"||r.status==="canceled"))return{action:"allow",reason:"finished"};if(r!==null&&r.lifecycle==="resident")return{action:"allow",reason:"dormant"};const u=await s(t,i);return u!==null?{action:"allow",reason:u}:{action:"reprompt",reason:"stalled",message:o("stop-guard",{},A)}}a(J,"evaluateStop");export{h as RUN_SCHEMA_REPROMPT_LIMIT,Y as STALL_REPROMPT,J as evaluateStop,w as isAppRunRoot,H as runSchemaRepromptPending};
|
|
1
|
+
var g=Object.defineProperty;var e=(t,a)=>g(t,"name",{value:a,configurable:!0});import{hasActiveLiveSubscription as _,hasPendingCronWake as h,getNode as l}from"../canvas/index.js";import{hasLiveControllerWait as S,hasLiveObjectWait as O}from"../canvas/waits.js";import{runningJobs as L}from"../graph/jobs.js";import{hasOpenReplyBearingRequestByRequester as y}from"../human/requests.js";import{formatCard as p,formatStructuredOutputReprompt as N,STALL_REPROMPT as A}from"../../shared/generated-context.js";import{readOutputRequest as c,readSchemaReprompts as m,takeSchemaReprompt as E}from"./output-result.js";import{openDb as f}from"../canvas/db.js";const w=3;function d(t){return t.parent==null&&t.run_id===t.node_id&&t.metadata_json!=null}e(d,"isAppRunRoot");async function R(t){const a=await m(t);return a.count===0?a:await(await f()).prepare(`SELECT 1 FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
2
|
+
WHERE d.destination_id = ? AND d.wake = 1 AND m.kind IN ('message', 'completed') AND d.created_at > ? LIMIT 1`).get(t,a.at)!==void 0?{count:0,at:a.at}:a}e(R,"effectiveSchemaReprompts");async function P(t){const{count:a}=await R(t);return a>=w?!1:await E(t,(await m(t)).count,a+1,Date.now())}e(P,"takeRunSchemaReprompt");async function D(t){return t.pi_pid!=null&&d(t)&&await c(t.node_id)!==null&&(await R(t.node_id)).count<w&&await i(t.node_id)===null}e(D,"runSchemaRepromptPending");import{STALL_REPROMPT as F}from"../../shared/generated-context.js";function T(t,a){return p("stop-guard",{},N(JSON.stringify(a,null,2),t))}e(T,"formatValidStructuredOutputReprompt");async function i(t){return await h(t)?"scheduled":await _(t)||await S(t)||await O(t)||await y(t)||(await L(await f(),t)).length>0?"awaiting":null}e(i,"wakeCapableWait");async function J(t,a){if(a.pushedFinal)return{action:"allow",reason:"finished"};const r=await c(t);if(r!==null){const u=await i(t);if(u!==null)return{action:"allow",reason:u};const s=await l(t);return s!==null&&d(s)&&!await P(t)?{action:"allow",reason:"dormant"}:{action:"reprompt",reason:"stalled",message:T(r.request_id,r.schema)}}const n=await l(t);if(n!==null&&(n.final_report!=null||n.status==="done"||n.status==="dead"||n.status==="canceled"))return{action:"allow",reason:"finished"};if(n!==null&&n.lifecycle==="resident")return{action:"allow",reason:"dormant"};const o=await i(t);return o!==null?{action:"allow",reason:o}:{action:"reprompt",reason:"stalled",message:p("stop-guard",{},A)}}e(J,"evaluateStop");export{w as RUN_SCHEMA_REPROMPT_LIMIT,F as STALL_REPROMPT,J as evaluateStop,d as isAppRunRoot,D as runSchemaRepromptPending};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { outputSchemaRefProblem } from './output-schema-refs.js';
|
|
2
|
-
import type { DeclinedResult } from '../canvas/types.js';
|
|
3
2
|
/** The pi tool a node calls to answer its pending structured-output request
|
|
4
3
|
* (registered by canvas-structured-output; `run.get` names it `submitting_result`). */
|
|
5
4
|
export declare const SUBMIT_RESULT_TOOL = "submit_result";
|
|
@@ -11,16 +10,6 @@ export interface StructuredOutputRequest {
|
|
|
11
10
|
/** The one-off request's message id; its answer ends the requester's message watch. */
|
|
12
11
|
requestMessageId?: string;
|
|
13
12
|
}
|
|
14
|
-
/** Tri-state result of reading a structured-output request file. */
|
|
15
|
-
export type StructuredOutputState = {
|
|
16
|
-
state: 'absent';
|
|
17
|
-
} | {
|
|
18
|
-
state: 'valid';
|
|
19
|
-
request: StructuredOutputRequest;
|
|
20
|
-
} | {
|
|
21
|
-
state: 'invalid';
|
|
22
|
-
error: string;
|
|
23
|
-
};
|
|
24
13
|
/** The `--output-schema` transport clause, rendered verbatim by every leaf that
|
|
25
14
|
* accepts one. Declared once so the call sites cannot drift apart. */
|
|
26
15
|
export declare const OUTPUT_SCHEMA_TRANSPORT = "A .json file path, or inline JSON beginning with `{`.";
|
|
@@ -28,37 +17,7 @@ export declare const OUTPUT_SCHEMA_TRANSPORT = "A .json file path, or inline JSO
|
|
|
28
17
|
* `crtr push result`; a mismatch rejects with the field errors and records
|
|
29
18
|
* nothing, so an over-constrained schema costs the target retries. */
|
|
30
19
|
export declare const OUTPUT_SCHEMA_CONSTRAINTS = "The full schema (including enum, pattern, and numeric bounds) is enforced when the target submits its result (its `submit_result` tool, or `crtr push result`); a mismatch rejects with the field errors and records nothing, so an over-constrained schema costs the target retries. A target that cannot honestly satisfy the schema declines (`submit_result` with `decline`, or `crtr push result --decline \"<reason>\" --code <token> [--retryable]`), which records a failure outcome with reason `declined` carrying the reason, code, and retryable flag instead of a value.";
|
|
31
|
-
export declare function outputSchemaPath(nodeId: string): string;
|
|
32
|
-
/** Broker-visible copy; the daemon validates only against outputSchemaPath. */
|
|
33
|
-
export declare function brokerOutputSchemaPath(nodeId: string): string;
|
|
34
|
-
export declare function shareRunFileWithBroker(nodeId: string, path: string): void;
|
|
35
|
-
export declare function projectOutputSchema(nodeId: string): void;
|
|
36
|
-
export declare function outputResultPath(nodeId: string, grantee?: string): string;
|
|
37
|
-
/** The node's machine result, read beneath its agent folder; undefined when it wrote none. */
|
|
38
|
-
export declare function readOutputResult(nodeId: string, grantee?: string): unknown;
|
|
39
|
-
export declare function structuredRequestResultPath(nodeId: string, requestId: string, mode: StructuredOutputMode, grantee?: string): string;
|
|
40
|
-
/** The marker a declined request leaves beside where `result.json` would have been. */
|
|
41
|
-
export declare function outputDeclinedPath(nodeId: string, grantee?: string): string;
|
|
42
|
-
export interface OutputDeclined extends DeclinedResult {
|
|
43
|
-
mode: StructuredOutputMode;
|
|
44
|
-
at: string;
|
|
45
|
-
}
|
|
46
20
|
export declare function parseOutputSchemaValue(value: string | undefined): Record<string, unknown> | null;
|
|
47
|
-
/** The daemon is the only caller for a row-backed request sidecar. */
|
|
48
|
-
export declare function writeStructuredRequestSidecar(row: {
|
|
49
|
-
request_id: string;
|
|
50
|
-
node_id: string | null;
|
|
51
|
-
submission: StructuredOutputMode;
|
|
52
|
-
schema: Record<string, unknown>;
|
|
53
|
-
request_message_id?: string | null;
|
|
54
|
-
}): string;
|
|
55
|
-
/** Read a structured-output request with full validation and error reporting.
|
|
56
|
-
* Returns a tri-state: absent (file doesn't exist), valid (parsed successfully),
|
|
57
|
-
* or invalid (file exists but is malformed). */
|
|
58
|
-
export declare function readOutputRequest(nodeId: string): StructuredOutputState;
|
|
59
|
-
export declare function readBrokerOutputRequest(nodeId: string): StructuredOutputState;
|
|
60
|
-
/** Reads the pre-request-id sidecar shape for daemon boot adoption only. */
|
|
61
|
-
export declare function readLegacyOutputRequest(nodeId: string): Pick<StructuredOutputRequest, 'mode' | 'schema' | 'requestMessageId'> | null;
|
|
62
21
|
/** Validate a submitted result value against a stored output schema, strictly. Returns
|
|
63
22
|
* the value exactly as submitted, or throws an Error whose message lists the per-field
|
|
64
23
|
* failures. Nothing is coerced: unlike a model's tool arguments, a final result is data
|
|
@@ -75,29 +34,3 @@ export { outputSchemaRefProblem };
|
|
|
75
34
|
export declare function outputSchemaProblem(schema: Record<string, unknown>): Promise<string | null>;
|
|
76
35
|
/** Throws the `bad_output_schema` input error when `outputSchemaProblem` finds one. */
|
|
77
36
|
export declare function assertOutputSchemaAccepted(schema: Record<string, unknown>): Promise<void>;
|
|
78
|
-
/** Persist a validated result atomically (temp-file-plus-rename), so a
|
|
79
|
-
* concurrent reader (Core's result poll peeks this file) never sees a torn
|
|
80
|
-
* write. Returns the result path. */
|
|
81
|
-
export declare function writeOutputResult(nodeId: string, value: unknown, grantee?: string): string;
|
|
82
|
-
/** Persist a decline atomically. `result.json` is left untouched: a one-off
|
|
83
|
-
* decline after an earlier answered request must not erase that answer. */
|
|
84
|
-
export declare function writeOutputDeclined(nodeId: string, declined: OutputDeclined, grantee?: string): string;
|
|
85
|
-
/** The stop guard's count of consecutive schema reprompts of a run's root
|
|
86
|
-
* (Silas, 2026-09-30): daemon-owned, beside the schema it counts against. */
|
|
87
|
-
export declare function schemaRepromptsPath(nodeId: string): string;
|
|
88
|
-
export interface SchemaReprompts {
|
|
89
|
-
count: number;
|
|
90
|
-
at: number;
|
|
91
|
-
}
|
|
92
|
-
export declare function readSchemaReprompts(nodeId: string): SchemaReprompts;
|
|
93
|
-
export declare function writeSchemaReprompts(nodeId: string, value: SchemaReprompts): void;
|
|
94
|
-
/** A `result.submit` resets the count. */
|
|
95
|
-
export declare function clearSchemaReprompts(nodeId: string): void;
|
|
96
|
-
export declare function removeOutputSchema(nodeId: string, requestId?: string): void;
|
|
97
|
-
export interface StagedStructuredProjection {
|
|
98
|
-
path: string;
|
|
99
|
-
tmpPath: string;
|
|
100
|
-
}
|
|
101
|
-
/** Stage the authoritative value before its settlement commit; install is one rename. */
|
|
102
|
-
export declare function stageStructuredResult(nodeId: string, requestId: string, mode: StructuredOutputMode, value: unknown, grantee?: string): StagedStructuredProjection;
|
|
103
|
-
export declare function installStagedStructuredProjection(staged: StagedStructuredProjection): string;
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
${s.join(`
|
|
5
|
-
`)||" - Unknown validation error"}`)}o(ct,"validateStructuredResult");async function L(t){const e=v(t);if(e!==null)return e;try{const{Compile:r}=await import("typebox/compile");r(t)}catch(r){return`the schema cannot be compiled: ${r.message}`}return null}o(L,"outputSchemaProblem");async function pt(t){const e=await L(t);if(e!==null)throw new l({error:"bad_output_schema",message:`output_schema is not usable: ${e}`,field:"output-schema",next:"Fix the schema (bundle referenced documents under $defs with their own $id) and send it again."})}o(pt,"assertOutputSchemaAccepted");function lt(t,e,r){const n=$(t,r),s=w(t,r);q(n,s,`${JSON.stringify(e,null,2)}
|
|
6
|
-
`,{atomic:!0});try{k(n,P(t,r))}catch(u){if(u.code!=="ENOENT")throw u}return s}o(lt,"writeOutputResult");function mt(t,e,r){const n=P(t,r);return q($(t,r),n,`${JSON.stringify(e,null,2)}
|
|
7
|
-
`,{atomic:!0}),n}o(mt,"writeOutputDeclined");function N(t){return`${R(t)}/output-schema-reprompts.json`}o(N,"schemaRepromptsPath");function dt(t){try{const e=JSON.parse(a(N(t),"utf8"));if(c(e)&&Number.isSafeInteger(e.count)&&Number.isFinite(e.at))return{count:e.count,at:e.at}}catch{}return{count:0,at:0}}o(dt,"readSchemaReprompts");function ft(t,e){const r=N(t);f(b(r),{recursive:!0});const n=`${r}.${x()}.tmp`;S(n,JSON.stringify(e),"utf8"),g(n,r)}o(ft,"writeSchemaReprompts");function I(t){try{h(N(t))}catch{}}o(I,"clearSchemaReprompts");function ht(t,e){const r=p(t);if(e!==void 0){const s=F(t);if(s.state!=="valid"||s.request.request_id!==e)return}try{h(r)}catch{}I(t);const n=_(t);try{h(n)}catch{}}o(ht,"removeOutputSchema");function St(t,e,r,n,s){const u=D(t,e,r,s);f(b(u),{recursive:!0});const i=`${u}.${x()}.tmp`;return S(i,`${JSON.stringify(n,null,2)}
|
|
8
|
-
`,"utf8"),{path:u,tmpPath:i}}o(St,"stageStructuredResult");function gt(t){return g(t.tmpPath,t.path),t.path}o(gt,"installStagedStructuredProjection");export{nt as OUTPUT_SCHEMA_CONSTRAINTS,rt as OUTPUT_SCHEMA_TRANSPORT,et as SUBMIT_RESULT_TOOL,pt as assertOutputSchemaAccepted,_ as brokerOutputSchemaPath,I as clearSchemaReprompts,gt as installStagedStructuredProjection,P as outputDeclinedPath,w as outputResultPath,p as outputSchemaPath,L as outputSchemaProblem,v as outputSchemaRefProblem,st as parseOutputSchemaValue,C as projectOutputSchema,it as readBrokerOutputRequest,at as readLegacyOutputRequest,F as readOutputRequest,ot as readOutputResult,dt as readSchemaReprompts,ht as removeOutputSchema,N as schemaRepromptsPath,U as shareRunFileWithBroker,St as stageStructuredResult,D as structuredRequestResultPath,ct as validateStructuredResult,mt as writeOutputDeclined,lt as writeOutputResult,ft as writeSchemaReprompts,ut as writeStructuredRequestSidecar};
|
|
1
|
+
var l=Object.defineProperty;var s=(r,e)=>l(r,"name",{value:e,configurable:!0});import{resolve as m}from"node:path";import{readFileSync as h}from"node:fs";import{outputSchemaRefProblem as u}from"./output-schema-refs.js";import{InputError as i}from"../io.js";import{isRecord as d}from"../../shared/predicates.js";const O="submit_result",x="A .json file path, or inline JSON beginning with `{`.",y='The full schema (including enum, pattern, and numeric bounds) is enforced when the target submits its result (its `submit_result` tool, or `crtr push result`); a mismatch rejects with the field errors and records nothing, so an over-constrained schema costs the target retries. A target that cannot honestly satisfy the schema declines (`submit_result` with `decline`, or `crtr push result --decline "<reason>" --code <token> [--retryable]`), which records a failure outcome with reason `declined` carrying the reason, code, and retryable flag instead of a value.';function N(r){const e=r?.trim();if(e===void 0||e==="")return null;let o,n;if(e.startsWith("{"))o=e,n="inline JSON";else{const t=m(e);n=t;try{o=h(t,"utf8")}catch(c){throw new i({error:"bad_output_schema",message:`could not read output schema from ${t}: ${c.message}`,field:"output-schema",next:"Pass a readable JSON Schema file path, or inline JSON beginning with `{`."})}}let a;try{a=JSON.parse(o)}catch(t){throw new i({error:"bad_output_schema",message:`output schema from ${n} is not valid JSON: ${t.message}`,field:"output-schema",next:"Pass valid JSON whose top-level value is an object."})}if(!d(a))throw new i({error:"bad_output_schema",message:`output schema from ${n} must be a JSON object`,field:"output-schema",next:"Pass a JSON Schema object, not an array, string, number, boolean, or null."});return a}s(N,"parseOutputSchemaValue");async function T(r,e){const{Compile:o}=await import("typebox/compile"),n=o(r);if(n.Check(e))return e;const a=n.Errors(e).map(t=>` - ${(t.keyword==="required"?[...t.instancePath.split("/").filter(Boolean),String(t.params.requiredProperties?.[0]??"")].filter(Boolean).join("."):t.instancePath.split("/").filter(Boolean).join("."))||"root"}: ${t.message}`);throw new Error(`Validation failed:
|
|
2
|
+
${a.join(`
|
|
3
|
+
`)||" - Unknown validation error"}`)}s(T,"validateStructuredResult");async function p(r){const e=u(r);if(e!==null)return e;try{const{Compile:o}=await import("typebox/compile");o(r)}catch(o){return`the schema cannot be compiled: ${o.message}`}return null}s(p,"outputSchemaProblem");async function $(r){const e=await p(r);if(e!==null)throw new i({error:"bad_output_schema",message:`output_schema is not usable: ${e}`,field:"output-schema",next:"Fix the schema (bundle referenced documents under $defs with their own $id) and send it again."})}s($,"assertOutputSchemaAccepted");export{y as OUTPUT_SCHEMA_CONSTRAINTS,x as OUTPUT_SCHEMA_TRANSPORT,O as SUBMIT_RESULT_TOOL,$ as assertOutputSchemaAccepted,p as outputSchemaProblem,u as outputSchemaRefProblem,N as parseOutputSchemaValue,T as validateStructuredResult};
|
|
@@ -5,6 +5,7 @@ declare function tmux(args: string[]): {
|
|
|
5
5
|
ok: boolean;
|
|
6
6
|
stdout: string;
|
|
7
7
|
stderr: string;
|
|
8
|
+
timedOut: boolean;
|
|
8
9
|
};
|
|
9
10
|
export declare function inTmux(): boolean;
|
|
10
11
|
/** Is any tmux SESSION currently up? `tmux list-sessions` exits 0 iff a server
|
|
@@ -160,6 +161,13 @@ export declare function windowIndex(target: string): number | null;
|
|
|
160
161
|
* liveness. We therefore require the echoed `#{pane_id}` to equal the requested
|
|
161
162
|
* pane: a live pane echoes its own id, a gone/bogus one yields empty. */
|
|
162
163
|
export declare function paneExists(pane: string): boolean;
|
|
164
|
+
/** What a liveness probe of a pane learned. `unknown` means the probe timed out: tmux did not answer, which says nothing
|
|
165
|
+
* about the pane. A caller that deletes state on `gone` must keep it on `unknown`. */
|
|
166
|
+
export type PaneState = 'live' | 'gone' | 'unknown';
|
|
167
|
+
/** {@link paneExists} that tells a timed-out probe apart from a pane that is gone. */
|
|
168
|
+
export declare function paneState(pane: string): PaneState;
|
|
169
|
+
/** {@link paneState} without blocking the event loop, bounded by the same timeout. */
|
|
170
|
+
export declare function paneStateAsync(pane: string, timeoutMs?: number): Promise<PaneState>;
|
|
163
171
|
/** Does this pane exist AND have its command still RUNNING (`#{pane_dead}` = 0)?
|
|
164
172
|
* Distinguishes a pane genuinely hosting a live process from a remain-on-exit
|
|
165
173
|
* corpse frozen after exit (`pane_dead` = 1). Node viewer panes run `crtr surface attach`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)){const s=e.indexOf(" ");if(!(s<0)&&e.slice(s+1)===n){const u=e.slice(0,s);if(u!=="")return u}}return null}r(
|
|
3
|
-
`).filter(t=>t!=="")):null}r(
|
|
4
|
-
`).filter(t=>t!==""))}r(
|
|
5
|
-
`)){const[i,a,c,b]=u.split(" ");if(i===void 0||i===""||a===void 0||a===""||c===void 0||c==="")continue;const
|
|
6
|
-
`).filter(e=>e!=="")}r(
|
|
1
|
+
var T=Object.defineProperty;var r=(n,t)=>T(n,"name",{value:t,configurable:!0});import{execFile as f,spawnSync as d}from"node:child_process";import{encodeAttachControlInput as M}from"../keybindings/index.js";import{listProcessTable as C}from"../canvas/pid.js";import{bundledPiCommandForShell as $}from"./pi-cli.js";import{shellQuote as m}from"../../shared/shell-quote.js";import{envPiBinaryOverride as L}from"../../shared/env.js";const p=5e3;function o(n){const t=d("tmux",n,{encoding:"utf8",timeout:p,killSignal:"SIGKILL"});return{timedOut:t.error?.code==="ETIMEDOUT",ok:t.status===0,stdout:(t.stdout??"").trim(),stderr:(t.stderr??"").trim()}}r(o,"tmux");function l(n,t){return o(n===void 0||n===""?t:["-S",n,...t])}r(l,"tmuxOnSocket");function N(){return process.env.TMUX!==void 0&&process.env.TMUX!==""}r(N,"inTmux");function tn(){return d("tmux",["list-sessions"],{encoding:"utf8",stdio:"ignore",timeout:p,killSignal:"SIGKILL"}).status===0}r(tn,"tmuxSessionsReachable");function en(){return d("tmux",["list-clients","-F","#{client_name}"],{encoding:"utf8",timeout:p,killSignal:"SIGKILL"}).status===0}r(en,"tmuxClientsReachable");function rn(n){if(n==="")return null;const t=o(["list-panes","-a","-F","#{pane_id} #{@crtr_node}"]);if(!t.ok)return null;for(const e of t.stdout.split(`
|
|
2
|
+
`)){const s=e.indexOf(" ");if(!(s<0)&&e.slice(s+1)===n){const u=e.slice(0,s);if(u!=="")return u}}return null}r(rn,"paneOfNode");function F(){if(!N())return null;const n=o(["display-message","-p","#{session_name} #{window_id} #{pane_id}"]);if(!n.ok)return null;const[t,e,s]=n.stdout.split(" ");return{session:t,window:e,pane:s}}r(F,"currentTmux");function on(){const n=d("tmux",["-V"],{stdio:"ignore",timeout:p,killSignal:"SIGKILL"});return n.error===void 0&&n.status===0}r(on,"tmuxAvailable");function sn(n){return d("tmux",n,{stdio:"inherit"}).status??1}r(sn,"tmuxInteractive");function A(n){return o(["has-session","-t",n]).ok}r(A,"sessionExists");function R(){const n=o(["show-options","-s","terminal-overrides"]).stdout;/Enbp=\\+E/.test(n)||o(["set-option","-sga","terminal-overrides","*:Enbp=\\E[?2004h:Dsbp=\\E[?2004l"])}r(R,"ensureBracketedPaste");function V(){R(),o(["set-option","-s","focus-events","on"])}r(V,"ensureServerOptions");function un(n,t){A(n)||o(["new-session","-d","-s",n,"-c",t]),V()}r(un,"ensureSession");function k(n){const t=[];for(const[e,s]of Object.entries(n))t.push("-e",`${e}=${s}`);return t}r(k,"envFlags");function an(n){const t=o(["new-window","-d","-a","-P","-F","#{window_id} #{pane_id}","-t",`${n.session}:`,"-n",n.name,"-c",n.cwd,...k(n.env),n.command]);if(!t.ok)return null;const[e,s]=t.stdout.split(" ");return e===void 0||e===""||s===void 0||s===""?null:{window:e,pane:s}}r(an,"openNodeWindow");function cn(n,t){const e=o(["split-window","-d",...t.vertical===!0?[]:["-h"],...t.before===!0?["-b"]:[],...t.size!==void 0?["-l",String(t.size)]:[],"-P","-F","#{pane_id}","-t",n,"-c",t.cwd,...k(t.env),t.command]);return e.ok&&e.stdout!==""?e.stdout:null}r(cn,"splitWindow");function dn(n,t){return!(F()?.session===n)&&!o(["switch-client","-t",n]).ok?!1:o(["select-window","-t",t]).ok}r(dn,"focusWindow");function pn(n){return o(["kill-window","-t",n]).ok}r(pn,"closeWindow");function ln(n,t){return o(["rename-window","-t",n,t]).ok}r(ln,"renameWindow");function fn(n){const t=o(["break-pane","-d","-P","-F","#{window_id} #{pane_id}","-s",n]);if(!t.ok)return null;const[e,s]=t.stdout.split(" ");return e===void 0||e===""||s===void 0||s===""?null:{window:e,pane:s}}r(fn,"breakPane");function mn(n){return o(["kill-pane","-t",n]).ok}r(mn,"closePane");function wn(n,t,e){return o(h(n,t,e)).ok}r(wn,"displayPopup");function xn(n,t,e){return new Promise(s=>{try{f("tmux",h(n,t,e),i=>s(i===null)).stdin?.end()}catch{s(!1)}})}r(xn,"displayPopupAsync");function h(n,t,e){return["display-popup","-E","-t",n,"-d",t,"-w","90%","-h","90%",e]}r(h,"displayPopupArgs");function kn(n,t){const e=o(["display-message","-p","-t",`${n}:${t}`,"#{pane_id}"]);return e.ok&&e.stdout!==""?e.stdout:null}r(kn,"paneOfWindow");function gn(n){const t=o(["display-message","-p","-t",n,"#{window_id}"]);return t.ok&&t.stdout!==""?t.stdout:null}r(gn,"windowOfPane");function _n(n){const t=o(["display-message","-p","-t",n,"#{session_name} #{window_id}"]);if(!t.ok)return null;const e=/^(.*) (@\d+)$/.exec(t.stdout);return e===null||e[1]===""?null:{session:e[1],window:e[2]}}r(_n,"paneLocation");function hn(n){const t=o(["display-message","-p","-t",n,"#{window_index}"]);return!t.ok||!/^\d+$/.test(t.stdout)?null:Number.parseInt(t.stdout,10)}r(hn,"windowIndex");function yn(n){return W(n)==="live"}r(yn,"paneExists");function y(n,t){return t.timedOut?"unknown":t.ok&&t.stdout===n?"live":"gone"}r(y,"paneStateFrom");function W(n){return y(n,o(["display-message","-p","-t",n,"#{pane_id}"]))}r(W,"paneState");async function Pn(n,t=p){return await new Promise(e=>{try{f("tmux",["display-message","-p","-t",n,"#{pane_id}"],{encoding:"utf8",timeout:t,killSignal:"SIGKILL"},(s,u)=>{const i=s!==null&&s.killed===!0;e(y(n,{ok:s===null,stdout:String(u).trim(),timedOut:i}))})}catch{e("gone")}})}r(Pn,"paneStateAsync");function Sn(n){const t=o(["display-message","-p","-t",n,"#{pane_id} #{pane_dead}"]);return t.ok&&t.stdout===`${n} 0`}r(Sn,"paneRunning");function In(){const n=o(["list-panes","-a","-F","#{pane_id}"]);return n.ok?new Set(n.stdout.split(`
|
|
3
|
+
`).filter(t=>t!=="")):null}r(In,"listLivePanes");const B=2e3;async function bn(){const n=await new Promise(t=>{try{f("tmux",["list-panes","-a","-F","#{pane_id}"],{encoding:"utf8",timeout:B,maxBuffer:4194304},(e,s)=>t(e?null:s))}catch{t(null)}});return n===null?null:new Set(n.trim().split(`
|
|
4
|
+
`).filter(t=>t!==""))}r(bn,"listLivePanesAsync");function vn(n){const t=o(["display-message","-p","-t",n,"#{pane_current_path}"]);return t.ok&&t.stdout!==""?t.stdout:null}r(vn,"paneCurrentPath");function On(n){const t=o(["display-message","-p","-t",n,"#{pane_width} #{pane_height}"]);if(!t.ok)return null;const[e,s]=t.stdout.split(" "),u=Number.parseInt(e,10),i=Number.parseInt(s,10);return Number.isInteger(u)&&u>0&&Number.isInteger(i)&&i>0?{cols:u,rows:i}:null}r(On,"paneSize");function En(n,t,e=4e3){const s=r(u=>{const i=["display-message",...u?["-C"]:[],"-d",String(e)];return t!==void 0&&t!==""&&i.push("-t",t),i.push(n),i},"args");return o(s(!0)).ok||o(s(!1)).ok}r(En,"displayMessage");function Tn(n,t,e){return o(["set-option","-p","-t",n,t,e]).ok}r(Tn,"setPaneOption");function Mn(n,t){const e=o(["show-options","-p","-t",n,"-q","-v",t]);return e.ok?e.stdout:void 0}r(Mn,"getPaneOption");const K="@crtr_viewer_at";let P=0,S=Promise.resolve();function Cn(n){if(n==="")return;const t=Math.max(Date.now(),P+1);P=t,S=S.then(()=>new Promise(e=>{try{f("tmux",["set-option","-p","-t",n,K,String(t)],()=>e())}catch{e()}}))}r(Cn,"stampViewerPaneAsync");function U(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}r(U,"escapeRegex");function g(n,t){const e=n.replace(/^"|"$/g,"");return new RegExp(`(?:^|\\s)surface\\s+attach\\s+to\\s+${U(t)}(?:\\s|$)`).test(e)}r(g,"looksLikeViewerCommand");function G(){const n=C();if(n===null)return null;const t=new Map,e=new Map;for(const{pid:s,ppid:u,command:i}of n){e.set(s,i);const a=t.get(u)??[];a.push(s),t.set(u,a)}return{childrenOf:t,commandOf:e}}r(G,"readProcessTree");function j(n,t,e){const s=[t];for(;s.length>0;){const u=s.pop();if(g(n.commandOf.get(u)??"",e))return!0;const i=n.childrenOf.get(u);i!==void 0&&s.push(...i)}return!1}r(j,"processTreeHasViewer");function $n(n){const t=l(n,["list-panes","-a","-F","#{pane_id} #{session_name} #{@crtr_node} #{@crtr_viewer_at}"]);if(!t.ok||t.stdout==="")return[];const e=[];let s;for(const u of t.stdout.split(`
|
|
5
|
+
`)){const[i,a,c,b]=u.split(" ");if(i===void 0||i===""||a===void 0||a===""||c===void 0||c==="")continue;const _=l(n,["display-message","-p","-t",i,"#{pane_current_command} #{pane_start_command} #{pane_pid}"]);if(!_.ok)continue;const[v="",O="",E]=_.stdout.split(" ");if(!(g(v,c)||g(O,c))){s??=G();const x=Number.parseInt(E,10);if(s===null||!Number.isInteger(x)||x<=0||!j(s,x,c))continue}const w=Number.parseInt(b??"",10);e.push({pane:i,session:a,nodeId:c,stampMs:Number.isSafeInteger(w)&&w>=0?w:0})}return e}r($n,"liveViewerPanes");function Ln(n,t,e){return l(n,["send-keys","-l","-t",t,M(e)]).ok}r(Ln,"sendAttachControl");function Nn(n,t,e){const s=r(u=>{const i=["display-message",...u?["-C"]:[]];return t!==void 0&&t!==""&&i.push("-c",t),i.push(e),i},"args");return l(n,s(!0)).ok||l(n,s(!1)).ok}r(Nn,"displayClientMessage");function I(n){return["respawn-pane","-k","-c",n.cwd,...k(n.env),"-t",n.pane,n.command]}r(I,"respawnPaneArgs");function Fn(n){return o(I(n)).ok}r(Fn,"respawnPaneSync");function An(n){return z(`tmux ${I(n).map(m).join(" ")} >/dev/null 2>&1`)}r(An,"respawnPaneInBackground");function z(n){return o(["run-shell","-b",n]).ok}r(z,"runShellInBackground");function Rn(n){const t=o(["display-message","-p","-t",n,"#{pane_start_command}"]);return t.ok?t.stdout:void 0}r(Rn,"paneStartCommand");function Vn(n,t){const e=o(["swap-pane","-s",n,"-t",t]);return e.ok?null:e.stderr===""?"tmux swap-pane failed":e.stderr}r(Vn,"swapPanes");function Wn(n){const t=o(["display-message","-p","-t",n,"#{pane_current_command}"]);return t.ok&&t.stdout!==""?t.stdout:void 0}r(Wn,"paneCurrentCommand");function Bn(n){const t=o(["display-message","-p","-t",n,"#{pane_pid}"]);if(!t.ok)return;const e=Number.parseInt(t.stdout,10);return Number.isInteger(e)&&e>0?e:void 0}r(Bn,"panePid");function Kn(n){return o(["respawn-pane","-k","-t",n]).ok}r(Kn,"respawnPaneInPlace");function Un(n,t=L()??$(m)){return[t,...n.map(m)].join(" ")}r(Un,"piCommand");function D(n){const t=o(["list-windows","-t",n,"-F","#{window_id}"]);return!t.ok||t.stdout===""?[]:t.stdout.split(`
|
|
6
|
+
`).filter(e=>e!=="")}r(D,"listWindowIds");function Gn(n,t){return n==null||t==null?!1:D(n).includes(t)}r(Gn,"windowAlive");function jn(n,t){return o(["select-window","-t",`${n}:${t}`]).ok}r(jn,"selectWindow");function zn(n,t){return o(["select-layout","-t",n,t]).ok}r(zn,"selectLayout");function Dn(n){return o(["select-pane","-t",n]).ok}r(Dn,"selectPane");function Xn(n){return o(["switch-client","-t",n]).ok}r(Xn,"switchClient");function qn(n,t){return o(["send-keys","-t",n,t,"Enter"]).ok}r(qn,"sendKeysEnter");export{K as VIEWER_STAMP_OPTION,fn as breakPane,mn as closePane,pn as closeWindow,F as currentTmux,Nn as displayClientMessage,En as displayMessage,wn as displayPopup,xn as displayPopupAsync,un as ensureSession,dn as focusWindow,Mn as getPaneOption,N as inTmux,In as listLivePanes,bn as listLivePanesAsync,D as listWindowIds,$n as liveViewerPanes,an as openNodeWindow,Wn as paneCurrentCommand,vn as paneCurrentPath,yn as paneExists,_n as paneLocation,rn as paneOfNode,kn as paneOfWindow,Bn as panePid,Sn as paneRunning,On as paneSize,Rn as paneStartCommand,W as paneState,Pn as paneStateAsync,Un as piCommand,ln as renameWindow,An as respawnPaneInBackground,Kn as respawnPaneInPlace,Fn as respawnPaneSync,z as runShellInBackground,o as runTmux,zn as selectLayout,Dn as selectPane,jn as selectWindow,Ln as sendAttachControl,qn as sendKeysEnter,A as sessionExists,Tn as setPaneOption,m as shellQuote,cn as splitWindow,Cn as stampViewerPaneAsync,Vn as swapPanes,Xn as switchClient,on as tmuxAvailable,en as tmuxClientsReachable,sn as tmuxInteractive,tn as tmuxSessionsReachable,Gn as windowAlive,hn as windowIndex,gn as windowOfPane};
|
|
@@ -18,3 +18,23 @@ export declare function waitForBrokerViewSocket(nodeId: string, exited?: Promise
|
|
|
18
18
|
code: number | null;
|
|
19
19
|
signal: NodeJS.Signals | null;
|
|
20
20
|
}>, waitMs?: number): Promise<boolean>;
|
|
21
|
+
/** The port a sandboxed broker serves `/view` on (127.0.0.1 only; the private preview forwards it). */
|
|
22
|
+
export declare const BROKER_VIEW_PORT = 4180;
|
|
23
|
+
/** The relay's end of one broker view connection: a view.sock {@link Socket}, or {@link connectWssView}'s link. Bytes in
|
|
24
|
+
* both directions are newline-terminated frames; `close` carries whether an error preceded it. */
|
|
25
|
+
export interface BrokerViewLink {
|
|
26
|
+
readonly destroyed: boolean;
|
|
27
|
+
write(line: string): unknown;
|
|
28
|
+
destroy(): unknown;
|
|
29
|
+
on(event: 'connect', listener: () => void): this;
|
|
30
|
+
on(event: 'data', listener: (chunk: Buffer) => void): this;
|
|
31
|
+
on(event: 'error', listener: (error: NodeJS.ErrnoException) => void): this;
|
|
32
|
+
on(event: 'close', listener: (hadError: boolean) => void): this;
|
|
33
|
+
}
|
|
34
|
+
/** A broker's `/view` WebSocket as a {@link BrokerViewLink}. Each broker message is one frame, delivered as one
|
|
35
|
+
* newline-terminated chunk; each line written is sent as one text message. The headers (the preview token) are
|
|
36
|
+
* sent on the handshake only and kept nowhere else. */
|
|
37
|
+
export declare function connectWssView(url: string, headers: Record<string, string>): BrokerViewLink;
|
|
38
|
+
/** Resolve true once the broker's `/view` WebSocket accepts a handshake within `waitMs`, retrying while it refuses;
|
|
39
|
+
* false on the deadline or when the broker's launch handle exits. */
|
|
40
|
+
export declare function waitForWssView(url: string, headers: Record<string, string>, exited?: Promise<unknown>, waitMs?: number): Promise<boolean>;
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var m=Object.defineProperty;var a=(n,e)=>m(n,"name",{value:e,configurable:!0});import{EventEmitter as p}from"node:events";import{createConnection as E,Socket as S}from"node:net";import{WebSocket as u}from"ws";import{CLIENT_READ_CAPS as x}from"./broker-protocol.js";import{nodeRunDir as y,viewSocketPath as O}from"../canvas/paths.js";import{isBeneathRefusal as _,socketBeneath as k}from"../spaces/open-beneath.js";const w=3e4,l=100,A=w;function d(n){return new Promise(e=>{setTimeout(e,n)})}a(d,"sleep");function R(n){let e;try{e=k(y(n),O(n))}catch(t){const r=new S;return process.nextTick(()=>r.destroy(t)),r}const s=E(e.path);return s.once("connect",e.release),s.once("close",e.release),s}a(R,"connectViewSocket");function T(n,e){return new Promise((s,t)=>{let r=!1,o=null;const f=a(i=>{r||(r=!0,o!==null&&o.destroy(),i instanceof Error?t(i):s(i))},"finish");o=R(n),o.once("connect",()=>f(!0)),o.once("error",i=>f(_(i)?i:!1)),o.setTimeout(e,()=>f(!1))})}a(T,"probeViewSocket");async function K(n,e,s=w){const t=Date.now()+s,r=e?.then(()=>"exit");for(;Date.now()<=t;){const o=Math.max(0,t-Date.now()),f=T(n,Math.min(l,o)).then(c=>c?"ready":"retry"),i=r===void 0?await f:await Promise.race([f,r]);if(i==="ready")return!0;if(i==="exit")return!1;if(r!==void 0){if(await Promise.race([d(l).then(()=>"sleep"),r])==="exit")return!1}else await d(l)}return!1}a(K,"waitForBrokerViewSocket");const I=4180;function C(n,e){return new B(n,e)}a(C,"connectWssView");class B extends p{static{a(this,"WssViewLink")}ws;failed=!1;ended=!1;terminated=!1;pending=[];constructor(e,s){super(),this.ws=new u(e,{headers:s,maxPayload:x.maxLineBytes}),this.ws.on("open",()=>{for(const t of this.pending.splice(0))this.ws.send(t);this.emit("connect")}),this.ws.on("message",t=>{const r=Array.isArray(t)?Buffer.concat(t):Buffer.isBuffer(t)?t:Buffer.from(new Uint8Array(t));this.emit("data",r.at(-1)===10?r:Buffer.concat([r,Buffer.from(`
|
|
2
|
+
`)]))}),this.ws.on("unexpected-response",(t,r)=>{this.fail(Object.assign(new Error(`broker view refused the upgrade (${r.statusCode??"no status"})`),{code:"ECONNREFUSED"})),this.ws.terminate()}),this.ws.on("error",t=>this.fail(t)),this.ws.on("close",t=>{this.ended||(t===1006&&!this.terminated&&this.fail(Object.assign(new Error("broker view connection dropped (1006)"),{code:"ECONNRESET"})),this.ended=!0,this.emit("close",this.failed))})}get destroyed(){return this.ended||this.ws.readyState===u.CLOSING||this.ws.readyState===u.CLOSED}write(e){const s=e.endsWith(`
|
|
3
|
+
`)?e.slice(0,-1):e;return this.ws.readyState===u.CONNECTING?(this.pending.push(s),!0):this.ws.readyState!==u.OPEN?!1:(this.ws.send(s),!0)}destroy(){return this.terminated=!0,this.ws.terminate(),this}fail(e){this.failed||(this.failed=!0,this.emit("error",e))}}async function M(n,e,s,t=w){const r=Date.now()+t;let o=!1;for(s?.then(()=>{o=!0});Date.now()<=r&&!o;){if(await new Promise(i=>{const c=C(n,e),h=setTimeout(()=>{c.destroy(),i(!1)},Math.max(1,r-Date.now()));c.on("connect",()=>{clearTimeout(h),c.destroy(),i(!0)}),c.on("error",()=>{}),c.on("close",()=>{clearTimeout(h),i(!1)})}))return!0;if(Date.now()+l>r)break;await d(l)}return!1}a(M,"waitForWssView");export{I as BROKER_VIEW_PORT,A as BROKER_VIEW_SOCKET_WAIT_MS,R as connectViewSocket,C as connectWssView,T as probeViewSocket,K as waitForBrokerViewSocket,M as waitForWssView};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Mode, OutcomeDeliveryBinding } from '../canvas/index.js';
|
|
1
|
+
import type { LaunchSpec, Mode, OutcomeDeliveryBinding } from '../canvas/index.js';
|
|
2
2
|
/** Kill switch. `CRTR_WARM_POOL=0` makes every create cold again: claims stop,
|
|
3
3
|
* refills stop, and daemon-start pre-warm no-ops. Read live (not cached at
|
|
4
4
|
* module load) so flipping it takes effect on the next `crtr sys daemon
|
|
@@ -29,6 +29,13 @@ export interface WarmRequest {
|
|
|
29
29
|
* claimant's, so provenance survives the warm path. */
|
|
30
30
|
creator: string | null;
|
|
31
31
|
}
|
|
32
|
+
/** The frozen half of a request, resolved. */
|
|
33
|
+
export interface ResolvedRecipe {
|
|
34
|
+
key: string;
|
|
35
|
+
/** The launch spec the CLAIMANT gets — model included. */
|
|
36
|
+
launch: LaunchSpec;
|
|
37
|
+
request: WarmRequest;
|
|
38
|
+
}
|
|
32
39
|
/** Claim a spare for `request`, reshaped onto its persona — or null when the
|
|
33
40
|
* pool cannot serve it. The caller falls back to a cold spawn; a refused
|
|
34
41
|
* create hook leaves the spare untouched and rejects the create. `beforeClaimDelivery`
|
|
@@ -53,10 +60,15 @@ export declare function resumeWarmClaim(request: WarmRequest, nodeId: string, be
|
|
|
53
60
|
* new owner. Only after winning the marker is the broker killed and the row +
|
|
54
61
|
* dir deleted. Never throws: a failed reap is retried on the next sweep. */
|
|
55
62
|
export declare function reapStaleSpares(): Promise<string[]>;
|
|
63
|
+
/** Claims the lease and renews it until the returned release runs; undefined when another holder has it. */
|
|
64
|
+
export declare function holdMintLease(lane: string, key: string): Promise<(() => Promise<void>) | undefined>;
|
|
56
65
|
/** Bring the pool for `request` back to depth 1, in the background. Never
|
|
57
66
|
* throws and never blocks a caller: a failed mint just means the next create
|
|
58
67
|
* for this key is cold again. */
|
|
59
68
|
export declare function refillWarmPool(request: WarmRequest): void;
|
|
69
|
+
/** Births one spare as node `nodeId`. The node's mint lease is held before the node exists and until its birth settles, so no
|
|
70
|
+
* process's reaper can take the spare for a dead broker; when the lease is not obtained nothing is born. */
|
|
71
|
+
export declare function birthSpare({ key, request }: ResolvedRecipe, nodeId: string): Promise<void>;
|
|
60
72
|
/** Mint a spare for the most recently used profiles so the FIRST create after
|
|
61
73
|
* crtrd boots is warm too, not only the second. The profile is the whole
|
|
62
74
|
* recipe: it supplies the cwd, and everything else a claim reshapes live.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var k=Object.defineProperty;var n=(e,r)=>k(e,"name",{value:r,configurable:!0});import{createHash as x,randomUUID as N}from"node:crypto";import{openDb as R}from"../canvas/db.js";import{claimReconcilerLease as $,releaseReconcilerLease as L,renewReconcilerLease as C}from"../canvas/reconciler-leases.js";import{claimWarmSpare as b,deleteNode as E,getNode as p,listNodes as W,listWarmSpares as M,registerWarmSpare as P,unregisterWarmSpare as A,updateNode as I,warmSpareCount as w}from"../canvas/index.js";import{recordedPidLiveness as D}from"../canvas/pid.js";import{nowIso as u}from"../fs-utils.js";import{admitNodeCreate as O}from"../command-hooks/lifecycle-create.js";import{spawnChildPrepared as T}from"./spawn.js";import{newNodeId as H}from"./nodes.js";import{checkStart as F}from"./start-check.js";import{buildLaunchSpecAsync as K}from"./launch.js";import{setModelLive as U}from"./model-swap.js";import{setSituationalContextLive as j}from"./situational-live.js";import{deliverBearingsLive as B}from"./deliver-live.js";import{closeNode as y}from"./close.js";function h(){return process.env.CRTR_WARM_POOL!=="0"}n(h,"warmPoolEnabled");function G(e,r,a){const t=Object.entries(a.env??{}).sort(([s],[i])=>s<i?-1:s>i?1:0),o=JSON.stringify([e,r,a.tools??[],a.extensions??[],a.systemPrompt??null,t]);return x("sha256").update(o).digest("hex").slice(0,32)}n(G,"warmRecipeKey");async function d(e){const{launch:r}=await K(e.kind,e.mode,{lifecycle:"resident",hasManager:!1,...e.model!==null?{model:e.model}:{},cwd:e.cwd,profileId:e.profileId});return{key:G(e.cwd,e.profileId,r),launch:r,request:e}}n(d,"resolveRecipe");async function g(e){const r=e.creator===null?null:await p(e.creator);await F({grantee:r?.grantee??"app:terminal",sub:r?.sub,grant_id:r?.grant_id})}n(g,"checkClaimantStart");async function pe(e,r={},a){await g(e);const t=await d(e);if(await w(t.key)===0)return null;const o=u(),s=await O({kind:e.kind,mode:e.mode,cwd:e.cwd,profile:e.profileId,root:!0,parentId:null,requestingNodeId:e.creator,lifecycle:"resident",replaces:null},e.creator===null?"app:terminal":await(async()=>{const c=await p(e.creator);if(!c?.grantee)throw new Error("warm node creator has no app");return c.grantee})());let i;try{i=await b(t.key,o,r)}finally{s()}return i===null?null:v(i,t,o,a)}n(pe,"claimWarmNode");async function fe(e,r,a){return await g(e),v(r,await d(e),u(),a)}n(fe,"resumeWarmClaim");async function v(e,r,a,t){const{request:o}=r,i=(await p(e))?.launch?.model;await I(e,{created:a,kind:o.kind,mode:o.mode,name:o.name??o.kind,creator:o.creator,launch:r.launch,persona_ack:{kind:o.kind,mode:o.mode,lifecycle:"resident"},...o.model!==null?{model_override:o.model}:{}});try{t?.(e)}catch(l){return await m(e,"birth preparation",l)}try{await B(e)}catch(l){return await m(e,"bearings delivery",l)}const c=r.launch.model;if(c!==void 0&&c!==i)try{await U(e,c,r.launch.modelIntent)}catch(l){return await m(e,"model swap",l)}if(o.situationalContext!==null)try{await j(e,o.situationalContext)}catch(l){return await m(e,"situational-context delivery",l)}return e}n(v,"completeWarmClaim");async function m(e,r,a){console.error(`[warm-pool] ${r} failed on claim; closing the spare: ${a.message}`);try{await y(e)}catch{}return null}n(m,"abandonSpare");const J=3600*1e3;async function we(){const e=[];let r;try{r=await M()}catch(t){return console.error(`[warm-pool] spare scan failed: ${t.message}`),e}const a=Date.now()-J;for(const t of r){if(await z(t.node_id))continue;const o=Date.parse(t.created),s=Number.isNaN(o)||o<a,i=D(t.pi_pid,t.pi_pid_identity),c=(t.status==="active"||t.status==="idle")&&i==="alive";if(!(c&&!s)&&!(i==="indeterminate"&&!s))try{if(!await A(t.node_id))continue;if(c)try{await y(t.node_id)}catch{}await E(t.node_id),e.push(t.node_id)}catch(l){console.error(`[warm-pool] reap failed for ${t.node_id}: ${l.message}`)}}return e}n(we,"reapStaleSpares");const f=6e4;async function _(e,r){const a=N();if(await $(e,r,a,f)===void 0)return;const t=setInterval(()=>{C(e,r,a,f).catch(()=>{})},f/3);return t.unref(),async()=>{clearInterval(t),await L(e,r,a)}}n(_,"holdMintLease");async function z(e){return await(await R()).prepare("SELECT 1 FROM reconciler_leases WHERE lane = ? AND key = ? AND expires_at > ?").get("warm-pool-mint",e,new Date().toISOString())!==void 0}n(z,"mintLeaseHeld");function ue(e){if(h())try{d({...e,model:null,situationalContext:null}).then(S).catch(r=>console.error(`[warm-pool] recipe resolution failed: ${r.message}`))}catch(r){console.error(`[warm-pool] recipe resolution failed: ${r.message}`)}}n(ue,"refillWarmPool");async function S(e){const{key:r}=e,a=await _("warm-pool",r);if(a!==void 0){if(await w(r)>0){await a();return}Q(e,await H()).finally(()=>a().catch(()=>{}))}}n(S,"mint");async function Q({key:e,request:r},a){const t=await _("warm-pool-mint",a);if(t===void 0){console.error(`[warm-pool] mint refused for ${r.kind}: the mint lease of ${a} is held elsewhere`);return}try{await T({nodeId:a,kind:r.kind,mode:r.mode,cwd:r.cwd,prompt:"",root:!0,readiness:"await",profile:r.profileId},async o=>{await P(o,e)})}catch(o){console.error(`[warm-pool] mint failed for ${r.kind}: ${o.message}`)}finally{await t().catch(()=>{})}}n(Q,"birthSpare");const V=2;async function ye(){if(!h())return;let e;try{const r=new Set;e=[];for(const a of(await W({status:["active","idle"]})).reverse()){if(a.parent!==null||a.kind==="human")continue;const t=a.profile_id??null;if(!r.has(t??"")&&(r.add(t??""),e.push({cwd:a.cwd,profileId:t}),e.length>=V))break}}catch(r){console.error(`[warm-pool] prewarm scan failed: ${r.message}`);return}for(const r of e)try{d({kind:"general",mode:"base",cwd:r.cwd,profileId:r.profileId,model:null,situationalContext:null,name:null,creator:null}).then(S).catch(a=>console.error(`[warm-pool] prewarm failed for ${r.cwd}: ${a.message}`))}catch(a){console.error(`[warm-pool] prewarm failed for ${r.cwd}: ${a.message}`)}}n(ye,"prewarmRecentRecipes");export{Q as birthSpare,pe as claimWarmNode,_ as holdMintLease,ye as prewarmRecentRecipes,we as reapStaleSpares,ue as refillWarmPool,fe as resumeWarmClaim,h as warmPoolEnabled};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PersonSnapshot } from './person-store.js';
|
|
2
|
+
/** The old user store's contents in the shape of a person's snapshot, or null when this install never had a store. */
|
|
3
|
+
export declare function readLegacyUserSnapshot(root: string): PersonSnapshot | null;
|
|
4
|
+
/** Pre-canvas per-project memory caps (`none|name|preview`) the canvas import has not converted yet. */
|
|
5
|
+
export declare function listLegacyProjectCaps(root: string): Array<{
|
|
6
|
+
profileId: string;
|
|
7
|
+
path: string;
|
|
8
|
+
memory: string;
|
|
9
|
+
}>;
|
|
10
|
+
/** Delete every legacy cap row once the canvas import has stored the converted limits on the profile rows. */
|
|
11
|
+
export declare function deleteLegacyProjectCaps(root: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var y=Object.defineProperty;var r=(s,a)=>y(s,"name",{value:a,configurable:!0});import{prepared as o}from"../sqlite-statements.js";import{userStore as c}from"./paths.js";import{openScopedStore as u,scopedStoreExists as i,withScopedWrite as g}from"./db.js";function S(s){const a=c(s);if(!i(a))return null;const t=u(a),m=o(t,"SELECT profile_id, path FROM profile_projects ORDER BY profile_id, position").all(),E=o(t,"SELECT id, name, created_at, last_used_at, paused_at, default_kind, grantee, metadata_json, delivery_limits_json, environment_id FROM profiles ORDER BY rowid").all().map(e=>{const n=JSON.parse(e.metadata_json),f=JSON.parse(e.delivery_limits_json);return{profileId:e.id,manifest:{schema_version:1,name:e.name,projects:m.filter(_=>_.profile_id===e.id).map(_=>({path:_.path})),paused_at:e.paused_at,...e.default_kind===null?{}:{default_kind:e.default_kind},...e.grantee===null?{}:{grantee:e.grantee},...e.environment_id===null?{}:{environment_id:e.environment_id},...Object.keys(f).length===0?{}:{delivery_limits:f},...Object.keys(n).length===0?{}:{metadata:n},created_at:e.created_at,last_used_at:e.last_used_at}}}),k=Object.fromEntries(o(t,"SELECT directory, profile_id FROM profile_defaults").all().map(e=>[e.directory,e.profile_id])),p={};for(const e of o(t,"SELECT owner_key, raw_json FROM scope_settings WHERE owner_key != 'project'").all())p[e.owner_key]=JSON.parse(e.raw_json);const d={},l=r(e=>d[e]??={marketplaces:{},plugins:{},activeCanvas:null},"stateOf");for(const e of o(t,"SELECT owner_key, last_self_check, active_canvas FROM scope_bookkeeping WHERE owner_key != 'project'").all()){const n=l(e.owner_key);e.last_self_check!==null&&(n.last_self_check=e.last_self_check),n.activeCanvas=e.active_canvas}for(const e of o(t,"SELECT owner_key, name, last_updated FROM scope_marketplaces WHERE owner_key != 'project'").all())l(e.owner_key).marketplaces[e.name]=e.last_updated===null?{}:{last_updated:e.last_updated};for(const e of o(t,"SELECT owner_key, name, last_updated, etag, checked_at FROM scope_plugins WHERE owner_key != 'project'").all())l(e.owner_key).plugins[e.name]={...e.last_updated===null?{}:{last_updated:e.last_updated},...e.etag===null?{}:{etag:e.etag},...e.checked_at===null?{}:{checked_at:e.checked_at}};return{profiles:E,defaults:k,settings:p,state:d}}r(S,"readLegacyUserSnapshot");function v(s){const a=c(s);return i(a)?o(u(a),"SELECT profile_id, path, memory FROM legacy_project_caps ORDER BY profile_id, path").all().map(t=>({profileId:t.profile_id,path:t.path,memory:t.memory})):[]}r(v,"listLegacyProjectCaps");function w(s){const a=c(s);i(a)&&g(a,t=>{o(t,"DELETE FROM legacy_project_caps").run()})}r(w,"deleteLegacyProjectCaps");export{w as deleteLegacyProjectCaps,v as listLegacyProjectCaps,S as readLegacyUserSnapshot};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** One enabled plugin row of the person's user scope, with its marketplace's url and ref. */
|
|
2
|
+
export interface PluginInstall {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string | null;
|
|
5
|
+
sourcePath: string | null;
|
|
6
|
+
marketplace: {
|
|
7
|
+
name: string;
|
|
8
|
+
url: string | null;
|
|
9
|
+
ref: string | null;
|
|
10
|
+
} | null;
|
|
11
|
+
}
|
|
12
|
+
/** The directory holding this person's materialized plugins as `<dir>/<plugin name>`; undefined when none were materialized. */
|
|
13
|
+
export declare function materializedPluginsDir(person: string): string | undefined;
|
|
14
|
+
/** Install `installs` for `person` at `revision` into this process's plugin cache, once per (person, revision). When a plugin cannot
|
|
15
|
+
* be installed — a source on another machine, a marketplace that does not list it, a failed clone — the failure is held for that person
|
|
16
|
+
* and thrown by the next read of their plugins (`materializedPluginsDir`), so a request that never reads plugins, such as the one that
|
|
17
|
+
* fixes the settings, still works; the next load retries. */
|
|
18
|
+
export declare function materializePlugins(person: string, revision: number, installs: readonly PluginInstall[]): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var z=Object.defineProperty;var u=(e,n)=>z(e,"name",{value:n,configurable:!0});import{cpSync as S,existsSync as h,mkdirSync as b,renameSync as M,rmSync as w}from"node:fs";import{tmpdir as A}from"node:os";import{isAbsolute as $,join as l,relative as P,resolve as v}from"node:path";import{CrtrError as c}from"../errors.js";import{gitAsync as x}from"../git.js";import{readMarketplaceManifest as D}from"../manifest.js";const m=new Map,d=new Map;function q(e){const n=m.get(e);if(n!==void 0&&"failure"in n)throw n.failure;return n?.dir}u(q,"materializedPluginsDir");function y(e){return l(A(),"crtr-plugin-cache",e.replace(/[^A-Za-z0-9._-]/g,"_"))}u(y,"cacheRoot");async function _(e,n,o,r){const t=await x(["clone","--depth","1",...n?["--branch",n]:[],e,o]);if(t.status!==0)throw new c("plugin_install_failed",`${r}: git clone ${e} failed: ${t.stderr.trim()}`)}u(_,"cloneInto");async function R(e,n){const o=new Map;b(l(e,"plugins"),{recursive:!0});for(const r of n){if(r.sourcePath!==null)throw new c("plugin_source_unreachable",`${r.name}: its source is ${r.sourcePath} on the machine that registered it, which the control plane cannot read`);const t=r.marketplace;if(t===null)throw new c("plugin_source_unreachable",`${r.name}: it names neither a marketplace nor a path`);if(t.url===null||t.url==="")throw new c("plugin_source_unreachable",`${r.name}: its marketplace ${t.name} has no url`);const s=`${t.url}\0${t.ref??""}`;let a=o.get(s);a===void 0&&(a=l(e,"marketplaces",String(o.size)),await _(t.url,t.ref,a,`${r.name}: marketplace ${t.name}`),o.set(s,a));const i=D(a)?.plugins.find(k=>k.name===r.name);if(i===void 0)throw new c("plugin_install_failed",`${r.name}: marketplace ${t.name} (${t.url}) does not list it`);const f=l(e,"plugins",r.name);if($(i.source)||/^[a-z][a-z0-9+.-]*:|^git@/i.test(i.source)||i.source.endsWith(".git")){await _(i.source,null,f,r.name);continue}const p=v(a,i.source),g=P(a,p);if(g.startsWith("..")||$(g))throw new c("plugin_install_failed",`${r.name}: its source ${i.source} leaves the marketplace`);if(!h(p))throw new c("plugin_install_failed",`${r.name}: its source ${i.source} is not in marketplace ${t.name}`);S(p,f,{recursive:!0})}w(l(e,"marketplaces"),{recursive:!0,force:!0})}u(R,"installAll");async function B(e,n,o){const r=m.get(e);if(r?.revision===n&&!("failure"in r))return;const t=l(y(e),String(n)),s=`${e}\0${n}`;let a=d.get(s);a===void 0&&(a=(async()=>{if(!h(l(t,"plugins"))){const i=l(y(e),`${n}.${process.pid}.${Date.now()}`);try{await R(i,o);try{M(i,t)}catch(f){if(!h(l(t,"plugins")))throw f}}finally{w(i,{recursive:!0,force:!0})}}return l(t,"plugins")})().finally(()=>d.delete(s)),d.set(s,a));try{m.set(e,{revision:n,dir:await a})}catch(i){if(!(i instanceof c))throw i;m.set(e,{revision:n,failure:i})}}u(B,"materializePlugins");export{B as materializePlugins,q as materializedPluginsDir};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { type PersonSnapshot } from './person-store.js';
|
|
2
2
|
/** Conversion is intentionally explicit. Deployment coordination must prove all legacy writers at these shared roots are stopped before calling it. */
|
|
3
3
|
export declare function convertLegacyScopedStore(input: {
|
|
4
4
|
kind: 'user' | 'project' | 'provider';
|
|
@@ -6,3 +6,10 @@ export declare function convertLegacyScopedStore(input: {
|
|
|
6
6
|
}): void;
|
|
7
7
|
/** Converts legacy provider pools only after the activation owner has stopped every writer sharing this agent directory. */
|
|
8
8
|
export declare function convertLegacyProviderStore(agentDir: string): Promise<void>;
|
|
9
|
+
export declare function personStoresCopied(): Promise<boolean>;
|
|
10
|
+
/** Copy this install's files into the person's rows, once: profiles, scope settings and bookkeeping, the plugin and marketplace
|
|
11
|
+
* lists, managed model accounts with their cooldowns, rotation settings, the OpenAI device id, `auth.json` API keys and the profile, app and deployment env files (sealed into `env_vars`). One
|
|
12
|
+
* transaction, skipping any key a row already holds, ending with `canvas_meta.person_stores_copied`. The files stay, unread. */
|
|
13
|
+
export declare function copyPersonStoresToRows(person: string, legacyUserSnapshot: PersonSnapshot | null, agentDir: string): Promise<void>;
|
|
14
|
+
/** The install's person just became known: copy the old local files into their rows once, then load their snapshot. */
|
|
15
|
+
export declare function adoptInstallPerson(person: string): Promise<void>;
|