@north-light/crouter 0.3.352 → 0.3.354
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 +35 -25
- package/dist/api/client.js +2 -2
- package/dist/api/dto/broker-ops.d.ts +2 -36
- package/dist/api/dto/canvas.d.ts +8 -13
- package/dist/api/dto/config.d.ts +4 -0
- package/dist/api/dto/delivery.d.ts +61 -0
- package/dist/api/dto/docs.d.ts +133 -0
- package/dist/api/dto/docs.js +1 -0
- package/dist/api/dto/health.d.ts +26 -79
- package/dist/api/dto/node-outcomes.d.ts +1 -3
- package/dist/api/dto/nodes.d.ts +5 -26
- package/dist/api/dto/objects.d.ts +167 -0
- package/dist/api/dto/objects.js +1 -0
- package/dist/api/dto/profiles.d.ts +14 -8
- package/dist/api/dto/reports.d.ts +9 -7
- package/dist/api/dto/reviews.d.ts +9 -3
- package/dist/api/dto/worktree.d.ts +1 -1
- package/dist/api/index.d.ts +0 -1
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +14 -12
- package/dist/api/routes.js +1 -1
- package/dist/build-root.js +1 -1
- package/dist/builtin-memory/00-runtime-base/00-authoring.md +10 -5
- package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
- package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
- package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
- package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
- package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
- package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
- package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
- package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
- package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
- package/dist/builtin-memory/crouter-sdk/README.md +5 -6
- package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
- package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
- package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
- package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
- package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
- package/dist/builtin-memory/explore/exploration-doc.md +4 -4
- package/dist/builtin-memory/insights/capture.md +6 -6
- package/dist/builtin-memory/insights/init.md +14 -14
- package/dist/builtin-memory/internal/INDEX.md +4 -4
- package/dist/builtin-memory/internal/agent-shaping.md +20 -20
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
- package/dist/builtin-memory/internal/marketplaces.md +2 -2
- package/dist/builtin-memory/internal/memory-loading.md +31 -30
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +16 -14
- package/dist/builtin-memory/internal/storage-tiers.md +4 -4
- package/dist/builtin-memory/memory-read-orientation.md +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
- package/dist/clients/attach/input/controller.js +1 -1
- package/dist/clients/attach/input/ref-autocomplete.js +1 -1
- package/dist/clients/attach/input/titled-editor.js +1 -1
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/render/crtr-output.d.ts +1 -2
- package/dist/clients/attach/render/crtr-output.js +17 -17
- package/dist/clients/attach/render/group-activity.d.ts +8 -8
- package/dist/clients/attach/render/group-activity.js +2 -2
- package/dist/clients/attach/render/group-recap.js +1 -1
- package/dist/clients/attach/render/tool-calls.d.ts +1 -1
- package/dist/clients/attach/session/profile-files.js +1 -1
- package/dist/clients/attach/slash/dispatch.js +1 -1
- package/dist/clients/attach/viewer.js +806 -1553
- package/dist/commands/api-client.d.ts +2 -0
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/canvas/edges.d.ts +2 -0
- package/dist/commands/canvas/edges.js +2 -0
- package/dist/commands/canvas/list.d.ts +4 -0
- package/dist/commands/canvas/list.js +3 -0
- package/dist/commands/canvas/read.d.ts +8 -0
- package/dist/commands/canvas/read.js +5 -0
- package/dist/commands/canvas/search.d.ts +2 -0
- package/dist/commands/canvas/search.js +3 -0
- package/dist/commands/canvas/unwatch.d.ts +2 -0
- package/dist/commands/canvas/unwatch.js +1 -0
- package/dist/commands/canvas/watch.d.ts +3 -0
- package/dist/commands/canvas/watch.js +1 -0
- package/dist/commands/canvas-analytics.js +1 -1
- package/dist/commands/canvas-history/grep.js +4 -4
- package/dist/commands/canvas-history/read.js +2 -2
- package/dist/commands/canvas-history/search.js +7 -7
- package/dist/commands/canvas-history/shared.d.ts +0 -1
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history/stats.js +2 -2
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/doc/delete.d.ts +2 -0
- package/dist/commands/doc/delete.js +1 -0
- package/dist/commands/doc/edit.d.ts +2 -0
- package/dist/commands/doc/edit.js +1 -0
- package/dist/commands/doc/history.d.ts +2 -0
- package/dist/commands/doc/history.js +2 -0
- package/dist/commands/doc/lint.d.ts +2 -0
- package/dist/commands/doc/lint.js +2 -0
- package/dist/commands/doc/list.d.ts +2 -0
- package/dist/commands/doc/list.js +1 -0
- package/dist/commands/doc/move.d.ts +2 -0
- package/dist/commands/doc/move.js +1 -0
- package/dist/commands/doc/read.d.ts +2 -0
- package/dist/commands/doc/read.js +1 -0
- package/dist/commands/doc/shared.d.ts +25 -0
- package/dist/commands/doc/shared.js +2 -0
- package/dist/commands/doc/write.d.ts +2 -0
- package/dist/commands/doc/write.js +1 -0
- package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
- package/dist/commands/doc.js +1 -0
- package/dist/commands/human/review.js +1 -1
- package/dist/commands/node/bash.js +2 -2
- package/dist/commands/node/create.js +1 -1
- package/dist/commands/node/inspect.js +10 -10
- package/dist/commands/node/lifecycle.js +2 -2
- package/dist/commands/node/outcome.js +1 -1
- package/dist/commands/node/subscription.js +1 -1
- package/dist/commands/node-context.js +2 -2
- package/dist/commands/pkg/browse/catalog.js +1 -1
- package/dist/commands/pkg/browse/doc-view.js +1 -1
- package/dist/commands/pkg/browse/model.d.ts +9 -17
- package/dist/commands/pkg/plugin-inspect.js +1 -1
- package/dist/commands/pkg/plugin-manage.d.ts +4 -8
- package/dist/commands/pkg/plugin-manage.js +15 -17
- package/dist/commands/profile/list.js +1 -1
- package/dist/commands/profile/new.js +1 -1
- package/dist/commands/profile/project.js +1 -1
- package/dist/commands/profile/show.js +1 -1
- package/dist/commands/push.js +3 -3
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/context/admin/actions.d.ts +18 -43
- package/dist/commands/sys/context/admin/actions.js +1 -2
- package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
- package/dist/commands/sys/context/admin/detail-panel.js +2 -1
- package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
- package/dist/commands/sys/context/admin/docs-panel.js +1 -1
- package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
- package/dist/commands/sys/context/admin/list-view.js +1 -1
- package/dist/commands/sys/context/admin/model.d.ts +96 -69
- package/dist/commands/sys/context/admin/model.js +1 -1
- package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
- package/dist/commands/sys/context/admin/rail-panel.js +1 -1
- package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
- package/dist/commands/sys/context/admin/read-view.js +1 -2
- package/dist/commands/sys/context/admin/shell.d.ts +26 -31
- package/dist/commands/sys/context/admin/shell.js +1 -1
- package/dist/commands/sys/context/admin.js +2 -2
- package/dist/commands/sys/context/doc.js +2 -3
- package/dist/commands/sys/context/expose.js +2 -2
- package/dist/commands/sys/context/prompt-review.js +4 -4
- package/dist/commands/sys/context/resolve.d.ts +92 -65
- package/dist/commands/sys/context/resolve.js +7 -9
- package/dist/commands/sys/context.js +1 -1
- package/dist/commands/sys/doctor.js +1 -1
- package/dist/commands/sys/migrate.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/sync-deps.d.ts +6 -11
- package/dist/commands/sys/sync-deps.js +7 -8
- package/dist/commands/sys/sync-project-guidance.js +5 -4
- package/dist/commands/sys/sync-shared.d.ts +41 -4
- package/dist/commands/sys/sync-shared.js +1 -1
- package/dist/commands/sys/sync-skills.js +2 -2
- package/dist/commands/sys/sync.js +1 -1
- package/dist/core/bash-job-supervisor.d.ts +2 -3
- package/dist/core/bash-job-supervisor.js +3 -3
- package/dist/core/bash-jobs.d.ts +0 -5
- package/dist/core/bash-jobs.js +7 -7
- package/dist/core/bootstrap.js +2 -2
- package/dist/core/canvas/canvas.d.ts +6 -50
- package/dist/core/canvas/canvas.js +16 -21
- package/dist/core/canvas/db.d.ts +4 -1
- package/dist/core/canvas/db.js +2 -2
- package/dist/core/canvas/history.d.ts +11 -39
- package/dist/core/canvas/history.js +9 -20
- package/dist/core/canvas/install-id.d.ts +2 -2
- package/dist/core/canvas/install-id.js +1 -1
- package/dist/core/canvas/memory-reads.d.ts +5 -0
- package/dist/core/canvas/memory-reads.js +1 -1
- package/dist/core/canvas/migrations.js +215 -41
- package/dist/core/canvas/node-agent-paths.js +1 -1
- package/dist/core/canvas/node-tokens.js +1 -1
- package/dist/core/canvas/paths.d.ts +0 -4
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
- package/dist/core/canvas/remote-canvas-source.js +1 -1
- package/dist/core/canvas/render-source.d.ts +9 -6
- package/dist/core/canvas/render-source.js +6 -6
- package/dist/core/canvas/sessions.js +2 -2
- package/dist/core/canvas/source.d.ts +6 -0
- package/dist/core/canvas/tree.d.ts +29 -0
- package/dist/core/canvas/tree.js +12 -0
- package/dist/core/canvas/types.d.ts +0 -20
- package/dist/core/command-plugins/bundle.js +1 -1
- package/dist/core/config.d.ts +1 -1
- package/dist/core/conversation-store/listener.js +4 -2
- package/dist/core/feed/feed.d.ts +9 -7
- package/dist/core/feed/feed.js +3 -7
- package/dist/core/feed/inbox.d.ts +3 -5
- package/dist/core/feed/inbox.js +1 -10
- package/dist/core/feed/messages.d.ts +33 -6
- package/dist/core/feed/messages.js +10 -7
- package/dist/core/feed/reports.d.ts +10 -0
- package/dist/core/feed/reports.js +2 -0
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/graph/access.d.ts +24 -0
- package/dist/core/graph/access.js +8 -0
- package/dist/core/graph/bodies.d.ts +6 -0
- package/dist/core/graph/bodies.js +1 -0
- package/dist/core/graph/deletion.d.ts +9 -0
- package/dist/core/graph/deletion.js +5 -0
- package/dist/core/graph/diff.d.ts +4 -0
- package/dist/core/graph/diff.js +4 -0
- package/dist/core/graph/documents.d.ts +160 -0
- package/dist/core/graph/documents.js +7 -0
- package/dist/core/graph/edges.d.ts +24 -0
- package/dist/core/graph/edges.js +1 -0
- package/dist/core/graph/events.d.ts +26 -0
- package/dist/core/graph/events.js +6 -0
- package/dist/core/graph/exposures.d.ts +53 -0
- package/dist/core/graph/exposures.js +4 -0
- package/dist/core/graph/jobs.d.ts +31 -0
- package/dist/core/graph/jobs.js +2 -0
- package/dist/core/graph/names.d.ts +28 -0
- package/dist/core/graph/names.js +3 -0
- package/dist/core/graph/objects.d.ts +55 -0
- package/dist/core/graph/objects.js +9 -0
- package/dist/core/graph/package-docs.d.ts +31 -0
- package/dist/core/graph/package-docs.js +5 -0
- package/dist/core/graph/package-files.d.ts +20 -0
- package/dist/core/graph/package-files.js +2 -0
- package/dist/core/graph/reader.d.ts +21 -0
- package/dist/core/graph/reader.js +3 -0
- package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
- package/dist/core/graph/repo-sync/exchange.js +2 -0
- package/dist/core/graph/repo-sync/identity.d.ts +30 -0
- package/dist/core/graph/repo-sync/identity.js +1 -0
- package/dist/core/graph/repo-sync/index.d.ts +4 -0
- package/dist/core/graph/repo-sync/index.js +1 -0
- package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
- package/dist/core/graph/repo-sync/mirror.js +6 -0
- package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
- package/dist/core/graph/repo-sync/ref-format.js +2 -0
- package/dist/core/graph/repo-sync/repos.d.ts +17 -0
- package/dist/core/graph/repo-sync/repos.js +3 -0
- package/dist/core/graph/repo-sync/sync.d.ts +42 -0
- package/dist/core/graph/repo-sync/sync.js +2 -0
- package/dist/core/graph/rules.d.ts +26 -0
- package/dist/core/graph/rules.js +3 -0
- package/dist/core/graph/spaces/app.d.ts +3 -0
- package/dist/core/graph/spaces/app.js +1 -0
- package/dist/core/graph/spaces/index.d.ts +19 -0
- package/dist/core/graph/spaces/index.js +1 -0
- package/dist/core/graph/spaces/person.d.ts +5 -0
- package/dist/core/graph/spaces/person.js +2 -0
- package/dist/core/graph/spaces/repo.d.ts +4 -0
- package/dist/core/graph/spaces/repo.js +1 -0
- package/dist/core/graph/types.d.ts +75 -0
- package/dist/core/graph/types.js +1 -0
- package/dist/core/graph/watches.d.ts +62 -0
- package/dist/core/graph/watches.js +18 -0
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/requests.d.ts +3 -1
- package/dist/core/human/requests.js +6 -6
- package/dist/core/inspector/model.js +2 -2
- package/dist/core/io.js +5 -5
- package/dist/core/layout-migrate/index.d.ts +24 -1
- package/dist/core/layout-migrate/index.js +4 -4
- package/dist/core/layout-migrate/paths.d.ts +4 -0
- package/dist/core/layout-migrate/paths.js +1 -1
- package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
- package/dist/core/layout-migrate/stored-paths.js +11 -11
- package/dist/core/layout-migrate/stores.d.ts +19 -6
- package/dist/core/layout-migrate/stores.js +3 -4
- package/dist/core/manifest.d.ts +0 -2
- package/dist/core/manifest.js +1 -1
- package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
- package/dist/core/plugin-extensions.js +1 -0
- package/dist/core/preview-registry.d.ts +1 -1
- package/dist/core/preview-registry.js +3 -2
- package/dist/core/profiles/manifest.d.ts +7 -7
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/profiles/select.js +3 -3
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/stage.d.ts +12 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/store.d.ts +2 -0
- package/dist/core/review/store.js +1 -1
- package/dist/core/review/types.d.ts +7 -1
- package/dist/core/runs/events.js +1 -1
- package/dist/core/runs/operations.js +5 -5
- package/dist/core/runs/questions.js +2 -2
- package/dist/core/runtime/bearings-render.d.ts +13 -7
- package/dist/core/runtime/bearings-render.js +12 -12
- package/dist/core/runtime/bearings.d.ts +8 -18
- package/dist/core/runtime/bearings.js +7 -7
- package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
- 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-dispatch.d.ts +1 -1
- package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
- package/dist/core/runtime/broker/inbox.d.ts +1 -4
- package/dist/core/runtime/broker/inbox.js +1 -10
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
- package/dist/core/runtime/broker/retry-card-elision.js +1 -0
- package/dist/core/runtime/broker-extension-render.d.ts +0 -13
- package/dist/core/runtime/broker-extension-render.js +2 -4
- package/dist/core/runtime/broker-persona-guidance.js +3 -3
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +9 -4
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/kickoff.js +17 -19
- package/dist/core/runtime/launch-target.d.ts +7 -0
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/ledger.d.ts +10 -0
- package/dist/core/runtime/ledger.js +3 -0
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/nodes.d.ts +10 -2
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +2 -2
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.d.ts +2 -2
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/prospective-inventory-cli.js +2 -2
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/roadmap.d.ts +17 -9
- package/dist/core/runtime/roadmap.js +4 -4
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.d.ts +5 -3
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/structured-output.d.ts +3 -1
- package/dist/core/runtime/structured-output.js +4 -4
- package/dist/core/scope.d.ts +1 -32
- package/dist/core/scope.js +1 -1
- package/dist/core/scoped-state/db.js +2 -1
- package/dist/core/scoped-state/migrate.js +2 -2
- package/dist/core/scoped-state/profiles.d.ts +11 -0
- package/dist/core/scoped-state/profiles.js +1 -1
- package/dist/core/scoped-state/schema.d.ts +1 -1
- package/dist/core/scoped-state/schema.js +7 -5
- package/dist/core/spaces/permissions.d.ts +0 -14
- package/dist/core/spaces/permissions.js +1 -1
- package/dist/core/spaces/stop.d.ts +13 -0
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/storage/tables.d.ts +1 -1
- package/dist/core/substrate/delivery/corpus.d.ts +21 -0
- package/dist/core/substrate/delivery/corpus.js +3 -0
- package/dist/core/substrate/delivery/deliver.d.ts +76 -0
- package/dist/core/substrate/delivery/deliver.js +6 -0
- package/dist/core/substrate/delivery/listings.d.ts +27 -0
- package/dist/core/substrate/delivery/listings.js +4 -0
- package/dist/core/substrate/delivery/match.d.ts +28 -0
- package/dist/core/substrate/delivery/match.js +1 -0
- package/dist/core/substrate/delivery/plan.d.ts +67 -0
- package/dist/core/substrate/delivery/plan.js +3 -0
- package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
- package/dist/core/substrate/delivery/render-boot.js +54 -0
- package/dist/core/substrate/delivery/render-event.d.ts +47 -0
- package/dist/core/substrate/delivery/render-event.js +6 -0
- package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
- package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
- package/dist/core/substrate/delivery/types.d.ts +30 -0
- package/dist/core/substrate/delivery/types.js +0 -0
- package/dist/core/substrate/gate-explain.d.ts +0 -13
- package/dist/core/substrate/gate-explain.js +1 -1
- package/dist/core/substrate/schema.d.ts +11 -139
- package/dist/core/substrate/schema.js +1 -1
- package/dist/core/substrate/subject-fields.d.ts +3 -0
- package/dist/core/substrate/subject.d.ts +2 -1
- package/dist/core/substrate/subject.js +1 -1
- package/dist/daemon/api/app-listener.js +11 -11
- package/dist/daemon/api/handlers/app-profiles.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -2
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +5 -5
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/delivery.d.ts +2 -0
- package/dist/daemon/api/handlers/delivery.js +1 -0
- package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
- package/dist/daemon/api/handlers/docs.js +1 -0
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/modelauth.d.ts +3 -0
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-records.js +2 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.d.ts +2 -0
- package/dist/daemon/api/handlers/objects.js +5 -0
- package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
- package/dist/daemon/api/handlers/package-docs.js +1 -0
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/reports.d.ts +2 -2
- package/dist/daemon/api/handlers/reports.js +4 -4
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/vendor-status.d.ts +8 -0
- package/dist/daemon/api/handlers/vendor-status.js +1 -0
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.d.ts +1 -1
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/principal.d.ts +5 -0
- package/dist/daemon/api/principal.js +1 -1
- package/dist/daemon/api/reader.d.ts +17 -0
- package/dist/daemon/api/reader.js +1 -0
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/control.d.ts +2 -3
- package/dist/daemon/crtrd.js +8 -6
- package/dist/daemon/fleet.js +4 -4
- package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
- package/dist/daemon/reconcilers/bash-deadline.js +2 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/review/deliver.js +2 -2
- package/dist/daemon/review/finish.js +1 -1
- package/dist/hook-authoring.d.ts +0 -1
- package/dist/hook-authoring.js +3 -3
- package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
- package/dist/migrations/004-canvas-documents/apply.js +1 -0
- package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
- package/dist/migrations/004-canvas-documents/fields.js +2 -0
- package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
- package/dist/migrations/004-canvas-documents/index.js +2 -0
- package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
- package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
- package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
- package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
- package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
- package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
- package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
- package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
- package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
- package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
- package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
- package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
- package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
- package/dist/migrations/004-canvas-documents/plan.js +3 -0
- package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
- package/dist/migrations/004-canvas-documents/pointers.js +4 -0
- package/dist/migrations/activation.d.ts +9 -18
- package/dist/migrations/activation.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +2 -2
- package/dist/pi-extensions/broker-local.js +2 -2
- package/dist/pi-extensions/canvas-bash-valve.js +5 -4
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
- package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-passive-context.js +1 -1
- package/dist/pi-extensions/canvas-recap.js +2 -2
- package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/prompts/review.js +3 -3
- package/dist/shared/env.d.ts +5 -0
- package/dist/shared/env.js +1 -1
- package/dist/shared/generated-context.js +2 -10
- package/dist/shared/inbox-entry-body.d.ts +22 -0
- package/dist/shared/inbox-entry-body.js +10 -0
- package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
- package/dist/shared/inline-ref-guidance.js +2 -0
- package/dist/types.d.ts +3 -1
- package/docs/cli/memory-and-preferences.md +12 -14
- package/docs/concepts/README.md +1 -1
- package/docs/concepts/lifecycle-and-wakes.md +1 -1
- package/docs/concepts/memory.md +15 -15
- package/docs/concepts/nodes-and-the-canvas.md +1 -1
- package/docs/concepts/profiles-kinds-and-modes.md +5 -5
- package/docs/concepts/scopes-and-trust.md +1 -1
- package/docs/concepts/why-a-daemon.md +1 -1
- package/docs/sdk/README.md +5 -6
- package/docs/sdk/errors.md +0 -13
- package/docs/sdk/guides/README.md +0 -1
- package/docs/sdk/nodes.md +0 -2
- package/docs/sdk/resources.md +0 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +11 -11
- package/dist/api/dto/memory.d.ts +0 -171
- package/dist/api/dto/memory.js +0 -1
- package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
- package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
- package/dist/commands/broker-permissions.d.ts +0 -2
- package/dist/commands/broker-permissions.js +0 -1
- package/dist/commands/memory/client.d.ts +0 -11
- package/dist/commands/memory/client.js +0 -1
- package/dist/commands/memory/delete.d.ts +0 -1
- package/dist/commands/memory/delete.js +0 -1
- package/dist/commands/memory/edit.d.ts +0 -1
- package/dist/commands/memory/edit.js +0 -21
- package/dist/commands/memory/find.d.ts +0 -1
- package/dist/commands/memory/find.js +0 -1
- package/dist/commands/memory/history.d.ts +0 -1
- package/dist/commands/memory/history.js +0 -5
- package/dist/commands/memory/lint.d.ts +0 -1
- package/dist/commands/memory/lint.js +0 -1
- package/dist/commands/memory/list.d.ts +0 -1
- package/dist/commands/memory/list.js +0 -1
- package/dist/commands/memory/move.d.ts +0 -1
- package/dist/commands/memory/move.js +0 -1
- package/dist/commands/memory/origin.d.ts +0 -1
- package/dist/commands/memory/origin.js +0 -1
- package/dist/commands/memory/read.d.ts +0 -1
- package/dist/commands/memory/read.js +0 -6
- package/dist/commands/memory/shared.d.ts +0 -22
- package/dist/commands/memory/shared.js +0 -1
- package/dist/commands/memory/write.d.ts +0 -1
- package/dist/commands/memory/write.js +0 -13
- package/dist/commands/memory.js +0 -1
- package/dist/commands/node-inspect-artifacts.d.ts +0 -1
- package/dist/commands/node-inspect-artifacts.js +0 -8
- package/dist/core/help/memory-extensions.d.ts +0 -3
- package/dist/core/help/memory-extensions.js +0 -2
- package/dist/core/memory/cli-selector.d.ts +0 -13
- package/dist/core/memory/cli-selector.js +0 -1
- package/dist/core/memory/doc-link-grammar.d.ts +0 -20
- package/dist/core/memory/doc-link-grammar.js +0 -2
- package/dist/core/memory/extensions.js +0 -1
- package/dist/core/memory/history.d.ts +0 -87
- package/dist/core/memory/history.js +0 -6
- package/dist/core/memory/identity.d.ts +0 -65
- package/dist/core/memory/identity.js +0 -1
- package/dist/core/memory/inline-ref-guidance.js +0 -2
- package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
- package/dist/core/memory/inline-ref-inventory.js +0 -1
- package/dist/core/memory/lint.d.ts +0 -163
- package/dist/core/memory/lint.js +0 -2
- package/dist/core/memory/mutation-domain.d.ts +0 -113
- package/dist/core/memory/mutation-domain.js +0 -12
- package/dist/core/memory/mutations.d.ts +0 -74
- package/dist/core/memory/mutations.js +0 -1
- package/dist/core/memory/project-namespace.d.ts +0 -31
- package/dist/core/memory/project-namespace.js +0 -2
- package/dist/core/memory/repository-association.d.ts +0 -31
- package/dist/core/memory/repository-association.js +0 -1
- package/dist/core/memory/service.d.ts +0 -145
- package/dist/core/memory/service.js +0 -2
- package/dist/core/memory/tree.d.ts +0 -39
- package/dist/core/memory/tree.js +0 -1
- package/dist/core/memory-resolver.d.ts +0 -280
- package/dist/core/memory-resolver.js +0 -2
- package/dist/core/nested-stores.d.ts +0 -18
- package/dist/core/nested-stores.js +0 -1
- package/dist/core/runtime/memory.d.ts +0 -3
- package/dist/core/runtime/memory.js +0 -1
- package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
- package/dist/core/substrate/frontmatter-validation.js +0 -1
- package/dist/core/substrate/gate.d.ts +0 -16
- package/dist/core/substrate/gate.js +0 -1
- package/dist/core/substrate/index.d.ts +0 -18
- package/dist/core/substrate/index.js +0 -1
- package/dist/core/substrate/injected-store.d.ts +0 -75
- package/dist/core/substrate/injected-store.js +0 -2
- package/dist/core/substrate/listings.d.ts +0 -28
- package/dist/core/substrate/listings.js +0 -1
- package/dist/core/substrate/memory-events.d.ts +0 -6
- package/dist/core/substrate/memory-events.js +0 -1
- package/dist/core/substrate/on-read-node.d.ts +0 -6
- package/dist/core/substrate/on-read-node.js +0 -1
- package/dist/core/substrate/on-read.d.ts +0 -101
- package/dist/core/substrate/on-read.js +0 -9
- package/dist/core/substrate/plan.d.ts +0 -94
- package/dist/core/substrate/plan.js +0 -1
- package/dist/core/substrate/render-node.d.ts +0 -12
- package/dist/core/substrate/render-node.js +0 -1
- package/dist/core/substrate/render.d.ts +0 -41
- package/dist/core/substrate/render.js +0 -65
- package/dist/core/substrate/session-cache.d.ts +0 -27
- package/dist/core/substrate/session-cache.js +0 -1
- package/dist/core/substrate/surface-match.d.ts +0 -73
- package/dist/core/substrate/surface-match.js +0 -1
- package/dist/daemon/api/handlers/memory.js +0 -5
- package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
- package/dist/migrations/001-surfaces-frontmatter.js +0 -1
- package/dist/migrations/002-profile-project-memory.d.ts +0 -2
- package/dist/migrations/002-profile-project-memory.js +0 -1
- package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
- package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
- package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
- package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
- package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
- package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
- package/dist/migrations/convergent.d.ts +0 -43
- package/dist/migrations/convergent.js +0 -2
- package/dist/migrations/corpus.d.ts +0 -75
- package/dist/migrations/corpus.js +0 -3
- package/dist/migrations/frontmatter-splice.d.ts +0 -15
- package/dist/migrations/frontmatter-splice.js +0 -8
- package/dist/migrations/profile-manifests.d.ts +0 -30
- package/dist/migrations/profile-manifests.js +0 -2
- package/dist/migrations/registry.d.ts +0 -7
- package/dist/migrations/registry.js +0 -1
- package/dist/migrations/runner.d.ts +0 -43
- package/dist/migrations/runner.js +0 -1
- package/dist/migrations/types.d.ts +0 -211
- package/dist/shared/birth-announcement.d.ts +0 -12
- package/dist/shared/birth-announcement.js +0 -1
- package/docs/sdk/guides/app-memory.md +0 -22
- package/docs/sdk/memory.md +0 -85
- /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
- /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
- /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var E=Object.defineProperty;var f=(n,e)=>E(n,"name",{value:e,configurable:!0});import{ApiError as d}from"../../api/index.js";import{readerFor as R}from"../../core/graph/reader.js";import{canRead as v}from"../../core/graph/access.js";import{ownersByHandle as h,resolveName as x,viewOf as j}from"../../core/graph/names.js";import{ensureOwner as y}from"../../core/graph/objects.js";import{reposForCwd as $}from"../../core/graph/repo-sync/repos.js";import{lookupProfile as F}from"../../core/profiles/manifest.js";function A(n,e){return R(n,e.principal,o=>$(n,o))}f(A,"readerFor");function b(n,e,o){const t=x(n,e,o);if("object"in t)return t.object;if("deleted"in t||"remote"in t)return t;if("ambiguous"in t){const p=t.ambiguous.map(u=>`${O(n,u)}/${u.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one object: ${p.join(", ")}`,{candidates:p,next:"Read one of them by its full `<type>:<owner>/<name>`."})}const r=o.replace(/^\s*\[\[(.*)\]\]\s*$/,"$1").trim(),i=/^(person|app|repo|profile):([^/]+)$/.exec(r),s=(i?h(n,i[2],i[1]):h(n,r).filter(p=>p.type!=="node")).filter(p=>v(n,e,p));if(s.length>0){const p=j(n,e),u=f(l=>{const c=p.findIndex(g=>g.rowid===l.rowid);return c<0?1/0:c},"rank"),w=[...s].sort((l,c)=>u(l)-u(c))[0];if(u(w)===1/0&&s.length>1){const l=s.map(c=>`${c.type}:${c.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one owner: ${l.join(", ")}`,{candidates:l,next:"Name one as `<type>:<handle>`."})}return w.deleted_at?{deleted:w}:w}const a=`'${o}' not found: no object by that name in your view`,m=`Search for it with \`crtr canvas search ${r}\`.`;throw new d(404,"not_found",a,{error:"not_found",message:a,next:m})}f(b,"resolveRef");function O(n,e){if(e.owner===null)return"";const o=n.prepare("SELECT type, id, name FROM objects WHERE rowid = ?").get(e.owner);return o.type==="node"?o.id:`${o.type}:${o.name}`}f(O,"typedOwnerHandle");function D(n,e,o,t){const r=o??(e.class==="node"?"node":e.class==="person"?"user":"app"),i=f(s=>new d(400,"invalid_owner",s,{next:"Run `crtr doc write --owner -h`."}),"refuse");if(r==="node"){if(e.class!=="node")throw i("`--owner node` needs a node; you are not running as one");return e.node}if(r==="user")return y(n,"person","local-user","user:local","user");if(r==="app"){if(e.class==="person")throw i("`--owner app` needs an app; a person has none \u2014 use `--owner user`");return e.app}if(r==="profile"){if(e.class!=="node"||!e.profile)throw i("`--owner profile` needs a profile; you have none");return e.profile}if(r==="repo"){const s=t?$(n,t):[],a=s[0]?s:e.class==="node"?e.repos:[];if(!a[0])throw i(`\`--owner repo\` needs a repo; ${t??(e.class==="node"?e.cwd:"your directory")} is not inside one`);return a[0]}if(r.startsWith("repo:"))return _(n,"repo",r.slice(5),i);if(r.startsWith("profile:")){const s=r.slice(8),a=n.prepare("SELECT * FROM objects WHERE type = 'profile' AND name = ?").get(s);if(a)return a;const m=F(s);if(m.kind!=="resolved")throw i(`no profile named '${s}'`);const p=e.class==="person"?e.person:e.app;return y(n,"profile","profile",m.entry.profileId,m.entry.manifest.name,p)}throw i(`unknown --owner value '${r}'`)}f(D,"ownerFromFlag");function _(n,e,o,t){const r=n.prepare("SELECT * FROM objects WHERE type = ? AND name = ? AND deleted_at IS NULL").get(e,o);if(!r)throw t(`no ${e} named '${o}'`);return r}f(_,"namedOwner");export{D as ownerFromFlag,A as readerFor,b as resolveRef};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var D=Object.defineProperty;var l=(t,o)=>D(t,"name",{value:o,configurable:!0});import{createServer as H}from"node:http";import{chmodSync as Y,existsSync as C,unlinkSync as x}from"node:fs";import{apiSocketPath as Z}from"../../core/canvas/paths.js";import{resolveNodeToken as I}from"../../core/canvas/node-tokens.js";import{grantFor as K,hasSyncedGrants as Q}from"../../core/grants/mirror.js";import{readConfig as U}from"../../core/config.js";import{peerUid as V}from"../../native/linux.js";import{getApiToken as X,listScopedApiTokens as q}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as ee,envCrtrdToken as re}from"../../shared/env.js";import{Router as B}from"./router.js";import{handleAttachUpgrade as te,refuseUpgrade as A}from"./bridge.js";import{boundDaemonControl as oe}from"../control.js";import{attachRoutes as ne}from"./handlers/attach.js";import{bashJobRoutes as ie}from"./handlers/bash-jobs.js";import{bashRoutes as se}from"./handlers/bash.js";import{hookExecRoutes as le}from"./handlers/hook-exec.js";import{brokerOperationRoutes as G}from"./handlers/broker-ops.js";import{brokerRecoveryRoutes as j,nodeFaultRoutes as ae}from"./handlers/broker-recovery.js";import{canvasRoutes as ce}from"./handlers/canvas.js";import{chatInventoryRoutes as ue}from"./handlers/chat-inventory.js";import{daemonRoutes as pe}from"./handlers/daemon.js";import{fileRoutes as de}from"./handlers/files.js";import{focusRoutes as me}from"./handlers/focus.js";import{analyticsRoutes as fe}from"./handlers/analytics.js";import{memoryReadsRoutes as ge}from"./handlers/memory-reads.js";import{healthRoutes as he}from"./handlers/health.js";import{humanRequestRoutes as Ae}from"./handlers/human-requests.js";import{inboxRoutes as Re}from"./handlers/inbox.js";import{feedbackCommentRoutes as ve}from"./handlers/feedback-comments.js";import{memoryRoutes as ye}from"./handlers/memory.js";import{brokerMailRoutes as $,messageRoutes as be}from"./handlers/messages.js";import{modelAuthRoutes as we}from"./handlers/modelauth.js";import{llmRoutes as Se}from"./handlers/llm.js";import{modelConfigRoutes as ke}from"./handlers/model-config.js";import{nodeRoutes as Te}from"./handlers/nodes.js";import{nodeRecordRoutes as Ee}from"./handlers/node-records.js";import{nodeOutcomeRoutes as Ce}from"./handlers/node-outcomes.js";import{nodeEventRoutes as Ue}from"./handlers/node-events.js";import{profileRoutes as Oe}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as ze}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as Pe}from"./handlers/reports.js";import{runRoutes as _e}from"./handlers/run-routes.js";import{reviewCommentRoutes as Ne}from"./handlers/review-comments.js";import{reviewRoutes as He}from"./handlers/reviews.js";import{subscriptionRoutes as xe}from"./handlers/subscriptions.js";import{cronRoutes as Ie}from"./handlers/crons.js";import{worktreeRoutes as Be}from"./handlers/worktree.js";function Ge(t){return new B().registerAll(he(t)).registerAll(pe).registerAll(Te).registerAll(Ee).registerAll(Ce).registerAll(Ue).registerAll(ie).registerAll(se).registerAll(le).registerAll(G).registerAll(j).registerAll(ae).registerAll(Be).registerAll($).registerAll(be).registerAll(Pe).registerAll(_e).registerAll(ne).registerAll(ce).registerAll(fe).registerAll(ge).registerAll(de).registerAll(ye).registerAll(me).registerAll(xe).registerAll(Ie).registerAll(Oe).registerAll(we).registerAll(Se).registerAll(ke).registerAll(He).registerAll(Ne).registerAll(Re).registerAll(Ae).registerAll(ue).registerAll(ze).registerAll(ve)}l(Ge,"buildRouter");function je(t,o){if(t.toUpperCase()!=="GET")return null;const s=o.split("/").filter(d=>d.length>0);if(s.length!==4||s[0]!=="v1"||s[1]!=="nodes"||s[3]!=="attach")return null;const p=s[2];return p===void 0||p===""?null:decodeURIComponent(p)}l(je,"attachNodeId");function $e(t){const o=t.trim();if(o==="")return null;const s=o.lastIndexOf(":");if(s<0)return null;const p=o.slice(0,s),d=o.slice(s+1),c=Number(d);return!Number.isInteger(c)||c<0||c>65535?null:{host:p===""?"0.0.0.0":p,port:c}}l($e,"parseTcp");function Fe(t,o){return`${t.includes(":")?`[${t}]`:t}:${o}`}l(Fe,"formatTcpAddress");const v={code:"unauthorized",message:"missing or invalid bearer token"},w={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},S=new WeakMap;function Je(t){return S.get(t)}l(Je,"socketPrincipal");function F(t,o){const s=process.platform==="linux"?V(t.socket):null,p=t.headers.authorization;if(p===void 0)return s===null||o.has(s)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";const d=I(p.slice(7));if(!d||s!==null&&s!==d.uid)return"unauthorized";const c=U("user").runtime?.issuer;if(c&&!Q(c.replace(/\/$/,"")))return"runtime_starting";const y=d.grant??K("app:terminal",d.sub)?.id??null;return{class:"broker",...d,grant:y}}l(F,"resolveSocketPrincipal");function Le(t){const o=new Map;for(const s of q("user"))o.set(s.token,{principal:{class:"app",app:s.grantee,scopes:s.scopes},ceiling:s.scopes});return o.set(t,{principal:{class:"person"},ceiling:null}),o}l(Le,"resolveBearers");function J(t,o){const s=t.headers.authorization;if(!(typeof s!="string"||!s.startsWith("Bearer ")))return o.get(s.slice(7))}l(J,"authorize");function k(t){t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:v}))}l(k,"writeUnauthorized");function Me(t,o){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:o}}))}l(Me,"writeStartupBlocked");function L(t){return new Promise(o=>{try{t.closeAllConnections()}catch{}t.close(()=>o())})}l(L,"closeServer");function Fr(t={}){let o=null;const s=Ge(()=>o),p=new B().registerAll(G).registerAll(j).registerAll($),d=l((e,r)=>{const n=oe()?.startupBlock()??null;return n===null||e==="GET"&&(r==="/healthz"||r==="/v1/status")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||n.phase==="recovering"&&p.match(e,r)!==null?null:n},"startupBlockFor"),c=Z(),y=new Set([process.getuid?.()??0,...U("user").runtime?.person_uids??[]]),T=l((e,r,n)=>{const a=l(i=>{g({event:"api.request.failed",level:"error",error:i instanceof Error?i:new Error(String(i))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error"}}))}catch{}},"internalFailure");let h;try{h=new URL(e.url??"/","http://127.0.0.1")}catch{try{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid"}}))}catch{}return}try{const i=d((e.method??"GET").toUpperCase(),h.pathname);if(i!==null){Me(r,i.message);return}s.handle(e,r,n,Je(e)??{class:"person"}).catch(a)}catch(i){a(i)}},"onRequest"),E=l((e,r,n)=>{r.on("error",()=>{});try{const a=new URL(e.url??"/","http://127.0.0.1"),h=d((e.method??"GET").toUpperCase(),a.pathname);if(h!==null){A(r,503,"Service Unavailable","startup_blocked",h.message);return}const i=je(e.method??"GET",a.pathname);if(i===null){r.destroy();return}te(e,r,n,i).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),M=l(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),R=H((e,r)=>{try{const n=F(e,y);if(n==="unauthorized"){k(r);return}if(n==="runtime_starting"){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}S.set(e,n),n.class==="broker"&&g({event:"api.request.principal",level:"info",node_id:n.node,fields:{principal:`${n.app} node:${n.node}`,method:e.method,path:e.url}}),T(e,r,null)}catch(n){g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}),k(r)}});R.on("upgrade",(e,r,n)=>{try{const a=F(e,y);if(a==="unauthorized"||a==="runtime_starting"){A(r,a==="unauthorized"?401:503,"Unauthorized",a,"socket principal unavailable");return}if(a.class!=="person"){A(r,403,"Forbidden",w.code,w.message);return}S.set(e,a),E(e,r,n)}catch(a){g({event:"api.principal.failed",level:"error",error:a instanceof Error?a:new Error(String(a))}),A(r,401,"Unauthorized",v.code,v.message)}});let O=!1,z,P;const W=new Promise((e,r)=>{z=e,P=r});R.once("listening",()=>{O=!0,z()}),R.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),O||P(e)});try{C(c)&&x(c)}catch{}R.listen(c,()=>{try{Y(c,process.platform==="linux"&&C("/run/crtr/launcher.sock")?438:384)}catch(e){g({event:"api.socket.chmod_failed",level:"error",error:e instanceof Error?e:new Error(String(e))})}});let f;const b=t.tcp??ee()??U("user").api.tcp;if(b!==void 0&&b!==""){const e=$e(b);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${b}`)});else{const r=t.token??re()??X("user"),n=r===void 0?void 0:Le(r),a=n===void 0?(i,u)=>{const m=i.headers.authorization;if(typeof m=="string"&&m.startsWith("Bearer ")&&I(m.slice(7))){k(u);return}T(i,u,null)}:(i,u)=>{if((i.method??"GET").toUpperCase()==="OPTIONS"){u.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"authorization, content-type","Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),u.end();return}const m=J(i,n);if(m===void 0){k(u);return}S.set(i,m.principal),u.setHeader("Access-Control-Allow-Origin","*"),T(i,u,m.ceiling)},h=n===void 0?E:(i,u,m)=>{const N=J(i,n);if(N===void 0){A(u,401,"Unauthorized",v.code,v.message);return}if(N.ceiling!==null){A(u,403,"Forbidden",w.code,w.message);return}E(i,u,m)};f=H(a),f.on("upgrade",h),M(f),f.once("listening",()=>{const i=f?.address();if(i!==null&&typeof i=="object"){const{address:u,port:m}=i;o=Fe(u,m)}}),f.listen(e.port,e.host)}}let _=!1;return{ready:W,tcpAddress:l(()=>o,"tcpAddress"),close:l(async()=>{if(!_){_=!0,await Promise.all([L(R),f!==void 0?L(f):Promise.resolve()]);try{C(c)&&x(c)}catch{}}},"close")}}l(Fr,"createApiServer");export{Fr as createApiServer,Je as socketPrincipal};
|
|
1
|
+
var Y=Object.defineProperty;var a=(t,o)=>Y(t,"name",{value:o,configurable:!0});import{createServer as H}from"node:http";import{chmodSync as Z,existsSync as C,unlinkSync as x}from"node:fs";import{apiSocketPath as K}from"../../core/canvas/paths.js";import{resolveNodeToken as I}from"../../core/canvas/node-tokens.js";import{grantFor as Q,hasSyncedGrants as V}from"../../core/grants/mirror.js";import{readConfig as U}from"../../core/config.js";import{peerUid as X}from"../../native/linux.js";import{getApiToken as q,listScopedApiTokens as ee}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as re,envCrtrdToken as te}from"../../shared/env.js";import{Router as B}from"./router.js";import{handleAttachUpgrade as oe,refuseUpgrade as A}from"./bridge.js";import{boundDaemonControl as ne}from"../control.js";import{attachRoutes as ie}from"./handlers/attach.js";import{bashJobRoutes as se}from"./handlers/bash-jobs.js";import{bashRoutes as le}from"./handlers/bash.js";import{hookExecRoutes as ae}from"./handlers/hook-exec.js";import{brokerOperationRoutes as j}from"./handlers/broker-ops.js";import{brokerRecoveryRoutes as G,nodeFaultRoutes as ce}from"./handlers/broker-recovery.js";import{canvasRoutes as ue}from"./handlers/canvas.js";import{chatInventoryRoutes as pe}from"./handlers/chat-inventory.js";import{daemonRoutes as de}from"./handlers/daemon.js";import{fileRoutes as me}from"./handlers/files.js";import{focusRoutes as fe}from"./handlers/focus.js";import{analyticsRoutes as ge}from"./handlers/analytics.js";import{memoryReadsRoutes as he}from"./handlers/memory-reads.js";import{healthRoutes as Ae}from"./handlers/health.js";import{humanRequestRoutes as Re}from"./handlers/human-requests.js";import{inboxRoutes as ve}from"./handlers/inbox.js";import{feedbackCommentRoutes as ye}from"./handlers/feedback-comments.js";import{objectRoutes as be}from"./handlers/objects.js";import{docRoutes as we}from"./handlers/docs.js";import{deliveryRoutes as $}from"./handlers/delivery.js";import{packageDocRoutes as ke}from"./handlers/package-docs.js";import{brokerMailRoutes as F,messageRoutes as Se}from"./handlers/messages.js";import{modelAuthRoutes as Te}from"./handlers/modelauth.js";import{llmRoutes as Ee}from"./handlers/llm.js";import{modelConfigRoutes as Ce}from"./handlers/model-config.js";import{nodeRoutes as Ue}from"./handlers/nodes.js";import{nodeRecordRoutes as Oe}from"./handlers/node-records.js";import{nodeOutcomeRoutes as ze}from"./handlers/node-outcomes.js";import{nodeEventRoutes as Pe}from"./handlers/node-events.js";import{profileRoutes as _e}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as Ne}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as He}from"./handlers/reports.js";import{runRoutes as xe}from"./handlers/run-routes.js";import{reviewCommentRoutes as Ie}from"./handlers/review-comments.js";import{reviewRoutes as Be}from"./handlers/reviews.js";import{subscriptionRoutes as je}from"./handlers/subscriptions.js";import{cronRoutes as Ge}from"./handlers/crons.js";import{worktreeRoutes as $e}from"./handlers/worktree.js";function Fe(t){return new B().registerAll(Ae(t)).registerAll(de).registerAll(Ue).registerAll(Oe).registerAll(ze).registerAll(Pe).registerAll(se).registerAll(le).registerAll(ae).registerAll(j).registerAll($).registerAll(G).registerAll(ce).registerAll($e).registerAll(F).registerAll(Se).registerAll(He).registerAll(xe).registerAll(ie).registerAll(ue).registerAll(ge).registerAll(he).registerAll(me).registerAll(be).registerAll(we).registerAll(ke).registerAll(fe).registerAll(je).registerAll(Ge).registerAll(_e).registerAll(Te).registerAll(Ee).registerAll(Ce).registerAll(Be).registerAll(Ie).registerAll(ve).registerAll(Re).registerAll(pe).registerAll(Ne).registerAll(ye)}a(Fe,"buildRouter");function Je(t,o){if(t.toUpperCase()!=="GET")return null;const s=o.split("/").filter(d=>d.length>0);if(s.length!==4||s[0]!=="v1"||s[1]!=="nodes"||s[3]!=="attach")return null;const p=s[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(Je,"attachNodeId");function Le(t){const o=t.trim();if(o==="")return null;const s=o.lastIndexOf(":");if(s<0)return null;const p=o.slice(0,s),d=o.slice(s+1),c=Number(d);return!Number.isInteger(c)||c<0||c>65535?null:{host:p===""?"0.0.0.0":p,port:c}}a(Le,"parseTcp");function De(t,o){return`${t.includes(":")?`[${t}]`:t}:${o}`}a(De,"formatTcpAddress");const v={code:"unauthorized",message:"missing or invalid bearer token"},w={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},k=new WeakMap;function Me(t){return k.get(t)}a(Me,"socketPrincipal");function J(t,o){const s=process.platform==="linux"?X(t.socket):null,p=t.headers.authorization;if(p===void 0)return s===null||o.has(s)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";const d=I(p.slice(7));if(!d||s!==null&&s!==d.uid)return"unauthorized";const c=U("user").runtime?.issuer;if(c&&!V(c.replace(/\/$/,"")))return"runtime_starting";const y=d.grant??Q("app:terminal",d.sub)?.id??null;return{class:"broker",...d,grant:y}}a(J,"resolveSocketPrincipal");function We(t){const o=new Map;for(const s of ee("user"))o.set(s.token,{principal:{class:"app",app:s.grantee,scopes:s.scopes},ceiling:s.scopes});return o.set(t,{principal:{class:"person"},ceiling:null}),o}a(We,"resolveBearers");function L(t,o){const s=t.headers.authorization;if(!(typeof s!="string"||!s.startsWith("Bearer ")))return o.get(s.slice(7))}a(L,"authorize");function S(t){t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:v}))}a(S,"writeUnauthorized");function Ye(t,o){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:o}}))}a(Ye,"writeStartupBlocked");function D(t){return new Promise(o=>{try{t.closeAllConnections()}catch{}t.close(()=>o())})}a(D,"closeServer");function Yr(t={}){let o=null;const s=Fe(()=>o),p=new B().registerAll(j).registerAll($).registerAll(G).registerAll(F),d=a((e,r)=>{const n=ne()?.startupBlock()??null;return n===null||e==="GET"&&(r==="/healthz"||r==="/v1/status")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||n.phase==="recovering"&&p.match(e,r)!==null?null:n},"startupBlockFor"),c=K(),y=new Set([process.getuid?.()??0,...U("user").runtime?.person_uids??[]]),T=a((e,r,n)=>{const l=a(i=>{g({event:"api.request.failed",level:"error",error:i instanceof Error?i:new Error(String(i))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error"}}))}catch{}},"internalFailure");let h;try{h=new URL(e.url??"/","http://127.0.0.1")}catch{try{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid"}}))}catch{}return}try{const i=d((e.method??"GET").toUpperCase(),h.pathname);if(i!==null){Ye(r,i.message);return}s.handle(e,r,n,Me(e)??{class:"person"}).catch(l)}catch(i){l(i)}},"onRequest"),E=a((e,r,n)=>{r.on("error",()=>{});try{const l=new URL(e.url??"/","http://127.0.0.1"),h=d((e.method??"GET").toUpperCase(),l.pathname);if(h!==null){A(r,503,"Service Unavailable","startup_blocked",h.message);return}const i=Je(e.method??"GET",l.pathname);if(i===null){r.destroy();return}oe(e,r,n,i).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),M=a(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),R=H((e,r)=>{try{const n=J(e,y);if(n==="unauthorized"){S(r);return}if(n==="runtime_starting"){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}k.set(e,n),n.class==="broker"&&g({event:"api.request.principal",level:"info",node_id:n.node,fields:{principal:`${n.app} node:${n.node}`,method:e.method,path:e.url}}),T(e,r,null)}catch(n){g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}),S(r)}});R.on("upgrade",(e,r,n)=>{try{const l=J(e,y);if(l==="unauthorized"||l==="runtime_starting"){A(r,l==="unauthorized"?401:503,"Unauthorized",l,"socket principal unavailable");return}if(l.class!=="person"&&l.class!=="broker"){A(r,403,"Forbidden",w.code,w.message);return}k.set(e,l),E(e,r,n)}catch(l){g({event:"api.principal.failed",level:"error",error:l instanceof Error?l:new Error(String(l))}),A(r,401,"Unauthorized",v.code,v.message)}});let O=!1,z,P;const W=new Promise((e,r)=>{z=e,P=r});R.once("listening",()=>{O=!0,z()}),R.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),O||P(e)});try{C(c)&&x(c)}catch{}R.listen(c,()=>{try{Z(c,process.platform==="linux"&&C("/run/crtr/launcher.sock")?438:384)}catch(e){g({event:"api.socket.chmod_failed",level:"error",error:e instanceof Error?e:new Error(String(e))})}});let f;const b=t.tcp??re()??U("user").api.tcp;if(b!==void 0&&b!==""){const e=Le(b);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${b}`)});else{const r=t.token??te()??q("user"),n=r===void 0?void 0:We(r),l=n===void 0?(i,u)=>{const m=i.headers.authorization;if(typeof m=="string"&&m.startsWith("Bearer ")&&I(m.slice(7))){S(u);return}T(i,u,null)}:(i,u)=>{if((i.method??"GET").toUpperCase()==="OPTIONS"){u.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"authorization, content-type","Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),u.end();return}const m=L(i,n);if(m===void 0){S(u);return}k.set(i,m.principal),u.setHeader("Access-Control-Allow-Origin","*"),T(i,u,m.ceiling)},h=n===void 0?E:(i,u,m)=>{const N=L(i,n);if(N===void 0){A(u,401,"Unauthorized",v.code,v.message);return}if(N.ceiling!==null){A(u,403,"Forbidden",w.code,w.message);return}E(i,u,m)};f=H(l),f.on("upgrade",h),M(f),f.once("listening",()=>{const i=f?.address();if(i!==null&&typeof i=="object"){const{address:u,port:m}=i;o=De(u,m)}}),f.listen(e.port,e.host)}}let _=!1;return{ready:W,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!_){_=!0,await Promise.all([D(R),f!==void 0?D(f):Promise.resolve()]);try{C(c)&&x(c)}catch{}}},"close")}}a(Yr,"createApiServer");export{Yr as createApiServer,Me as socketPrincipal};
|
package/dist/daemon/control.d.ts
CHANGED
|
@@ -23,12 +23,11 @@ export interface DaemonControl {
|
|
|
23
23
|
} | null;
|
|
24
24
|
/** Admit normal work after the daemon has prepared its storage. */
|
|
25
25
|
admitStartup(): Promise<DaemonAdmitDTO>;
|
|
26
|
-
/**
|
|
26
|
+
/** Plan or run the canvas import and resume normal startup when it completes. */
|
|
27
27
|
repairMigrations(req: {
|
|
28
28
|
dryRun: boolean;
|
|
29
|
-
dirs: readonly string[];
|
|
30
29
|
}): Promise<{
|
|
31
|
-
result: import('../migrations/
|
|
30
|
+
result: import('../migrations/activation.js').CanvasImportResult;
|
|
32
31
|
resumed: boolean;
|
|
33
32
|
resumeError?: string;
|
|
34
33
|
}>;
|
package/dist/daemon/crtrd.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
var ve=Object.defineProperty;var a=(t,n)=>ve(t,"name",{value:n,configurable:!0});import{writeFileSync as ge,readFileSync as we,rmSync as ye,mkdirSync as V,existsSync as k,chmodSync as Se}from"node:fs";import{createServer as J}from"node:http";import{dirname as _e}from"node:path";import{envCrtrdTcp as ke}from"../shared/env.js";import{serveCanvasConversationStore as be}from"../core/canvas/sessions.js";import{pollRunObservers as Ee}from"./runs/observer.js";import{randomBytes as Pe}from"node:crypto";import{apiSocketPath as Ie,crtrHome as Te}from"../core/canvas/paths.js";import{activeAppUsers as Re}from"../core/spaces/users.js";import{ensureAppSpace as xe,ensureUserFiles as De}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as E}from"../launcher/spec.js";import{launcherRequest as T}from"../launcher/client.js";import{initializeEmptyLayout as Ce,layoutNeedsMigration as Me,socketDir as Q}from"../core/layout.js";import{listNodeMemoryTargets as Y,listNodesForSupervision as Ae}from"../core/canvas/index.js";import{createApiServer as Le}from"./api/server.js";import{createAppListener as Ne}from"./api/app-listener.js";import{installLocalTerminalGrant as Ge}from"../core/grants/local.js";import{createGrantSync as $e,GRANT_SYNC_INTERVAL_S as Oe}from"../core/grants/sync.js";import{runRemovalCascades as Fe}from"../core/grants/remove.js";import{sweepSandboxes as je}from"../core/grants/on-sync.js";import{hasSyncedGrants as He}from"../core/grants/mirror.js";import{readConfig as ze}from"../core/config.js";import{reconcileUndeliveredTickets as Be}from"./human/sweep.js";import{resetHandedOffDeliveries as We}from"../core/canvas/deliveries.js";import{sweepReviews as Ue}from"./review/sweep.js";import{pidfilePath as $}from"./pidfile.js";import{rendererWarning as qe}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as Ke}from"./supervise-cadence.js";import{BrokerSupervisionReconciler as Ve}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as Je}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Qe}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as Ye}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as Xe}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as Ze}from"./reconcilers/delivery-lane.js";import{migrateLegacyExecutionIdentities as er}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as rr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as tr}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as nr}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as or}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as ir}from"./reconcilers/bash-deadline.js";import{captureLivenessSnapshot as X,capturePidCommand as ar,captureTeardownSnapshot as Z,isPidAlive as sr,isAnyPidAlive as ee,killProcessTreePids as re}from"../core/canvas/pid.js";import{bindFleet as cr,boundFleet as lr}from"../core/runtime/fleet.js";import{bindDaemonControl as dr,clearDaemonControl as pr}from"./control.js";import{execDaemon as mr,spawnDaemon as fr}from"./manage.js";import{reconcileAndMigrateBoot as ur}from"../core/canvas/boot.js";import{resolveInstallId as hr}from"../core/canvas/install-id.js";import{setInstallId as vr}from"../core/runtime/nodes.js";import{claimDaemonOwnership as gr,releaseDaemonOwnership as te}from"../core/canvas/daemon-owner.js";import{migrate as wr,openDb as yr}from"../core/canvas/db.js";import{prewarmRecentRecipes as Sr,reapStaleSpares as _r}from"../core/runtime/warm-pool.js";import{DaemonFleet as kr}from"./fleet.js";import{BOOT_MIGRATIONS as br}from"./boot-migrations.js";import{applyJoinedOwner as Er}from"./joined-owner.js";import{emitEvent as h}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as Pr}from"../core/events/source.js";import{activateOnDiskMigrations as Ir,MigrationBlockedError as Tr,runForcedOnDiskMigrations as Rr}from"../migrations/activation.js";import{convertLegacyProviderStore as xr,convertLegacyScopedStore as Dr}from"../core/scoped-state/migrate.js";import{userScopeRoot as Cr}from"../core/scope.js";import{secretsDir as Mr}from"../core/layout.js";function O(t,n){return t.includes(` --canvas-home ${n} `)}a(O,"brokerCommandDeclaresCanvasHome");function F(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}a(F,"brokerCommandEpoch");const Ar=5e3,ne=150;async function Lr(t){const n=X();if(n===null)throw h({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const s=Te(),m=[];for(const[i,p]of n.processes){const g=p.command;if(p.zombie||!g.includes("broker-cli.js")||!O(g,s)||F(g)===t)continue;const y=g.trim().split(/\s+/).at(-1)??"";y===""||y.endsWith("broker-cli.js")||m.push({pid:i,nodeId:y})}let f=0;const o=[];for(const i of m){const p=ar(i.pid);if(p===null||!p.includes("broker-cli.js")||!O(p,s)||F(p)===t||p.trim().split(/\s+/).at(-1)!==i.nodeId)continue;const g=Z(i.pid,null);if(!g.reused){try{process.platform==="linux"&&k(E)?await T({operation:"stop",pid:i.pid}):process.kill(i.pid,"SIGTERM")}catch{continue}f++,o.push({pid:i.pid,snap:g})}}const w=Date.now()+Ar;for(;Date.now()<w&&o.some(i=>ee(i.snap.tree.length>0?i.snap.tree:[i.pid]));)await new Promise(i=>setTimeout(i,ne));let v=0;for(const i of o){const p=i.snap.tree.length>0?i.snap.tree:[i.pid];ee(p)&&(process.platform==="linux"&&k(E)?await T({operation:"stop",pid:i.pid}):re(p,"SIGKILL",i.snap.identities),v++)}v>0&&await new Promise(i=>setTimeout(i,ne));const c=X();if(c===null)throw h({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const d=[];for(const[i,p]of c.processes){const g=p.command;p.zombie||!g.includes("broker-cli.js")||O(g,s)&&F(g)!==t&&d.push(i)}if(d.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${d.join(", ")}`);h({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:m.length,sigtermed:f,sigkilled:v}})}a(Lr,"reapPriorEpochBrokers");const Nr=5e3;async function Gr(t){const n=Array.from(t.entries());if(n.length===0)return;const s=n.map(([,o])=>({pid:o.pid,snap:Z(o.pid,null),exited:o.handle.exited}));for(const o of s)if(!o.snap.reused)try{process.platform==="linux"&&k(E)?await T({operation:"stop",pid:o.pid}):process.kill(o.pid,"SIGTERM")}catch{}const m=new Promise(o=>{setTimeout(o,Nr).unref()});await Promise.allSettled(s.map(o=>Promise.race([o.exited.then(()=>{}),m])));const f=[];for(const o of s)sr(o.pid)&&(process.platform==="linux"&&k(E)?await T({operation:"stop",pid:o.pid}):re(o.snap.tree.length>0?o.snap.tree:[o.pid],"SIGKILL",o.snap.identities),f.push(o));await Promise.all(f.map(o=>o.exited)),h({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:s.length,sigkilled:f.length}})}a(Gr,"teardownFleet");function oe(){V(_e($()),{recursive:!0}),ge($(),String(process.pid),"utf8")}a(oe,"writePidfile");function ie(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}a(ie,"isMissingPathError");function ae(t){const n=$();let s;try{s=we(n,"utf8")}catch(m){if(ie(m))return;throw m}if(s.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{ye(n)}catch(m){if(ie(m))return;throw m}}a(ae,"removeOwnedPidfileMirror");const $r={acceptsDetachedWork:a(()=>!0,"acceptsDetachedWork"),registerDetached:a(t=>{t.catch(()=>{})},"registerDetached")},j=new Ve,Or=new Je,Fr=new Qe,jr=new Ye,Hr=new Xe,zr=new Ze,Br=new tr,Wr=new nr,Ur=new or,qr=new ir;async function Kr(t=Date.now(),n=$r){const s=lr(),m=await j.runFleetPreamble(s);let f,o;try{const v=Ae();f=v.filter(c=>c.status==="active"||c.status==="idle"),o=v.filter(c=>c.status==="done"||c.status==="canceled"||c.status==="dead")}catch(v){h({level:"error",event:"canvas.node_list.failed",error:v});return}await j.run(t,{rows:f,fleet:s,lifecycle:n}),Or.run(t,{rows:f});const w=await Fr.run(t,{rows:[...f,...o],fleet:s});jr.run(t),Hr.run(t,{lifecycle:n}),zr.run(t,{lifecycle:n}),Br.run(t,{lifecycle:n}),Wr.run(t,{lifecycle:n,fleet:s}),Ur.run(t,{lifecycle:n}),Ee(),await qr.run(t,{rows:f}),j.warnIfSaturated({fleet:s,lifecycle:n,thresholds:m,frozen:w})}a(Kr,"superviseTick");async function Vr(t){V(Q(),{recursive:!0,mode:493}),process.platform==="linux"&&Se(Q(),493);const n=Ie();if(k(n))throw new Error(`layout refusal cannot bind occupied socket: ${n}`);const s=J((c,d)=>{if(c.method==="GET"&&c.url==="/healthz"){d.writeHead(200,{"content-type":"application/json; charset=utf-8"}),d.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}d.writeHead(503,{"content-type":"application/json; charset=utf-8"}),d.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((c,d)=>{s.once("error",d),s.listen(n,()=>{s.off("error",d),c()})});let m;const f=t.tcp??ke();if(f){const c=/^(.*):(\d+)$/.exec(f);if(!c||Number(c[2])>65535)throw new Error(`invalid refusal TCP address: ${f}`);const d=J(s.listeners("request")[0]);await new Promise((i,p)=>{d.once("error",p),d.listen(Number(c[2]),c[1],()=>{d.off("error",p),i()})}),m=d}oe();let o;const w=a(()=>(o??=(async()=>{s.closeAllConnections(),m?.closeAllConnections(),await Promise.all([s,m].filter(c=>c!==void 0).map(c=>new Promise((d,i)=>c.close(p=>p?i(p):d())))),ae(process.pid),process.off("SIGINT",v),process.off("SIGTERM",v)})(),o),"cleanup"),v=a(()=>{w().then(()=>process.exit(0),c=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(c)}
|
|
2
|
-
`),process.exit(1)})},"onSignal");return process.on("SIGINT",v),process.on("SIGTERM",v),w}a(
|
|
1
|
+
var ve=Object.defineProperty;var a=(t,n)=>ve(t,"name",{value:n,configurable:!0});import{writeFileSync as ge,readFileSync as we,rmSync as ye,mkdirSync as V,existsSync as b,chmodSync as Se}from"node:fs";import{createServer as Q}from"node:http";import{dirname as _e}from"node:path";import{envCrtrdTcp as be}from"../shared/env.js";import{serveCanvasConversationStore as ke}from"../core/canvas/sessions.js";import{pollRunObservers as Ee}from"./runs/observer.js";import{randomBytes as Pe}from"node:crypto";import{apiSocketPath as Ie,crtrHome as Re}from"../core/canvas/paths.js";import{activeAppUsers as Te}from"../core/spaces/users.js";import{ensureAppSpace as xe,ensureUserFiles as De}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as E}from"../launcher/spec.js";import{launcherRequest as R}from"../launcher/client.js";import{initializeEmptyLayout as Ce,layoutNeedsMigration as Ae,socketDir as Y}from"../core/layout.js";import{listNodesForSupervision as Le}from"../core/canvas/index.js";import{createApiServer as $e}from"./api/server.js";import{createAppListener as Me}from"./api/app-listener.js";import{installLocalTerminalGrant as Ne}from"../core/grants/local.js";import{createGrantSync as Ge,GRANT_SYNC_INTERVAL_S as Oe}from"../core/grants/sync.js";import{runRemovalCascades as Fe}from"../core/grants/remove.js";import{sweepSandboxes as je}from"../core/grants/on-sync.js";import{hasSyncedGrants as He}from"../core/grants/mirror.js";import{readConfig as Be}from"../core/config.js";import{reconcileUndeliveredTickets as ze}from"./human/sweep.js";import{resetHandedOffDeliveries as We}from"../core/canvas/deliveries.js";import{sweepReviews as qe}from"./review/sweep.js";import{pidfilePath as G}from"./pidfile.js";import{rendererWarning as Ue}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as Ke}from"./supervise-cadence.js";import{BrokerSupervisionReconciler as Je}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as Ve}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Qe}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as Ye}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as Xe}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as Ze}from"./reconcilers/delivery-lane.js";import{migrateLegacyExecutionIdentities as er}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as rr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as tr}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as nr}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as or}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as ir}from"./reconcilers/bash-deadline.js";import{captureLivenessSnapshot as X,capturePidCommand as ar,captureTeardownSnapshot as Z,isPidAlive as sr,isAnyPidAlive as ee,killProcessTreePids as re}from"../core/canvas/pid.js";import{bindFleet as cr,boundFleet as lr}from"../core/runtime/fleet.js";import{bindDaemonControl as dr,clearDaemonControl as pr}from"./control.js";import{execDaemon as mr,spawnDaemon as fr}from"./manage.js";import{reconcileAndMigrateBoot as ur}from"../core/canvas/boot.js";import{resolveInstallId as hr}from"../core/canvas/install-id.js";import{setInstallId as vr}from"../core/runtime/nodes.js";import{claimDaemonOwnership as gr,releaseDaemonOwnership as te}from"../core/canvas/daemon-owner.js";import{migrate as wr,openDb as ne,withCanvasWrite as yr}from"../core/canvas/db.js";import{reconcilePackageDocuments as Sr}from"../core/graph/package-docs.js";import{startRepoSync as _r}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as br,reapStaleSpares as kr}from"../core/runtime/warm-pool.js";import{DaemonFleet as Er}from"./fleet.js";import{BOOT_MIGRATIONS as Pr}from"./boot-migrations.js";import{applyJoinedOwner as Ir}from"./joined-owner.js";import{emitEvent as h}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as Rr}from"../core/events/source.js";import{activateCanvasImport as Tr,MigrationBlockedError as xr,runForcedCanvasImport as Dr}from"../migrations/activation.js";import{convertLegacyProviderStore as Cr,convertLegacyScopedStore as Ar}from"../core/scoped-state/migrate.js";import{userScopeRoot as Lr}from"../core/scope.js";import{secretsDir as $r}from"../core/layout.js";function O(t,n){return t.includes(` --canvas-home ${n} `)}a(O,"brokerCommandDeclaresCanvasHome");function F(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}a(F,"brokerCommandEpoch");const Mr=5e3,oe=150;async function Nr(t){const n=X();if(n===null)throw h({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const s=Re(),m=[];for(const[i,p]of n.processes){const g=p.command;if(p.zombie||!g.includes("broker-cli.js")||!O(g,s)||F(g)===t)continue;const y=g.trim().split(/\s+/).at(-1)??"";y===""||y.endsWith("broker-cli.js")||m.push({pid:i,nodeId:y})}let f=0;const o=[];for(const i of m){const p=ar(i.pid);if(p===null||!p.includes("broker-cli.js")||!O(p,s)||F(p)===t||p.trim().split(/\s+/).at(-1)!==i.nodeId)continue;const g=Z(i.pid,null);if(!g.reused){try{process.platform==="linux"&&b(E)?await R({operation:"stop",pid:i.pid}):process.kill(i.pid,"SIGTERM")}catch{continue}f++,o.push({pid:i.pid,snap:g})}}const w=Date.now()+Mr;for(;Date.now()<w&&o.some(i=>ee(i.snap.tree.length>0?i.snap.tree:[i.pid]));)await new Promise(i=>setTimeout(i,oe));let v=0;for(const i of o){const p=i.snap.tree.length>0?i.snap.tree:[i.pid];ee(p)&&(process.platform==="linux"&&b(E)?await R({operation:"stop",pid:i.pid}):re(p,"SIGKILL",i.snap.identities),v++)}v>0&&await new Promise(i=>setTimeout(i,oe));const c=X();if(c===null)throw h({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const d=[];for(const[i,p]of c.processes){const g=p.command;p.zombie||!g.includes("broker-cli.js")||O(g,s)&&F(g)!==t&&d.push(i)}if(d.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${d.join(", ")}`);h({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:m.length,sigtermed:f,sigkilled:v}})}a(Nr,"reapPriorEpochBrokers");const Gr=5e3;async function Or(t){const n=Array.from(t.entries());if(n.length===0)return;const s=n.map(([,o])=>({pid:o.pid,snap:Z(o.pid,null),exited:o.handle.exited}));for(const o of s)if(!o.snap.reused)try{process.platform==="linux"&&b(E)?await R({operation:"stop",pid:o.pid}):process.kill(o.pid,"SIGTERM")}catch{}const m=new Promise(o=>{setTimeout(o,Gr).unref()});await Promise.allSettled(s.map(o=>Promise.race([o.exited.then(()=>{}),m])));const f=[];for(const o of s)sr(o.pid)&&(process.platform==="linux"&&b(E)?await R({operation:"stop",pid:o.pid}):re(o.snap.tree.length>0?o.snap.tree:[o.pid],"SIGKILL",o.snap.identities),f.push(o));await Promise.all(f.map(o=>o.exited)),h({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:s.length,sigkilled:f.length}})}a(Or,"teardownFleet");function ie(){V(_e(G()),{recursive:!0}),ge(G(),String(process.pid),"utf8")}a(ie,"writePidfile");function ae(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}a(ae,"isMissingPathError");function se(t){const n=G();let s;try{s=we(n,"utf8")}catch(m){if(ae(m))return;throw m}if(s.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{ye(n)}catch(m){if(ae(m))return;throw m}}a(se,"removeOwnedPidfileMirror");const Fr={acceptsDetachedWork:a(()=>!0,"acceptsDetachedWork"),registerDetached:a(t=>{t.catch(()=>{})},"registerDetached")},j=new Je,jr=new Ve,Hr=new Qe,Br=new Ye,zr=new Xe,Wr=new Ze,qr=new tr,Ur=new nr,Kr=new or,Jr=new ir;async function Vr(t=Date.now(),n=Fr){const s=lr(),m=await j.runFleetPreamble(s);let f,o;try{const v=Le();f=v.filter(c=>c.status==="active"||c.status==="idle"),o=v.filter(c=>c.status==="done"||c.status==="canceled"||c.status==="dead")}catch(v){h({level:"error",event:"canvas.node_list.failed",error:v});return}await j.run(t,{rows:f,fleet:s,lifecycle:n}),jr.run(t,{rows:f});const w=await Hr.run(t,{rows:[...f,...o],fleet:s});Br.run(t),zr.run(t,{lifecycle:n}),Wr.run(t,{lifecycle:n}),qr.run(t,{lifecycle:n}),Ur.run(t,{lifecycle:n,fleet:s}),Kr.run(t,{lifecycle:n}),Ee(),await Jr.run(t,{rows:f}),j.warnIfSaturated({fleet:s,lifecycle:n,thresholds:m,frozen:w})}a(Vr,"superviseTick");async function Qr(t){V(Y(),{recursive:!0,mode:493}),process.platform==="linux"&&Se(Y(),493);const n=Ie();if(b(n))throw new Error(`layout refusal cannot bind occupied socket: ${n}`);const s=Q((c,d)=>{if(c.method==="GET"&&c.url==="/healthz"){d.writeHead(200,{"content-type":"application/json; charset=utf-8"}),d.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}d.writeHead(503,{"content-type":"application/json; charset=utf-8"}),d.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((c,d)=>{s.once("error",d),s.listen(n,()=>{s.off("error",d),c()})});let m;const f=t.tcp??be();if(f){const c=/^(.*):(\d+)$/.exec(f);if(!c||Number(c[2])>65535)throw new Error(`invalid refusal TCP address: ${f}`);const d=Q(s.listeners("request")[0]);await new Promise((i,p)=>{d.once("error",p),d.listen(Number(c[2]),c[1],()=>{d.off("error",p),i()})}),m=d}ie();let o;const w=a(()=>(o??=(async()=>{s.closeAllConnections(),m?.closeAllConnections(),await Promise.all([s,m].filter(c=>c!==void 0).map(c=>new Promise((d,i)=>c.close(p=>p?i(p):d())))),se(process.pid),process.off("SIGINT",v),process.off("SIGTERM",v)})(),o),"cleanup"),v=a(()=>{w().then(()=>process.exit(0),c=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(c)}
|
|
2
|
+
`),process.exit(1)})},"onSignal");return process.on("SIGINT",v),process.on("SIGTERM",v),w}a(Qr,"serveLayoutRefusal");async function Yr(t={}){if(Ae())return Qr(t);Ce();const n=gr(Pe(16).toString("hex"));if(!n.claimed){if(n.reason==="incumbent_alive")process.stderr.write(`[crtrd] already running (pid ${n.incumbentPid??"?"})
|
|
3
3
|
`);else{const e=[n.incumbentPid!==void 0?`pid ${n.incumbentPid}`:void 0,n.verdict!==void 0?`verdict ${n.verdict}`:void 0].filter(l=>l!==void 0),r=e.length>0?` (${e.join(", ")})`:"";process.stderr.write(`[crtrd] claim lost: ${n.reason}${r}
|
|
4
|
-
`)}return async()=>{}}const s=n.claim;let m=null;try{await
|
|
4
|
+
`)}return async()=>{}}const s=n.claim;let m=null;try{await Nr(s.token),Ar({kind:"user",root:Lr()}),await Cr($r()),wr(ne());const e=yr(r=>Sr(r));for(const r of e.conflicts)process.stderr.write(`[crtrd] plugin documents not reconciled: ${r.message}
|
|
5
|
+
`);for(const r of e.invalid)process.stderr.write(`[crtrd] package file is not a document: ${r.path}: ${r.error}
|
|
6
|
+
`);m=Ir(),process.platform==="linux"&&b(E)&&await R({operation:"users.sync",users:Te()}),rr(s.token)}catch(e){try{const{released:r}=te(s);if(!r)throw new Error("daemon ownership claim was not released")}catch(r){throw new AggregateError([e,r],"daemon startup failed and cleanup also failed")}throw e}let f=!0,o,w=Promise.resolve(),v=!1,c,d;const i=new Set;let p=!1,g=!1,y,C,H=!1,A,T,x,L,u={phase:"initializing",message:"daemon startup is running the canvas import and normal services are unavailable",blockerPaths:[]},P="initial startup activation",ce=null;function le(){return u.phase==="ready"?null:{phase:u.phase,message:u.message,blockerPaths:u.blockerPaths}}a(le,"startupBlock");function I(e){i.add(e),e.finally(()=>{i.delete(e)}).catch(()=>{})}a(I,"registerDetached");const B={acceptsDetachedWork:a(()=>f,"acceptsDetachedWork"),registerDetached:I};_r(B,ne);async function de(){try{f=!1,c!==void 0&&(clearInterval(c),c=void 0),x!==void 0&&(clearInterval(x),x=void 0);let e;do e=w,await e;while(e!==w);for(;i.size>0;)await Promise.allSettled([...i]);if(d!==void 0&&(await Or(d),d.dispose()),C!==void 0&&!H&&(H=!0,await C.close()),T!==void 0){const r=T;T=void 0,await r.close()}if(A!==void 0){const r=A;A=void 0,await r.close()}if(p||(se(process.pid),p=!0),p&&!g){const{released:r}=te(s);if(!r)throw new Error("daemon ownership claim was not released");g=!0}}finally{pr(),process.off("SIGINT",q),process.off("SIGTERM",U),process.off("exit",K)}}a(de,"cleanupAttempt");const $=1e3;let z=!1;function pe(){return z?{graceMs:$}:(z=!0,_.fresh(()=>{h({level:"info",event:"daemon.handover.armed",fields:{pid:process.pid,grace_ms:$}})}),setTimeout(()=>{me()},$),{graceMs:$})}a(pe,"requestHandover");async function me(){try{await k()}catch(e){const r=e instanceof Error?e.stack??e.message:String(e);process.stderr.write(`[crtrd] handover cleanup failed:
|
|
5
7
|
${r}
|
|
6
|
-
`),process.exit(1)}try{process.platform==="linux"&&
|
|
7
|
-
`),process.exit(1)}process.exit(0)}a(me,"performHandover");function
|
|
8
|
+
`),process.exit(1)}try{process.platform==="linux"&&b(E)&&(await R({operation:"daemon.handover"}),process.exit(0)),process.pid===1&&await mr();const e=await fr();_.fresh(()=>{h({level:"info",event:"daemon.handover.completed",fields:{predecessor_pid:process.pid,successor_pid:e.pid??e.existing_pid??null,spawned:e.started}})})}catch(e){_.fresh(()=>{h({level:"error",event:"daemon.handover.successor_failed",error:e})});const r=e instanceof Error?e.message:String(e);process.stderr.write(`[crtrd] handover successor failed to start: ${r}
|
|
9
|
+
`),process.exit(1)}process.exit(0)}a(me,"performHandover");function k(){if(y!==void 0)return y;const e=de();return y=e,e.then(()=>{y===e&&(y=void 0)},()=>{y===e&&(y=void 0)}),e}a(k,"requestCleanup");async function W(e){try{await k(),process.exit(0)}catch(r){process.exitCode=1;const l=r instanceof Error?r.stack??`${r.name}: ${r.message}`:String(r);process.stderr.write(`[crtrd] ${e} cleanup failed:
|
|
8
10
|
${l}
|
|
9
|
-
`),process.exit(1)}}a(
|
|
11
|
+
`),process.exit(1)}}a(W,"handleSignal");function q(){W("SIGINT")}a(q,"onSigint");function U(){W("SIGTERM")}a(U,"onSigterm");function K(){k().catch(()=>{})}a(K,"onExit");function M(e){f&&(w=w.then(e).then(()=>{},r=>{_.fresh(()=>{h({level:"error",event:"daemon.lane_job.failed",error:r})})}))}a(M,"enqueue");function J(){!f||v||(v=!0,M(async()=>{if(v=!1,!!f)try{await Vr(Date.now(),B)}catch(e){_.fresh(()=>{h({level:"error",event:"daemon.tick.failed",error:e})})}}))}a(J,"enqueueTick");let D=null;async function fe(){if(D!==null)throw{status:500,code:"admission_failed",message:`daemon admission previously failed: ${D instanceof Error?D.message:String(D)}`};if(u.phase==="ready")return{admitted:!1,already_admitted:!0,startup_phase:"ready"};if(u.phase!=="prepared"&&u.phase!=="recovering")throw{status:409,code:"not_prepared",message:u.message};const e=u.phase==="prepared";try{return await N(),u={phase:"ready",message:"",blockerPaths:[]},e?{admitted:!0,already_admitted:!1,startup_phase:"ready"}:{admitted:!1,already_admitted:!0,startup_phase:"ready"}}catch(r){throw D=r,{status:500,code:"admission_failed",message:`daemon admission failed: ${r instanceof Error?r.message:String(r)}`}}}a(fe,"admitStartup");async function ue(e){if(P!==null)throw{status:409,code:"migration_in_progress",message:`the canvas import is already running (${P})`};P="repair";try{const r=await Dr({dryRun:e.dryRun});if(e.dryRun||r.pending||u.phase!=="blocked")return{result:r,resumed:!1};if(t.prepare)return u={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]},{result:r,resumed:!1};try{return await N(),u={phase:"ready",message:"",blockerPaths:[]},{result:r,resumed:!0}}catch(l){const S=l instanceof Error?l.message:String(l);return setTimeout(()=>{k().catch(()=>{})},1e3),{result:r,resumed:!1,resumeError:S}}}finally{P=null}}a(ue,"repairMigrations");async function he(){o=t.intervalMs??Ke;const e=s.token;d=new Er({epoch:e,enqueue:M}),cr(d),u={phase:"recovering",message:"daemon startup recovery is running and normal services are unavailable",blockerPaths:[]},_.fresh(()=>{h({level:"info",event:"daemon.started",fields:{pid:process.pid,interval_ms:o}})});const r=hr();if(vr(r),_.fresh(()=>{h({level:"info",event:"daemon.install_id.resolved",fields:{install_id:r}})}),_.fresh(()=>{let l;try{l=Ue()}catch{return}l!==null&&h({level:"warn",event:"daemon.startup.warning",fields:{stage:"termrender",warning:l.slice(0,2048)}})}),await _.fresh(async()=>{await qe(),await ze(),We(Date.now())}),_.fresh(()=>{const{reconcile:l,migrated:S}=ur(er);l.changed&&h({level:"info",event:"daemon.boot_change.reconciled",fields:{cleared_count:l.cleared.length,same_boot_proven:l.sameBootProven}}),S.length>0&&h({level:"info",event:"daemon.pid_identity.migrated",fields:{migrated_count:S.length}})}),_.fresh(()=>{for(const l of Pr){const S=l.apply();S.changed&&h({level:"info",event:"daemon.boot_migration.applied",fields:{migration:l.id,...S.summary}})}}),L){const l=a(()=>{I(L().catch(()=>{}))},"refresh");I(Fe().catch(()=>{})),I(je().then(({completion:S})=>S).catch(S=>{h({level:"error",event:"daemon.grants.sweep_failed",error:S})})),l(),x=setInterval(l,Oe*1e3),x.unref()}M(()=>{kr(),br()}),c=setInterval(J,o),J()}a(he,"completeStartup");function N(){return ce??=he().catch(e=>{throw u={phase:"initializing",message:"daemon startup recovery failed and normal services are unavailable",blockerPaths:[]},e})}a(N,"resumeStartup");try{process.on("SIGINT",q),process.on("SIGTERM",U),process.on("exit",K),Rr(),m!==null&&h({level:"info",event:"daemon.joined_owner.applied",fields:{owner:m.owner,rows:m.rows}}),A=await ke();const e=s.token;dr({epoch:e,requestHandover:pe,registerDetached:I,startupBlock:le,admitStartup:fe,repairMigrations:ue}),ie(),C=$e({tcp:t.tcp}),await C.ready;const r=Be("user").runtime;r?.issuer?L=Ge(r.issuer,I):Ne(),r!==void 0&&(T=Me(r,()=>He(r.issuer.replace(/\/$/,"")),L),await T.ready);try{await Tr()}catch(l){if(P=null,l instanceof xr)return u={phase:"blocked",message:l.message,blockerPaths:l.blockerPaths},k;throw l}process.platform==="linux"&&b(E)&&(De(),await xe("app:terminal"));try{t.prepare?u={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]}:(await N(),u={phase:"ready",message:"",blockerPaths:[]})}finally{P=null}return k}catch(e){try{await k()}catch(r){throw new AggregateError([e,r],"daemon startup failed and cleanup also failed")}throw e}}a(Yr,"runDaemon");var cn=Yr;export{O as brokerCommandDeclaresCanvasHome,F as brokerCommandEpoch,cn as default,Yr as runDaemon,Vr as superviseTick};
|
package/dist/daemon/fleet.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
var b=Object.defineProperty;var l=(t,e)=>b(t,"name",{value:e,configurable:!0});import{getNode as p,getRow as g
|
|
1
|
+
var b=Object.defineProperty;var l=(t,e)=>b(t,"name",{value:e,configurable:!0});import{getNode as p,getRow as g}from"../core/canvas/index.js";import{revokeExitedNodeToken as k}from"../core/canvas/node-tokens.js";import{isProfilePaused as $}from"../core/profiles/manifest.js";import{fullName as v}from"../core/canvas/labels.js";import{isSafeNodeId as o}from"../core/canvas/paths.js";import{transition as _}from"../core/runtime/lifecycle.js";import{publishNotice as T}from"../core/runtime/close.js";import{readInterruptedTurn as P,readTransportPoisonVerdict as E}from"../core/canvas/recovery.js";import{hasPendingWake as N}from"./reconcilers/live-obligation.js";import{clearRespawnPolicy as h,deferRespawnWhileOffline as x,MAX_RESPAWN_ATTEMPTS as R,OFFLINE_RESPAWN_RETRY_MS as C,recordRespawnPolicy as F,respawnBackoffMs as S}from"./reconcilers/node-lifecycle/respawn-policy.js";import{probeOnline as M}from"../core/runtime/connectivity.js";import{reviveNode as A}from"../core/runtime/revive.js";import{pushUrgent as m}from"../core/feed/feed.js";import{emitEvent as c}from"../core/events/emit.js";import{brokerThresholdsForDaemon as O}from"../core/runtime/fleet.js";import{isRecoveryHeld as z}from"../core/runtime/recovery-hold.js";function w(t,e){const r=e===void 0?"The daemon did not observe an exit status.":`The observed exit status was code ${e.code??"null"}, signal ${e.signal??"null"}.`;return`\u26A0 Spawn failed \u2014 \`${t.name}\` (${t.kind}) never started.
|
|
2
2
|
|
|
3
3
|
Its pi vehicle exited before the session came up (no pi_session_id was ever recorded), so the node produced no output. ${r}
|
|
4
4
|
|
|
5
5
|
Inspect canonical event diagnostics with \`crtr sys logs --node ${t.node_id}\`.
|
|
6
6
|
|
|
7
|
-
If the work still needs doing, re-spawn it.`}l(w,"bootFailureBody");async function y(t,e){await m(t.node_id,w(t,e),{from:t.node_id})}l(y,"surfaceBootFailure");async function
|
|
7
|
+
If the work still needs doing, re-spawn it.`}l(w,"bootFailureBody");async function y(t,e){await m(t.node_id,w(t,e),{from:t.node_id})}l(y,"surfaceBootFailure");async function D(t){const e=E(t.node_id),r=e===null?"":`
|
|
8
8
|
|
|
9
9
|
Provider rotation observed ${e.consecutivePasses} consecutive route-queue passes with no HTTP response (tried ${e.routes.join(", ")}). Check network and provider transport before reviving.`,i=`\u26A0 Crash loop \u2014 \`${t.name}\` (${t.kind}) kept dying without settling a turn.
|
|
10
10
|
|
|
11
11
|
Its session started successfully, but six consecutive relaunches made no progress, so the daemon stopped retrying.`+r+`
|
|
12
12
|
|
|
13
|
-
Fix the crash cause, then revive the node if the work still needs doing.`;await m(t.node_id,i,{from:t.node_id})}l(
|
|
13
|
+
Fix the crash cause, then revive the node if the work still needs doing.`;await m(t.node_id,i,{from:t.node_id})}l(D,"surfaceCrashLoop");async function B(t,e){const r=e instanceof Error?e.message:String(e),i=`\u26A0 Recovery failed \u2014 \`${t.name}\` (${t.kind}) could not be relaunched.
|
|
14
14
|
|
|
15
15
|
The daemon refused this recovery before starting a broker: ${r}
|
|
16
16
|
|
|
17
|
-
The node is now dead. Fix the recorded launch configuration, then revive it if the work still needs doing.`;await m(t.node_id,i,{from:t.node_id})}l(
|
|
17
|
+
The node is now dead. Fix the recorded launch configuration, then revive it if the work still needs doing.`;await m(t.node_id,i,{from:t.node_id})}l(B,"surfaceRecoveryFailure");function L(t){return t?.cycle_pending!==!0}l(L,"retryResumeMode");function W(t,e,r=!0){return t===null||t.status==="done"||t.status==="canceled"||t.status==="dead"?"forget":t.intent==="refresh"?"respawn-fresh":t.intent==="idle-release"?"dormant":t.lifecycle==="resident"&&!e&&!r&&t.pi_session_id!=null?"release-idle":t.pi_session_id!=null?L(t)?"respawn-resume":"respawn-cycle":e||t.fork_from!=null?"respawn-fresh":"boot-failure"}l(W,"classifyDeadNode");const q=3e4;class ne{static{l(this,"DaemonFleet")}#a;#o;#i;#l;#e=new Map;#r=new Set;#s=new Set;#t=new Map;#c=Number.NEGATIVE_INFINITY;constructor(e){this.#a=e.epoch,this.#o=e.enqueue,this.#i=e.now??Date.now,this.#l=e.probeOnline??(()=>M())}epoch(){return this.#a}register(e,r){if(this.#e.has(e))throw new Error(`fleet: ${e} already has a live broker entry \u2014 refusing a second launch (programming error)`);if(r.pid===null)throw new Error(`fleet: refusing to register ${e} with no pid`);this.#r.delete(e),this.#t.delete(e),this.#e.set(e,{pid:r.pid,handle:r})}has(e){return this.#e.has(e)}isClaimed(e){return this.#e.has(e)||this.#r.has(e)}get(e){return this.#e.get(e)}size(){return this.#e.size}occupancy(){return this.#e.size+this.#r.size}reserveSlot(e){if(this.#r.has(e)||this.#e.has(e))return!0;const{automaticReviveCap:r}=O();if(this.occupancy()<r)return this.#r.add(e),!0;const i=this.#i();return i-this.#c>=q&&(this.#c=i,c({level:"warn",event:"broker.capacity.revive_deferred",fields:{live_count:this.occupancy(),hard_cap:r}})),!1}releaseReservation(e){this.#r.delete(e)}entries(){return this.#e.entries()}interruptForProfilePause(e,r=this.#e.get(e)?.pid){if(r!==void 0){this.#s.add(e);try{process.kill(r,"SIGTERM")}catch{}}}hasProfilePauseInterruption(e){return this.#s.has(e)}forget(e){this.#e.delete(e),this.#r.delete(e),this.#t.delete(e)}onChildExit(e,r,i){i&&k(i),this.#e.delete(e),this.#o(()=>{const s=p(e),n=s?.launched_at==null?Number.NaN:Date.parse(s.launched_at),a=Number.isFinite(n)?Math.max(0,this.#i()-n):null,d=s?.respawn_failures??0;s?.status==="done"||s?.status==="canceled"||s?.status==="dead"?this.#t.delete(e):this.#t.set(e,r),this.#u(e,r,a,d)})}deliverExit(e,r){this.onChildExit(e,r)}async applyDeadRowPolicy(e){const r=this.#t.get(e);try{await this.#f(e,r)}finally{this.#t.get(e)===r&&this.#t.delete(e)}}async terminalizeIfStillNonTerminal(e,r,i,s,n){const a=p(e);return a===null||a.status==="done"||a.status==="canceled"||a.status==="dead"?!1:(await this.#n(e,a,{event:r,reason:s,detail:n,wake:`Child crashed \u2014 ${v(a)} (${e}) could not be relaunched and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,surface:l(()=>B(a,i),"surface")}),!0)}dispose(){}#u(e,r,i,s){c({level:"info",event:"broker.exit.observed",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},code:r.code,signal:r.signal,uptime_ms:i,consecutive_failures:s}})}async#f(e,r){return this.#h(e,r)}async#h(e,r){const i=p(e);if(i!==null&&$(i.profile_id))return h(e),"forget";if(this.#s.delete(e))return h(e),"forget";if(z(e))return"dormant";const s=P(e)?.interrupted===!0,n=W(i,s,N(e));switch(n){case"forget":h(e);break;case"dormant":h(e);break;case"release-idle":h(e),_(e,"release"),c({level:"info",event:"broker.recovery.released",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e}}});break;case"boot-failure":await this.#n(e,i,{event:"broker.boot.failed",reason:"boot_failed",detail:{schema:"crtr.node-outcome-detail/v1",message:w(i,r)},wake:`Child crashed \u2014 ${v(i)} (${e}) exited before its session ever came up and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,surface:l(()=>y(i,r),"surface")});break;case"respawn-fresh":case"respawn-cycle":case"respawn-resume":await this.#d(e,i,n,s);break}return n}async#d(e,r,i,s){const n=g(e);if(n===null)return;const a=n.respawn_failures??0;if(!await this.#l()){x(e,a,this.#i()),c({level:"info",event:"broker.respawn.offline_deferred",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},action:i,retry_in_ms:C,consecutive_failures:a}});return}const d=n.respawn_not_before==null,f=d?F(n,this.#i()):{failures:a,notBefore:n.respawn_not_before,exhausted:a>=R};if(f.exhausted){const u=`Child crashed \u2014 ${v(r)} (${e}) kept dying without settling a turn (${f.failures} consecutive launches) and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`;await this.#n(e,r,{event:"broker.respawn.exhausted",reason:"crash_looped",detail:{schema:"crtr.node-outcome-detail/v1",message:u,respawn_failures:f.failures},wake:u,...r.pi_session_id!=null?{surface:l(()=>D(r),"surface")}:{}});return}if(d&&f.notBefore!==null){c({level:"info",event:"broker.respawn.deferred",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},action:i,backoff_ms:S(f.failures),consecutive_failures:f.failures}});return}c({level:"info",event:"broker.respawn.started",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},action:i,consecutive_failures:f.failures}});try{await A(e,{capacity:"freeze",resume:i==="respawn-resume",wakeReason:i==="respawn-resume"&&s?"runtime-restart-abort":void 0,recovery:!0})}catch(u){c({level:"error",event:"broker.respawn.failed",...o(e)?{node_id:e}:{},error:u,fields:{...o(e)?{}:{affected_node_id:e},action:i}}),await this.terminalizeIfStillNonTerminal(e,"broker.respawn.refused",u,"launch_failed",{schema:"crtr.node-outcome-detail/v1",message:u instanceof Error?u.message:String(u)})}}async#n(e,r,i){c({level:"error",event:i.event,...o(e)?{node_id:e}:{fields:{affected_node_id:e}}}),_(e,"crash",{reason:i.reason,outcome:{detail:i.detail}});try{await(i.surface??(()=>y(r)))()}catch(s){c({level:"error",event:"broker.boot_failure_surface.failed",...o(e)?{node_id:e}:{fields:{affected_node_id:e}},error:s})}T(e,"notice.crash",i.wake,{reason:"child-crashed",child:e})}}export{ne as DaemonFleet,W as classifyDeadNode,L as retryResumeMode,y as surfaceBootFailure};
|
|
@@ -9,9 +9,19 @@ export interface BashDeadlineContext {
|
|
|
9
9
|
* alive. This lane is the enforcer: it survives a broker restart and fires while
|
|
10
10
|
* the node is idle, so a runaway command cannot outlive its window just because
|
|
11
11
|
* the agent moved on. A deliberately backgrounded job carries no deadline and is
|
|
12
|
-
* never
|
|
12
|
+
* never canceled here. It also publishes every backgrounded job's exit, and adopts
|
|
13
|
+
* a job the broker backgrounded while exiting (SIGTERM/SIGHUP), which could not
|
|
14
|
+
* record its own job object. */
|
|
13
15
|
export declare class BashDeadlineReconciler {
|
|
14
16
|
private lastScanAt;
|
|
17
|
+
/** An exit written before this daemon started is history, not a job to adopt. */
|
|
18
|
+
private readonly startedAt;
|
|
15
19
|
run(now: number, ctx: BashDeadlineContext): Promise<void>;
|
|
20
|
+
/** A running job whose supervisor wrote job.exit has exited: `finishJob` publishes `exited`
|
|
21
|
+
* once (the row leaves `running`). A job being stopped (job.stop) is ended by its killer. */
|
|
22
|
+
private publishExits;
|
|
23
|
+
/** Give every backgrounded job dir (job.bg) that has no job object one; the next tick's
|
|
24
|
+
* `publishExits` then ends it like any other job. */
|
|
25
|
+
private adoptUnrecorded;
|
|
16
26
|
private cancel;
|
|
17
27
|
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
var p=Object.defineProperty;var
|
|
1
|
+
var p=Object.defineProperty;var f=(l,e)=>p(l,"name",{value:e,configurable:!0});import{existsSync as s,readFileSync as m,readdirSync as u,statSync as j}from"node:fs";import{join as b}from"node:path";import{bashJobPaths as _,bashJobsDir as S,expiredAutoBackgroundBashJobs as x,stopBackgroundBashJob as y}from"../../core/bash-jobs.js";import{killBashJobObject as N,recordBashJobObject as E}from"../../core/spaces/stop.js";import{withCanvasWrite as h}from"../../core/canvas/db.js";import{finishJob as v}from"../../core/graph/jobs.js";import{getById as g,getByRowid as A}from"../../core/graph/objects.js";import{isSafeNodeId as c}from"../../core/canvas/paths.js";import{contextDir as B}from"../../core/canvas/node-agent-paths.js";import{emitEvent as a}from"../../core/events/emit.js";import{operationIdContext as d}from"../../core/events/operation-id.js";import{isProfilePaused as J}from"../../core/profiles/manifest.js";const w=5*1e3;class W{static{f(this,"BashDeadlineReconciler")}lastScanAt=Number.NEGATIVE_INFINITY;startedAt=Date.now();async run(e,n){if(this.publishExits(),!(e-this.lastScanAt<w)){this.lastScanAt=e;for(const t of n.rows){if(t.status==="dead"||J(t.profile_id))continue;const i=B(t.node_id);let r;try{this.adoptUnrecorded(t.node_id,i),r=x(i,e)}catch(o){d.fresh(()=>{a({level:"error",event:"bash_deadline.scan_failed",...c(t.node_id)?{node_id:t.node_id}:{},error:o})});continue}for(const o of r)await this.cancel(t.node_id,i,o.jobId)}}}publishExits(){try{h(e=>{const n=e.prepare(`SELECT j.object, j.job_dir FROM jobs j JOIN objects o ON o.rowid = j.object
|
|
2
|
+
WHERE j.status = 'running' AND o.deleted_at IS NULL`).all();for(const{object:t,job_dir:i}of n){const r=b(i,"job.exit");if(!s(r)||s(b(i,"job.stop")))continue;const o=Number(m(r,"utf8").trim());Number.isSafeInteger(o)&&v(e,A(e,t),{exitCode:o})}})}catch(e){d.fresh(()=>a({level:"error",event:"bash_completion.delivery_failed",error:e}))}}adoptUnrecorded(e,n){let t;try{t=u(S(n))}catch{return}const i=h(r=>t.filter(o=>g(r,o)===null));for(const r of i){const o=_(n,r);!s(o.jobBg)||!s(o.cmdSh)||s(o.jobExit)&&j(o.jobExit).mtimeMs<this.startedAt||E(e,r,{command:m(o.cmdSh,"utf8"),jobDir:o.dir,logPath:o.jobLog})}}async cancel(e,n,t){(await y(n,t,!1,e)).kind==="stopped"&&d.fresh(()=>{try{a({level:"info",event:"bash_deadline.canceled",...c(e)?{node_id:e}:{},fields:{job_id:t}}),N(t,()=>null,"deadline")}catch(r){a({level:"error",event:"bash_deadline.notice_failed",...c(e)?{node_id:e}:{},error:r,fields:{job_id:t}})}})}}export{W as BashDeadlineReconciler};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)){const a=i.trim();if(a==="")continue;const n=a.split(/\s+/);if(n.length<3)continue;const s=Number(n[0]),r=Number(n[1]),d=Number(n[2]);if(!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(d))continue;e.set(s,d);const c=t.get(r);c===void 0?t.set(r,[s]):c.push(s)}return{byPid:e,childrenOf:t}}m(
|
|
3
|
-
`).map(async p=>{if(p!=="")try{await N("tmux",["display-message","-C","-d","10000","-c",p,c],{encoding:"utf8",timeout:2e3})}catch{try{await N("tmux",["display-message","-c",p,c],{encoding:"utf8",timeout:2e3})}catch(h){f({level:"error",event:"broker.capacity.tmux_display_failed",error:h,fields:{client:p}})}}}))}catch(l){f({level:"error",event:"broker.capacity.tmux_list_clients_failed",error:l})}}async handleYieldStall(e,t,i,a){const n=e.node_id,s=
|
|
4
|
-
`)[0]??"").slice(0,200),r=t.providerError,d=r===void 0?"":` Provider: ${r.provider}/${r.model}.`+(r.status===void 0?"":` HTTP status: ${r.status}.`)+(r.errno===void 0?"":` Errno: ${r.errno}.`)+(r.code===void 0?"":` Code: ${r.code}.`)+(r.body===void 0?"":` Body: ${r.body.slice(0,200)}.`),c=t.kind==="context-overflow",l=i?.parent==null&&i?.lifecycle==="terminal",p=c||l,h=c?`Child failed \u2014 ${a} (${e}) exceeded its model context window and is now dead. Shrink the task or loaded context, or choose a larger-context model before spawning it again. Error: ${s}`:`Child hit a fatal provider fault \u2014 ${a} (${e}) got a non-retryable ${t.kind} error and will NOT recover on its own; `+(l?"its terminal run has failed. ":"it stays alive, and waking it clears the fault as soon as one turn completes \u2014 a wake that hits the same cause fails again. "+(n?"Its provider credential is dead \u2014 re-authenticate (`/login`, or re-auth crtr); the child recovers on its next wake once the auth reloads. ":""))+`Error: ${s}.${d}`;p&&(
|
|
1
|
+
var Y=Object.defineProperty;var m=(o,e)=>Y(o,"name",{value:e,configurable:!0});import{existsSync as H,statSync as j}from"node:fs";import{join as $}from"node:path";import{LAUNCHER_SOCKET as K}from"../../launcher/spec.js";import{launcherRequest as V}from"../../launcher/client.js";import{secretsDir as z}from"../../core/layout.js";import{execFile as J}from"node:child_process";import{promisify as Q}from"node:util";import{getNode as A,isWarmSpare as X}from"../../core/canvas/index.js";import{isSafeNodeId as u}from"../../core/canvas/paths.js";import{contextDir as Z}from"../../core/canvas/node-agent-paths.js";import{fullName as I}from"../../core/canvas/labels.js";import{recordedPidLiveness as D}from"../../core/canvas/pid.js";import{transition as ee}from"../../core/runtime/lifecycle.js";import{readFault as O,readLiveTurn as C,recordFault as te}from"../../core/canvas/recovery.js";import{errorClassFromFault as ne}from"../../core/fault-classifier.js";import{nextFaultRetry as re}from"../../core/runtime/fault-recovery.js";import{publishNotice as L}from"../../core/runtime/close.js";import{headlessBrokerHost as v}from"../../core/runtime/host.js";import{reloadAuthLive as ie}from"../../core/runtime/auth-reload.js";import{emitEvent as f}from"../../core/events/emit.js";import{operationIdContext as R}from"../../core/events/operation-id.js";import{hasUnseenWakeMail as ae,resetStaleExecutionMail as se}from"../../core/canvas/deliveries.js";import{activeBackgroundBashJobs as oe}from"../../core/bash-jobs.js";import{focusOf as le}from"../../core/runtime/placement.js";import{hasAttachedBrokerViewers as de}from"../api/viewer-presence.js";import{deliverLive as ce}from"../../core/runtime/interactive-deliver.js";import{BrokerUnreachableError as ue}from"../../core/runtime/broker-request.js";import{formatCard as fe,PARK_SUMMARY_PROMPT as pe}from"../../shared/generated-context.js";import{brokerThresholdsForDaemon as me}from"../../core/runtime/fleet.js";import{readConfig as he}from"../../core/config.js";import{scopedStoreExists as _e}from"../../core/scoped-state/db.js";import{providerStore as ge}from"../../core/scoped-state/paths.js";import{providerRevision as ve}from"../../core/scoped-state/providers.js";import{beginPendingPark as ke,consumePendingPark as y,pendingParkIds as ye,pendingParkStartedAt as we}from"../park-pending.js";import{shouldParkAfterSummary as be}from"../park-activity.js";import{applyParkEvent as w,parkEvent as Se}from"./live-obligation.js";import{envNoDaemonAutostart as Ae,envTestUnattendedParkMs as Ne,parkSummaryGraceMs as Pe,envUnattendedParkMs as Me}from"../../shared/env.js";const N=Q(J);function Te(o){return C(o)?.busy===!0}m(Te,"liveBusy");function wt(o){const e=C(o)?.progressAt;if(e==null)return null;const t=Date.parse(e);return Number.isNaN(t)?null:t}m(wt,"liveTurnProgressMs");function G(o,e){return e===null?null:`${o}:${e}`}m(G,"incarnationOf");function F(o){const e=C(o.node_id),t=e?.busy===!0&&e.progressAt!==null?Date.parse(e.progressAt):Number.NaN,i=o.launched_at===null||o.launched_at===void 0?Number.NaN:Date.parse(o.launched_at);return!Number.isFinite(t)||!Number.isFinite(i)||t<i?null:t}m(F,"busySinceForIncarnation");const W=3*6e4,U=2e4,x=20*6e4,Ee=2,$e=5*6e4;function Ce(){const o=Me();if(o!==void 0)return o;const e=he("user").lifecycle.unattendedParkMs;return Ae()?Ne()??e:e}m(Ce,"unattendedParkMsForDaemon");function B(){return Pe()}m(B,"parkSummaryGraceMsForDaemon");function Re(o,e,t,i){return o!==!0||e!=="refresh"||t?"leave":i===null||i<W?"pending":"kill"}m(Re,"yieldStallVerdict");function Fe(o){return!o.busy||o.quietForMs===null||o.quietForMs<x?"leave":o.cpuPercent===null||o.hasDescendants!==!1&&o.cpuPercent>Ee?"pending":"wedged"}m(Fe,"wedgeVerdict");function q(o){const e=new Map,t=new Map;for(const i of o.split(`
|
|
2
|
+
`)){const a=i.trim();if(a==="")continue;const n=a.split(/\s+/);if(n.length<3)continue;const s=Number(n[0]),r=Number(n[1]),d=Number(n[2]);if(!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(d))continue;e.set(s,d);const c=t.get(r);c===void 0?t.set(r,[s]):c.push(s)}return{byPid:e,childrenOf:t}}m(q,"parsePsTree");function xe(o,e){const{byPid:t,childrenOf:i}=q(o);if(!t.has(e))return null;let a=0;const n=[e],s=new Set;for(;n.length>0;){const r=n.pop();if(s.has(r))continue;s.add(r),a+=t.get(r)??0;const d=i.get(r);d!==void 0&&n.push(...d)}return a}m(xe,"sumTreeCpu");function Ie(o,e){const{byPid:t,childrenOf:i}=q(o);return t.has(e)?(i.get(e)??[]).length>0:null}m(Ie,"treeHasDescendants");function De(o){return[$(o,"auth.json"),$(o,"anthropic-credentials.json"),$(o,"openai-codex-credentials.json")]}m(De,"piCredentialPaths");class bt{static{m(this,"BrokerSupervisionReconciler")}yieldStalls=new Map;wedgeNotifiedAt=new Map;fatalFaultNotifiedAt=new Map;unattendedSince=new Map;sampleTree;signal;knownCredentialRevision=null;lastOverCapWarnAt=Number.NEGATIVE_INFINITY;constructor(e={}){this.sampleTree=e.readTreeSample??(t=>this.readTreeSample(t)),this.signal=e.signal??((t,i)=>{if(process.platform==="linux"&&H(K)){if(i!=="SIGTERM"&&i!=="SIGKILL")throw new Error(`unsupported launcher signal ${i}`);return V({operation:"stop",pid:t,signal:i}).then(()=>{})}process.kill(t,i)})}async runFleetPreamble(e){return await this.handleAuthReload(e),me()}warnIfSaturated(e){if(e.fleet.size()<e.thresholds.warning||!e.lifecycle.acceptsDetachedWork())return;const t=R.fresh(()=>this.warnOverCapInTmux(e.fleet.size(),e.thresholds,e.frozen));e.lifecycle.registerDetached(t)}async run(e,t){const i=Ce();for(const a of t.rows){const n=a.node_id,s=t.fleet.get(n);if(s===void 0||a.status!=="active"&&a.status!=="idle"){this.unattendedSince.delete(n);continue}await R.fresh(async()=>{try{await this.handleYieldStall(a,s,t.fleet,e),await this.handleWedgeDetection(a,s,t.fleet,e),this.handleFatalFault(n),this.handleUnattendedParking(n,A(n),s.pid,e,t,i)}catch(r){this.unattendedSince.delete(n),f({level:"error",event:"broker.supervision.failed",...u(n)?{node_id:n}:{fields:{affected_node_id:n}},error:r})}})}for(const a of this.unattendedSince.keys())t.fleet.has(a)||this.unattendedSince.delete(a);for(const a of ye())t.fleet.has(a)||y(a);se(e)}parkResetCondition(e,t,i,a){if(t.pi_session_id==null||t.pi_pid!==i||t.status==="done"||t.status==="canceled"||t.status==="dead"||t.intent!==null||oe(Z(e)).length>0||le(e)!==null||de(e))return!0;const n=O(e);return n!==null&&n.retry.disposition==="auto"&&n.retry.by==="daemon"&&(n.kind==="connection"||n.kind==="rate-limit"||n.kind==="overloaded")&&(n.retry.nextAt!==void 0||re(n,a)!==null)?!0:ae(e)}handleUnattendedParking(e,t,i,a,n,s){if(X(e)){this.unattendedSince.delete(e),y(e);return}if(t===null){this.unattendedSince.delete(e),y(e);return}const r=this.parkResetCondition(e,t,i,a),d=we(e);if(d!==void 0){if(a-d<B())return;const p=y(e);if(p===void 0||(this.unattendedSince.delete(e),!be(e,t,p)))return;f({level:"warn",event:"broker.park.summary_expired",...u(e)?{node_id:e}:{},fields:{...u(e)?{}:{affected_node_id:e},grace_ms:B()}}),w(e,"park"),v.teardown(e);return}if(r||Te(e)){this.unattendedSince.delete(e);return}const c=this.unattendedSince.get(e);if(c===void 0){this.unattendedSince.set(e,a);return}if(a-c<s)return;this.unattendedSince.delete(e);const l=Se(e,t.lifecycle);if(l==="release"){w(e,l),v.teardown(e);return}if(l==="cancel"){w(e,l),v.teardown(e);return}if(t.grantee!==void 0&&t.grantee!=="app:terminal"){w(e,"park"),v.teardown(e);return}n.lifecycle.acceptsDetachedWork()&&(ke(e,a),n.lifecycle.registerDetached(this.requestParkSummary(e)))}async requestParkSummary(e){try{const t=await ce(e,fe("park",{},pe),{origin:{type:"runtime",kind:"park"}});f({level:"info",event:"broker.park.summary_requested",...u(e)?{node_id:e}:{},fields:{...u(e)?{}:{affected_node_id:e},route:t}})}catch(t){if(y(e)===void 0)return;if(t instanceof ue){w(e,"park"),v.teardown(e);return}f({level:"error",event:"broker.park.summary_failed",...u(e)?{node_id:e}:{fields:{affected_node_id:e}},error:t})}}async warnOverCapInTmux(e,t,i){const a=Date.now();if(a-this.lastOverCapWarnAt<$e)return;this.lastOverCapWarnAt=a;const{warning:n,automaticReviveCap:s}=t,r=i.stalled+i.waitingOnMail;f({level:"warn",event:"broker.capacity.warning",fields:{live_count:e,warning_threshold:n,hard_cap:s,frozen_stalled:i.stalled,frozen_waiting_on_mail:i.waitingOnMail}});const d=r===0?"":` \u2014 ${r} frozen (${i.stalled} stalled, ${i.waitingOnMail} waiting on mail)`,c=`\u26A0 crtrd: ${e} live brokers (warning ${n}; hard cap ${s})${d} \u2014 possible broker leak. ps -ax | grep broker-cli.js`;try{const l=await N("tmux",["list-clients","-F","#{client_name}"],{encoding:"utf8",timeout:2e3});if(typeof l.stdout!="string")return;await Promise.allSettled(l.stdout.split(`
|
|
3
|
+
`).map(async p=>{if(p!=="")try{await N("tmux",["display-message","-C","-d","10000","-c",p,c],{encoding:"utf8",timeout:2e3})}catch{try{await N("tmux",["display-message","-c",p,c],{encoding:"utf8",timeout:2e3})}catch(h){f({level:"error",event:"broker.capacity.tmux_display_failed",error:h,fields:{client:p}})}}}))}catch(l){f({level:"error",event:"broker.capacity.tmux_list_clients_failed",error:l})}}async handleYieldStall(e,t,i,a){const n=e.node_id,s=G(t.pid,e.pi_pid_identity);if(e.intent!=="refresh"||F(e)!==null||s===null){s!==null&&this.yieldStalls.delete(s);return}let r=this.yieldStalls.get(s);if(r===void 0){r={since:a},this.yieldStalls.set(s,r);return}if(Re(!0,e.intent,!1,a-r.since)!=="kill")return;const d=A(n);if(!(i.get(n)!==t||d?.pi_pid!==t.pid||d.pi_pid_identity!==e.pi_pid_identity||D(t.pid,e.pi_pid_identity)!=="alive"))if(r.termedAt===void 0){if(!await this.signalYieldStall(n,t.pid,"SIGTERM"))return;r.termedAt=a,f({level:"warn",event:"broker.yield_stall.sigterm",...u(n)?{node_id:n}:{},fields:{...u(n)?{}:{affected_node_id:n},pid:t.pid,elapsed_ms:a-r.since,grace_ms:W}})}else a-r.termedAt>=U&&await this.signalYieldStall(n,t.pid,"SIGKILL")&&f({level:"warn",event:"broker.yield_stall.sigkill",...u(n)?{node_id:n}:{},fields:{...u(n)?{}:{affected_node_id:n},pid:t.pid,elapsed_ms:a-r.termedAt,grace_ms:U,stall_elapsed_ms:a-r.since}})}async signalYieldStall(e,t,i){try{return await this.signal(t,i),!0}catch(a){return f({level:"error",event:"broker.yield_stall.signal_failed",...u(e)?{node_id:e}:{},error:a,fields:{...u(e)?{}:{affected_node_id:e},pid:t,signal:i}}),!1}}async readTreeSample(e){try{const{stdout:t}=await N("ps",["-ax","-o","pid=,ppid=,pcpu="],{encoding:"utf8",timeout:2e3});if(typeof t!="string")return null;const i=xe(t,e),a=Ie(t,e);return i===null||a===null?null:{cpuPercent:i,hasDescendants:a}}catch{return null}}async handleWedgeDetection(e,t,i,a){const n=e.node_id,s=G(t.pid,e.pi_pid_identity),r=F(e);if(r===null||s===null){s!==null&&this.wedgeNotifiedAt.delete(s);return}const d=a-r,c=d>=x?await this.sampleTree(t.pid):null,l=A(n),p=l===null?null:F(l);if(i.get(n)!==t||l===null||l.pi_pid!==t.pid||l.pi_pid_identity!==e.pi_pid_identity||p!==r)return;const h=c?.cpuPercent??null,_=c?.hasDescendants??null;if(Fe({busy:!0,quietForMs:d,cpuPercent:h,hasDescendants:_})!=="wedged"||this.wedgeNotifiedAt.get(s)===r)return;this.wedgeNotifiedAt.set(s,r);const b=I(l),S=Math.round((d??x)/6e4),P=_??!0,k=!P&&D(t.pid,e.pi_pid_identity)!=="alive"?"pid_identity_unproven":null;let M=!1,T=!1,g;if(P)g=`Child wedged \u2014 ${b} (${n}) is alive and mid-turn but has shown NO engine progress for ${S}+ minutes and its process is near-idle. It will NOT recover on its own \u2014 read \`crtr canvas read wedged-child-on-runaway-bash\` and kill the runaway SUBPROCESS (not this node) so its turn can resume with no lost context.`;else if(k!==null)g=`Child wedged \u2014 ${b} (${n}) is alive and mid-turn but has shown NO engine progress for ${S}+ minutes and it has no subprocess to kill (the engine itself stalled). The daemon did not SIGTERM the broker because its PID identity cannot be confirmed alive.`;else{M=!0;try{await this.signal(t.pid,"SIGTERM"),T=!0,g=`Child wedged \u2014 ${b} (${n}) is alive and mid-turn but has shown NO engine progress for ${S}+ minutes and it has no subprocess to kill (the engine itself stalled). The daemon sent SIGTERM to the broker and will resume a cleanly aborted session with a continuation, or start a recovery cycle if the abort cannot settle.`}catch(E){f({level:"error",event:"broker.wedge.signal_failed",...u(n)?{node_id:n}:{},error:E,fields:{...u(n)?{}:{affected_node_id:n},pid:t.pid,signal:"SIGTERM"}}),g=`Child wedged \u2014 ${b} (${n}) is alive and mid-turn but has shown NO engine progress for ${S}+ minutes and it has no subprocess to kill (the engine itself stalled). The daemon attempted SIGTERM to the broker, but the signal call failed.`}}f({level:"error",event:"broker.wedge.detected",...u(n)?{node_id:n}:{},fields:{...u(n)?{}:{affected_node_id:n},pid:t.pid,quiet_ms:d,cpu_percent:h,has_descendants:P,kick_attempted:M,kicked:T,...k===null?{}:{kick_suppression_reason:k}}});try{te(n,{link:"daemon\u2192node",op:"engine wedge",kind:"wedged",retry:{disposition:"manual"},message:g})}catch(E){f({level:"error",event:"broker.wedge.fault_record_failed",...u(n)?{node_id:n}:{fields:{affected_node_id:n}},error:E})}L(n,"notice.crash",g,{reason:"child-wedged",child:n,quiet_ms:d,cpu_percent:h,kick_attempted:M,kicked:T,...k===null?{}:{kick_suppression_reason:k}})}handleFatalFault(e){const t=O(e);if(t===null){this.fatalFaultNotifiedAt.delete(e);return}if(t.retry.disposition!=="fatal"||t.link!=="pi\u2192provider"||this.fatalFaultNotifiedAt.get(e)===t.since)return;const i=A(e),a=i!==null?I(i):e,n=t.kind==="auth",s=(t.message.split(`
|
|
4
|
+
`)[0]??"").slice(0,200),r=t.providerError,d=r===void 0?"":` Provider: ${r.provider}/${r.model}.`+(r.status===void 0?"":` HTTP status: ${r.status}.`)+(r.errno===void 0?"":` Errno: ${r.errno}.`)+(r.code===void 0?"":` Code: ${r.code}.`)+(r.body===void 0?"":` Body: ${r.body.slice(0,200)}.`),c=t.kind==="context-overflow",l=i?.parent==null&&i?.lifecycle==="terminal",p=c||l,h=c?`Child failed \u2014 ${a} (${e}) exceeded its model context window and is now dead. Shrink the task or loaded context, or choose a larger-context model before spawning it again. Error: ${s}`:`Child hit a fatal provider fault \u2014 ${a} (${e}) got a non-retryable ${t.kind} error and will NOT recover on its own; `+(l?"its terminal run has failed. ":"it stays alive, and waking it clears the fault as soon as one turn completes \u2014 a wake that hits the same cause fails again. "+(n?"Its provider credential is dead \u2014 re-authenticate (`/login`, or re-auth crtr); the child recovers on its next wake once the auth reloads. ":""))+`Error: ${s}.${d}`;p&&(ee(e,"crash",{reason:c?"context_overflow":"provider_fatal",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:t.message,fault_kind:t.kind,error_class:ne(t).class}}}),v.teardown(e).then(_=>{_.confirmed||f({level:"error",event:"fault.fatal.teardown_failed",node_id:e,error:_.error??new Error("Broker teardown not confirmed")})},_=>f({level:"error",event:"fault.fatal.teardown_failed",node_id:e,error:_}))),this.fatalFaultNotifiedAt.set(e,t.since),f({level:"error",event:"fault.fatal.fanout",...u(e)?{node_id:e}:{},fields:{...u(e)?{}:{affected_node_id:e},kind:t.kind,link:t.link,terminal_overflow:c,terminal_provider_fault:l}}),L(e,"notice.crash",h,{reason:c?"child-context-overflow":"child-fault-fatal",child:e,kind:t.kind,message:s,...r===void 0?{}:{provider_error:r}})}async handleAuthReload(e){const t=z();let i=0;for(const r of De(t))try{i=Math.max(i,j(r).mtimeMs)}catch{}let a=0;const n=ge(t);_e(n)&&(a=ve(t));const s=`${i}:${a}`;if(this.knownCredentialRevision===null){this.knownCredentialRevision=s;return}s!==this.knownCredentialRevision&&(this.knownCredentialRevision=s,await R.fresh(async()=>{try{const r=Array.from(e.entries(),([l])=>l);if(r.length===0)return;const c=(await Promise.allSettled(r.map(async l=>{try{await ie(l)}catch(p){throw f({level:"error",event:"auth.reload.broker_failed",...u(l)?{node_id:l}:{fields:{broker_id:l}},error:p}),p}}))).filter(l=>l.status==="fulfilled").length;f({level:"info",event:"auth.reload.completed",outcome:c===r.length?"succeeded":"failed",fields:{broker_count:r.length,succeeded_count:c,failed_count:r.length-c}})}catch(r){f({level:"error",event:"auth.reload.failed",error:r})}}))}}export{bt as BrokerSupervisionReconciler,Ee as WEDGE_CPU_MAX_PERCENT,x as WEDGE_QUIET_MS,W as YIELD_STALL_GRACE_MS,B as parkSummaryGraceMsForDaemon,xe as sumTreeCpu,Ie as treeHasDescendants,Ce as unattendedParkMsForDaemon,Fe as wedgeVerdict,Re as yieldStallVerdict};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var f=Object.defineProperty;var e=(r,t)=>f(r,"name",{value:t,configurable:!0});import{hasActiveLiveSubscription as l,hasLiveMessageWait as p,hasLiveSubscriber as m,hasPendingCronWake as h}from"../../core/canvas/index.js";import{fullName as k}from"../../core/canvas/labels.js";import{newestReportName as g}from"../../core/feed/reports.js";import{countTickets as w}from"../../core/canvas/attention.js";import{hasUnseenWakeMail as s}from"../../core/canvas/deliveries.js";import{readOutputRequest as b}from"../../core/runtime/structured-output.js";import{focusOf as v}from"../../core/runtime/placement.js";import{hasAttachedBrokerViewers as x}from"../api/viewer-presence.js";import{publishNotice as $}from"../../core/runtime/close.js";import{readFault as L}from"../../core/canvas/recovery.js";import{transition as u}from"../../core/runtime/lifecycle.js";function a(r){return l(r)||p(r)||h(r)||w(r)>0||b(r).state!=="absent"}e(a,"hasLiveObligation");function V(r){return a(r)||s(r)?!0:n(r)}e(V,"hasPendingWake");function q(r){return t=>r.isClaimed(t)||a(t)||n(t)}e(q,"retentionHold");function n(r){return v(r)!==null||x(r)}e(n,"hasHumanViewer");function B(r,t){if(n(r)||a(r))return"release";const i=L(r);return i?.link==="pi\u2192provider"&&i.retry.disposition==="fatal"?"release":t==="resident"?s(r)?"release":"park":s(r)||m(r)?"release":"cancel"}e(B,"parkEvent");function F(r,t){const i=t==="cancel"?u(r,t,{reason:"stranded"}):u(r,t);if(t!=="park")return;const o=g(r),c=o===null?`It left no report behind; \`crtr node inspect show ${r}\` shows where it stands.`:`Its latest report is where it left things: \`crtr canvas read ${o}\`.`;$(r,"notice.close",`Resident concluded \u2014 ${k(i)} (${r}) had nothing left to wake it through its unattended grace, so its conversation was concluded. It submitted no final report. ${c} A message to it reopens it on a fresh cycle.`,{reason:"child-auto-done",child:r},"deferred")}e(F,"applyParkEvent");export{F as applyParkEvent,n as hasHumanViewer,a as hasLiveObligation,V as hasPendingWake,B as parkEvent,q as retentionHold};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var s=(o,e)=>c(o,"name",{value:e,configurable:!0});import{dueNodeDeadlines as _
|
|
1
|
+
var c=Object.defineProperty;var s=(o,e)=>c(o,"name",{value:e,configurable:!0});import{dueNodeDeadlines as _}from"../../core/canvas/index.js";import{emitEvent as n}from"../../core/events/emit.js";import{isProfilePaused as f}from"../../core/profiles/manifest.js";import{operationIdContext as m}from"../../core/events/operation-id.js";import{errorClassFromFault as u}from"../../core/fault-classifier.js";import{publishNotice as p}from"../../core/runtime/close.js";import{readFault as h}from"../../core/canvas/recovery.js";import{requestBrokerTeardown as v}from"../../core/runtime/host.js";import{transition as x}from"../../core/runtime/lifecycle.js";class b{static{s(this,"NodeDeadlineReconciler")}run(e){let r;try{r=_(new Date(e).toISOString())}catch(d){n({level:"error",event:"node_deadline.scan_failed",error:d});return}for(const d of r)f(d.profile_id)||m.fresh(()=>this.expire(d,e))}expire(e,r){const d=e.deadline_at;if(d==null)return;const l=h(e.node_id),t=l?.retry.disposition==="fatal"?l:null;let a;try{a=x(e.node_id,"cancel",{reason:"deadline_exceeded",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",deadline:{deadline_at:d,elapsed_ms:r-Date.parse(d)},...t===null?{}:{message:t.message,fault_kind:t.kind,error_class:u(t).class}}}})}catch(i){n({level:"error",event:"node_deadline.terminalize_failed",node_id:e.node_id,error:i,fields:{deadline_at:d}});return}if(!(a.status!=="canceled"||a.outcome_reason!=="deadline_exceeded")){try{v(e.node_id)}catch(i){n({level:"error",event:"node_deadline.teardown_failed",node_id:e.node_id,error:i,fields:{deadline_at:d}})}try{p(e.node_id,"notice.deadline","child-deadline-exceeded",{reason:"child-deadline-exceeded",child:e.node_id})}catch(i){n({level:"error",event:"node_deadline.notify_failed",node_id:e.node_id,error:i,fields:{deadline_at:d}})}try{n({level:"error",event:"node_deadline.expired",node_id:e.node_id,fields:{deadline_at:d,elapsed_ms:r-Date.parse(d)}})}catch{}}}}export{b as NodeDeadlineReconciler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var w=Object.defineProperty;var d=(i,t)=>w(i,"name",{value:t,configurable:!0});import{clearFrozen as v,getNode as E,getRow as y
|
|
1
|
+
var w=Object.defineProperty;var d=(i,t)=>w(i,"name",{value:t,configurable:!0});import{clearFrozen as v,getNode as E,getRow as y}from"../../../core/canvas/index.js";import{fullName as g}from"../../../core/canvas/labels.js";import{isSafeNodeId as s}from"../../../core/canvas/paths.js";import{emitEvent as c}from"../../../core/events/emit.js";import{operationIdContext as A}from"../../../core/events/operation-id.js";import{acknowledgedNodeMailCount as z}from"../../../core/canvas/deliveries.js";import{publishNotice as S}from"../../../core/runtime/close.js";import{transition as p}from"../../../core/runtime/lifecycle.js";import{reviveNode as m}from"../../../core/runtime/revive.js";import{hasPendingWake as _}from"../live-obligation.js";const f=6,k=10*6e4,R=2e4;function L(i,t){if(t)return 2;const r=i.launched_at;if(r==null)return 1;const e=i.last_settled_at;return e==null?2:Date.parse(e)>Date.parse(r)?1:2}d(L,"thawTier");function M(i,t){if(i.tier!==t.tier)return i.tier-t.tier;const r=i.row.frozen_at,e=t.row.frozen_at;return r==null?e==null?0:1:e==null?-1:Date.parse(r)-Date.parse(e)}d(M,"compareThaw");class O{static{d(this,"FreezeLaneReconciler")}relaunchState=new Map;endEpisode(t){this.relaunchState.delete(t)}async run(t,r){const e=r.candidates.map(a=>({...a,tier:L(a.row,_(a.row.node_id))}));e.sort(M);const n={stalled:0,waitingOnMail:0};for(const a of e)await A.fresh(()=>this.enact(t,a,r.fleet))==="frozen"&&(a.tier===1?n.stalled+=1:n.waitingOnMail+=1);return n}async enact(t,r,e){const n=r.row.node_id;try{return r.enact==="thaw"?await this.enactThaw(r.row):r.enact==="idle-release"?await this.enactIdleRelease(t,r.row):(await e.applyDeadRowPolicy(n),e.has(n)?"launched":y(n)?.frozen_at!=null?"frozen":"skipped")}catch(a){return c({level:"error",event:"node.lifecycle.enact_failed",...s(n)?{node_id:n}:{},error:a,fields:{...s(n)?{}:{affected_node_id:n},enact:r.enact}}),"skipped"}}async enactThaw(t){return t.lifecycle==="resident"&&E(t.node_id)?.pi_session_id!=null&&!_(t.node_id)?(p(t.node_id,"release"),v(t.node_id),"skipped"):(await m(t.node_id,{resume:!0,capacity:"freeze",recovery:!0})).outcome==="frozen"?"frozen":"launched"}async enactIdleRelease(t,r){const e=r.node_id,n=z(e),a=this.relaunchState.get(e),l=a===void 0||a.acknowledgedCount!==n,o=l?0:a.attempts;if(o>=f)return this.relaunchState.delete(e),c({level:"warn",event:"broker.idle_release.exhausted",...s(e)?{node_id:e}:{},fields:{...s(e)?{}:{affected_node_id:e},attempts:o,max_attempts:f}}),p(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",respawn_failures:o}}}),S(e,"notice.crash",`Child crashed \u2014 ${g(r)} (${e}) failed to relaunch after ${o} attempts while trying to deliver a pending inbox message (no delivery progress across any attempt), and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e}),"skipped";const u=l?void 0:a?.lastAttempt,h=Math.min(R*2**o,k);return u!==void 0&&t-u<h?"skipped":(await m(e,{resume:!0,capacity:"freeze"})).outcome==="frozen"?"frozen":(this.relaunchState.set(e,{acknowledgedCount:n,attempts:o+1,lastAttempt:t}),c({level:"info",event:"broker.revive.idle_release",...s(e)?{node_id:e}:{},attempt:o+1,fields:{...s(e)?{}:{affected_node_id:e},attempts:o+1,max_attempts:f}}),"launched")}}export{O as FreezeLaneReconciler,M as compareThaw,L as thawTier};
|
|
@@ -16,6 +16,7 @@ export interface StorageMaintenanceContext {
|
|
|
16
16
|
export declare class StorageMaintenanceReconciler {
|
|
17
17
|
private lastSpareSweepAt;
|
|
18
18
|
private lastRunExpiryAt;
|
|
19
|
+
private lastAnalyzeAt;
|
|
19
20
|
private lastRetentionSweepAt;
|
|
20
21
|
private lastContextStripAt;
|
|
21
22
|
private contextStripInFlight;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var S=Object.defineProperty;var c=(f,t)=>S(f,"name",{value:t,configurable:!0});import{rm as A}from"node:fs/promises";import{closeFocusRow as y,getFocusById as N,listFocuses as E,listNodes as h}from"../../core/canvas/index.js";import{getNode as g,lastActivityMs as u,pruneNodes as x}from"../../core/canvas/canvas.js";import{lastContextStripMs as T,stripContextDir as R}from"../../core/canvas/context-strip.js";import{isSafeNodeId as d}from"../../core/canvas/paths.js";import{emitEvent as i}from"../../core/events/emit.js";import{operationIdContext as o}from"../../core/events/operation-id.js";import{listLivePanesAsync as F,tearDownNode as w}from"../../core/runtime/placement.js";import{reapStaleSpares as D}from"../../core/runtime/warm-pool.js";import{ManagedWorktreeSweepReconciler as C}from"./managed-worktree-sweep.js";import{expireRunEvents as G}from"../../core/runs/events.js";import{openDb as b}from"../../core/canvas/db.js";import{retentionHold as m}from"./live-obligation.js";import{pruneMemoryReads as P}from"../../core/canvas/memory-reads.js";const M=10*6e4,V=60*1e3,v=5*6e4,W=14,Y=1440*6e4;class ee{static{c(this,"StorageMaintenanceReconciler")}lastSpareSweepAt=Number.NEGATIVE_INFINITY;lastRunExpiryAt=Number.NEGATIVE_INFINITY;lastAnalyzeAt=Number.NEGATIVE_INFINITY;lastRetentionSweepAt=Number.NEGATIVE_INFINITY;lastContextStripAt=Number.NEGATIVE_INFINITY;contextStripInFlight=!1;focusGcInFlight=!1;worktreeSweep=new C;run(t,r){if(this.reapDeadResidue(t),this.scheduleFocusGc(r),this.gcWarmPool(t),t-this.lastRunExpiryAt>=60*6e4){G(t);try{P(t)}catch(e){console.warn(`memory-read log prune failed: ${String(e)}`)}this.lastRunExpiryAt=t}t-this.lastAnalyzeAt>=1440*6e4&&(b().exec("ANALYZE"),this.lastAnalyzeAt=t),this.sweepRetention(t,r),this.scheduleContextStrip(t,r),this.worktreeSweep.run(t,r)}msSinceTerminalActivity(t,r){const e=u(t);return e===0?Number.POSITIVE_INFINITY:r-e}sweepRetention(t,r){t-this.lastRetentionSweepAt<v||r.lifecycle.acceptsDetachedWork()&&(this.lastRetentionSweepAt=t,o.fresh(()=>{try{const e=x({ttlDays:W,held:m(r.fleet),removeDirs:c(s=>{r.lifecycle.registerDetached(Promise.all(s.map(l=>A(l,{recursive:!0,force:!0}))).then(()=>{}).catch(l=>{o.fresh(()=>{i({level:"error",event:"canvas.retention.failed",error:l})})}))},"removeDirs")});e.pruned.length>0&&i({level:"info",event:"canvas.retention.pruned",outcome:"succeeded",fields:{pruned_count:e.pruned.length}})}catch(e){i({level:"error",event:"canvas.retention.failed",error:e})}}))}scheduleContextStrip(t,r){if(this.contextStripInFlight||t-this.lastContextStripAt<v||!r.lifecycle.acceptsDetachedWork())return;this.lastContextStripAt=t,this.contextStripInFlight=!0;const e=this.stripFinishedContexts(t,r).finally(()=>{this.contextStripInFlight=!1});r.lifecycle.registerDetached(e)}async stripFinishedContexts(t,r){const e=m(r.fleet),s=c(n=>n!==null&&["done","canceled","dead"].includes(n.status)&&(n.pi_pid??null)===null&&(n.frozen_at??null)===null&&(n.run_id??null)===null&&u(n)<t-Y&&!e(n.node_id),"eligible");let l=0,p=0;try{for(const n of h({status:["done","canceled","dead"]})){if(!d(n.node_id)||!s(n))continue;const _=await T(n.node_id);if(_!==null&&_>=u(n)||!s(g(n.node_id)))continue;let a;try{a=await R(n.node_id)}catch(I){o.fresh(()=>{i({level:"warn",event:"canvas.context_strip.node_failed",error:I,fields:{node_id:n.node_id}})});continue}a.removed.length>0&&(l+=1,p+=a.bytes)}}catch(n){o.fresh(()=>{i({level:"error",event:"canvas.context_strip.failed",error:n})})}l>0&&o.fresh(()=>{i({level:"info",event:"canvas.context_strip.completed",outcome:"succeeded",fields:{node_count:l,bytes:p}})})}reapDeadResidue(t){let r;try{r=h({status:["done","canceled","dead"]})}catch(e){o.fresh(()=>{i({level:"error",event:"residue.reap_scan.failed",error:e})});return}for(const e of r)if(!(e.pane==null&&e.window==null&&e.tmux_session==null)){try{if(this.msSinceTerminalActivity(e,t)<M)continue}catch(s){o.fresh(()=>{i({level:"error",event:"residue.reap.failed",...d(e.node_id)?{node_id:e.node_id}:{},error:s,fields:{...d(e.node_id)?{}:{affected_node_id:e.node_id},pane:e.pane,window:e.window,tmux_session:e.tmux_session}})});continue}o.fresh(()=>{try{i({level:"info",event:"residue.reaped",...d(e.node_id)?{node_id:e.node_id}:{},fields:{...d(e.node_id)?{}:{affected_node_id:e.node_id},pane:e.pane,window:e.window,tmux_session:e.tmux_session}}),w(e.node_id)}catch(s){i({level:"error",event:"residue.reap.failed",...d(e.node_id)?{node_id:e.node_id}:{},error:s,fields:{...d(e.node_id)?{}:{affected_node_id:e.node_id},pane:e.pane,window:e.window,tmux_session:e.tmux_session}})}})}}scheduleFocusGc(t){if(this.focusGcInFlight||!t.lifecycle.acceptsDetachedWork())return;this.focusGcInFlight=!0;const r=this.gcStaleFocuses().finally(()=>{this.focusGcInFlight=!1});t.lifecycle.registerDetached(r)}async gcStaleFocuses(){let t;try{t=E()}catch(e){o.fresh(()=>{i({level:"error",event:"focus.gc.failed",error:e})});return}if(t.length===0)return;let r;try{r=await F()}catch(e){o.fresh(()=>{i({level:"error",event:"focus.gc.failed",error:e})});return}if(r!==null)for(const e of t){if(e.pane===null||r.has(e.pane))continue;if(!o.fresh(()=>{try{return N(e.focus_id)?.pane!==e.pane||(i({level:"info",event:"focus.gc.removed",...d(e.node_id)?{node_id:e.node_id}:{},fields:{focus_id:e.focus_id,focus_node_id:e.node_id,pane:e.pane}}),y(e.focus_id)),!0}catch(l){return i({level:"error",event:"focus.gc.failed",error:l}),!1}}))return}}gcWarmPool(t){t-this.lastSpareSweepAt<V||(this.lastSpareSweepAt=t,o.fresh(()=>{const r=D();r.length>0&&i({level:"info",event:"warm_pool.spares_reaped",outcome:"succeeded",fields:{reaped_count:r.length}})}))}}export{Y as CONTEXT_STRIP_GRACE_MS,M as DEAD_REAP_GRACE_MS,v as RETENTION_SWEEP_INTERVAL_MS,W as RETENTION_TTL_DAYS,ee as StorageMaintenanceReconciler};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var a=Object.defineProperty;var d=(e,n)=>a(e,"name",{value:n,configurable:!0});import{formatCard as r}from"../../shared/generated-context.js";function c(e,n){const o=e.document_name!==null?e.changed?`The user reviewed and approved \`${e.document_name}\`. Their edits are saved as a new revision; re-read it with \`crtr canvas read ${e.document_name}\` before continuing. Review conversation: node \`${e.companion_node_id}\`.`:`The user reviewed and approved \`${e.document_name}\`. The document was not modified.`:e.changed?`The user reviewed and approved \`${e.file}\`. The document changed during review; re-read it before continuing. Review conversation: node \`${e.companion_node_id}\`.`:`The user reviewed and approved \`${e.file}\`. The document was not modified.`;return r("review-approval",{},`${o}
|
|
2
2
|
|
|
3
|
-
Durable review result: ${
|
|
3
|
+
Durable review result: ${n}`)}d(c,"renderApprovalMessage");export{c as renderApprovalMessage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var g=Object.defineProperty;var n=(e,t)=>g(e,"name",{value:t,configurable:!0});import{withCanvasWrite as j}from"../../core/canvas/db.js";import{get as S}from"../../core/graph/bodies.js";import{documentById as q,editDocument as C,heads as $}from"../../core/graph/documents.js";import{readerFor as J}from"../../core/graph/reader.js";import{reposForCwd as k}from"../../core/graph/repo-sync/repos.js";import{snapshotCommentsLocked as x}from"../../core/review/comments.js";import{readReviewSource as N}from"../../core/review/document.js";import{projectReviewCancellation as O,projectReviewResult as T,buildReviewResult as A}from"../../core/review/project.js";import{signalReviewActivity as p}from"../../core/review/signal.js";import{clearReviewSubmit as D,getReview as E,getReviewByCompanion as B,requestReviewSubmit as F,requireVisibleReview as u}from"../../core/review/store.js";import{ReviewOperationError as f}from"../../core/review/types.js";import{settleHumanRequest as w}from"../human/settle.js";import{retireCompanion as h}from"../companion-retire.js";import{companionHasQueuedWork as W,companionMidTurn as H,companionStillWorking as M}from"./companion.js";import{renderApprovalMessage as L}from"./deliver.js";function _(){return new Date().toISOString()}n(_,"now");function l(e,t){throw new f("review_terminal","review already has a terminal outcome",{state:e.state,requested:t,review:e})}n(l,"terminalConflict");function v(e){if(e.result_json===null)throw new Error(`approved review lacks its immutable result: ${e.review_id}`);return JSON.parse(e.result_json)}n(v,"approvedResult");function y(e){return`${e.review_dir}/result.json`}n(y,"resultPath");function P(e){return{project:n(t=>{T(u(t.request_id),e)},"project"),retire:n(async(t,o)=>{await h(t,o)},"retire")}}n(P,"effects");function Q(e){return{label:"review approved by the user",disposition:"human-answer",body_json:{review_id:e.review_id,result_path:y(e),body:L(e,y(e))}}}n(Q,"approvalNotification");function V(e,t,o){const s=o==="dismissed";return{label:s?"review dismissed":"review canceled",disposition:"human-canceled",body_json:{review_id:e.review_id,disposition:o,body:s?`The review of \`${e.document_name??e.file}\` was dismissed without approval.`:`The review of \`${e.document_name??e.file}\` was canceled${t===""?"":` \u2014 ${t}`}.`}}}n(V,"cancellationNotification");function z(e,t,o){if(t.document_id===null||t.document_base===null)return;const s=n(d=>k(e,d),"reposFn"),i=q(e,t.document_id),a=J(e,{class:"person"},s),c=C(e,a,i,{body:o},`edited in review ${t.review_id}`,t.document_base,{},s);if(!("stale"in c))return;const r=$(e,i);if(!(r.length===1&&S(r[0].body_hash)===o))throw new f("stale_revision",`${t.document_name??i.name} changed since the review began; the reviewed text was not saved`,{review_id:t.review_id,document:t.document_name??i.name,base:t.document_base,heads_key:c.stale.heads_key,revision:c.stale.revision,next:`Read the current revision with \`crtr canvas read ${i.id}\`, then start a new review of it.`})}n(z,"saveReviewedDocument");async function b(e){if(e.state==="canceled")return l(e,"submit");if(e.state==="approved")return{outcome:"already_settled",record:e,result:v(e)};const t=N(e.file,"submit"),{result:o,resultJson:s}=j(c=>{const r=u(e.review_id);if(r.state==="canceled")return l(r,"submit");if(r.state==="approved")return{result:v(r),resultJson:r.result_json};const d=x(c,r.review_id),m=A(r,d,t.sha256,_());return m.changed&&z(c,r,new TextDecoder("utf-8").decode(t.bytes)),{result:m,resultJson:JSON.stringify(m)}}),i=await w({request_id:e.review_id,outcome:"approved",result_json:s,notification:Q({...e,changed:o.changed}),post_commit:P(o)});i.outcome==="settled"&&p();const a=u(e.review_id);return i.outcome==="already_settled"&&a.state!=="approved"?l(a,"submit"):{outcome:i.outcome,record:a,result:i.outcome==="settled"?o:v(a)}}n(b,"approveReview");async function de(e){const t=u(e);return t.state==="canceled"?l(t,"submit"):t.state==="open"&&M(t.companion_node_id)?(F(e,_())&&p(),{outcome:"awaiting_companion",record:u(e)}):b(t)}n(de,"submitReviewApproval");async function G(e,t){const o=E(e);if(o===null||o.state!=="open"||o.submit_requested_at===null||W(o.companion_node_id)||!t.atCompanionTurnEnd&&H(o.companion_node_id))return null;try{return await b(o)}catch(s){throw s instanceof f&&s.code==="stale_revision"&&(D(e),p()),s}}n(G,"completeRequestedSubmit");async function me(e){const t=B(e);return t===null?null:G(t.review_id,{atCompanionTurnEnd:!0})}n(me,"completeCompanionRequestedSubmit");async function le(e,t={}){const o=u(e);if(o.state==="approved")return l(o,"cancel");const s=_(),i=t.reason??"",a=t.disposition??"canceled",c=JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:s,...i===""?{}:{reason:i},...t.actor===void 0?{}:{actor:t.actor},...a==="dismissed"?{disposition:a}:{}}),r=await w({request_id:e,outcome:a==="dismissed"?"dismissed":"canceled",result_json:c,notification:V(o,i,a),post_commit:{project:n(m=>{O(u(m.request_id),JSON.parse(c))},"project"),retire:n(async(m,R)=>{await h(m,R)},"retire")}});r.outcome==="settled"&&p();const d=u(e);return r.outcome==="already_settled"&&d.state==="approved"?l(d,"cancel"):{outcome:r.outcome,record:d}}n(le,"cancelReview");export{le as cancelReview,me as completeCompanionRequestedSubmit,G as completeRequestedSubmit,de as submitReviewApproval};
|