@north-light/crouter 0.3.353 → 0.3.355
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 +135 -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 +168 -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 +11 -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/02-turn-lifecycle/02-resident.md +1 -0
- package/dist/builtin-memory/04-orchestration-kernel.md +10 -31
- 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/overlays/file-review.d.ts +1 -0
- package/dist/clients/attach/overlays/file-review.js +2 -2
- package/dist/clients/attach/render/chat-view.d.ts +6 -0
- package/dist/clients/attach/render/chat-view.js +2 -2
- 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/doc-links.d.ts +34 -0
- package/dist/clients/attach/render/doc-links.js +1 -0
- 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/markdown-source.js +5 -5
- package/dist/clients/attach/render/tool-calls.d.ts +1 -1
- package/dist/clients/attach/session/doc-materialize.d.ts +53 -0
- package/dist/clients/attach/session/doc-materialize.js +3 -0
- package/dist/clients/attach/session/document-links.d.ts +21 -0
- package/dist/clients/attach/session/document-links.js +1 -0
- package/dist/clients/attach/session/file-links.d.ts +2 -0
- package/dist/clients/attach/session/file-links.js +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 +816 -1561
- package/dist/clients/inbox/review/review-client.d.ts +5 -1
- package/dist/clients/inbox/review/review-client.js +1 -1
- 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 +10 -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 +167 -0
- package/dist/core/graph/documents.js +10 -0
- package/dist/core/graph/edges.d.ts +25 -0
- package/dist/core/graph/edges.js +1 -0
- package/dist/core/graph/events.d.ts +26 -0
- package/dist/core/graph/events.js +7 -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 +30 -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 +20 -9
- package/dist/core/runtime/roadmap.js +10 -6
- 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 +30 -0
- package/dist/core/substrate/delivery/listings.js +7 -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 +54 -0
- package/dist/core/substrate/delivery/render-event.js +8 -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/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/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.d.ts +4 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.d.ts +1 -1
- package/dist/daemon/api/operations.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/scripts/lib/isolation-env.mjs +8 -2
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
var G=Object.defineProperty;var o=(e,t)=>G(e,"name",{value:t,configurable:!0});import{randomUUID as W}from"node:crypto";import{existsSync as B,realpathSync as E,rmSync as A,statSync as Q}from"node:fs";import{join as R,resolve as k}from"node:path";import{SCHEMA_VERSION as O}from"../../types.js";import{profileSpace as $}from"../layout.js";import{PROFILE_PROJECT_MEMORY_VALUES as M}from"../../api/dto/profiles.js";import{userScopeRoot as u,resetScopeCache as m}from"../scope.js";import{ensureDir as D,nowIso as y}from"../fs-utils.js";import{deleteStoredProfile as X,getStoredProfile as x,insertStoredProfile as L,listStoredProfiles as I,updateStoredProfile as ee}from"../scoped-state/profiles.js";import{usage as c,notFound as d,ambiguous as N,general as z}from"../errors.js";import{withExclusiveDirectoryLock as te}from"../exclusive-lock.js";import{fuzzyMatchProfile as re}from"./fuzzy-match.js";const C=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/,p="root-00000000",ne="root";function w(e){return e.grantee??"app:terminal"}o(w,"profileApp");function j(e,t){D($(w(t),e).memory)}o(j,"scaffoldProfile");function g(e){if(!C.test(e))throw c(`invalid profile id: ${e}`,{received:e,next:"Profile ids look like <slug>-<8-hex-chars> (as printed by `crtr profile new`). Pass an exact id or a profile name, not a raw path."})}o(g,"assertSafeProfileId");function Se(e){g(e);const t=x(u(),e);if(t===null)throw d(`profile not found: ${e}`,{received:e});return $(w(t.manifest),e).memory}o(Se,"profileMemoryDir");function J(e){const t=M.join(", ");if(!Array.isArray(e))throw c("projects must be an array of {path, memory} objects",{received:typeof e,field:"projects",next:`Pass entries like {"path": "/abs/dir", "memory": "content"} \u2014 memory is one of: ${t}.`});for(const r of e){if(typeof r!="object"||r===null||Array.isArray(r))throw c(`invalid project entry: ${JSON.stringify(r)}`,{field:"projects",next:'Every project is an object like {"path": "/abs/dir", "memory": "content"}.'});const{path:n,memory:i}=r;if(typeof n!="string"||n.trim()==="")throw c(`project entry has no path: ${JSON.stringify(r)}`,{field:"projects",next:"Give every project entry a non-empty directory path."});if(typeof i!="string"||!M.includes(i))throw c(`invalid project memory value: ${JSON.stringify(i)}`,{received:String(i),field:"projects",next:`Set memory on ${n} to one of: ${t}.`})}}o(J,"assertProfileProjects");function oe(){return{entries:I(u()),unreadableIds:[]}}o(oe,"enumerateProfiles");function v(){return oe().entries}o(v,"listProfiles");function ie(e){const t=v(),r=T(t,e,b);return r?{kind:"resolved",entry:r}:{kind:"absent"}}o(ie,"lookupProfile");function _(e){g(e);const t=x(u(),e);if(t!==null)return t;throw d(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(_,"loadExactProfileManifest");const b=o(e=>({profileId:e.profileId,name:e.manifest.name}),"entryCandidate");function T(e,t,r){if(C.test(t)){const i=e.find(a=>r(a).profileId===t);if(i!==void 0)return i}const n=e.filter(i=>r(i).name===t);if(n.length===1)return n[0];if(n.length>1){const i=n.map(a=>r(a).profileId);throw N(`profile name "${t}" matches ${i.length} profiles: ${i.join(", ")}`,{received:t,candidates:i,next:`Re-run with one exact profile id: ${i.join(", ")}.`})}return null}o(T,"findExactProfile");function U(e,t,r){const n=e.map(i=>`${r(i).profileId} (${r(i).name})`);return d(`profile not found: ${t}`,{received:t,available:n,next:n.length>0?`Re-run with one of the profiles on this host: ${n.join(", ")} \u2014 or create one with \`crtr profile new --name <name>\`.`:"No profiles exist on this host yet \u2014 create one with `crtr profile new --name <name>`."})}o(U,"profileNotFound");function ae(e){const t=ie(e);if(t.kind==="resolved")return t.entry;throw U(v(),e,b)}o(ae,"loadProfileManifest");function Ee(e){return se(v(),e,b)}o(Ee,"resolveProfileOperand");function se(e,t,r){const n=T(e,t,r);if(n!==null)return n;const{match:i,tied:a}=re(t,e.map(r));if(i!==null){const s=e.find(f=>r(f).profileId===i.profileId);return console.error(`crtr: no profile named "${t}" \u2014 using the closest match: ${r(s).name} (${r(s).profileId})`),s}if(a.length>1){const s=a.map(f=>`${f.profileId} (${f.name})`);throw N(`"${t}" is equally close to ${a.length} profiles: ${s.join(", ")}`,{received:t,candidates:a.map(f=>f.profileId),next:`Re-run with one exact profile id or name: ${s.join(", ")}.`})}throw U(e,t,r)}o(se,"matchProfileOperand");function F(){return R(u(),"profile-locks")}o(F,"locksDir");function P(e,t){return g(e),D(F()),te(R(F(),`${e}.lock`),t,{timeoutError:o(()=>z(`timed out waiting for the profile lock: ${e}`,{next:"Retry \u2014 another `crtr profile` command may be running concurrently on this profile."}),"timeoutError")})}o(P,"withProfileManifestLock");function K(e){const t=k(e);if(!B(t)||!Q(t).isDirectory())throw c(`project directory does not exist or is not a directory: ${e}`,{received:e,next:"Pass an existing directory path."});try{return E(t)}catch{return t}}o(K,"resolveExistingProjectDir");function q(e){const t=new Set,r=[];for(const n of e)t.has(n.path)||(t.add(n.path),r.push(n));return r}o(q,"dedupeProjects");function fe(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return t.length>40&&(t=t.slice(0,40).replace(/-+$/g,"")),t.length>0?t:"profile"}o(fe,"slugify");function ce(e){const t=fe(e);for(let r=0;r<20;r++){const n=W().replace(/-/g,"").slice(0,8),i=`${t}-${n}`;if(x(u(),i)===null)return i}throw z(`failed to generate a unique profile id for "${e}" after 20 attempts`)}o(ce,"generateProfileId");function Ae(){return P(p,()=>{const e=x(u(),p);if(e!==null)return j(p,e.manifest),e;const t={schema_version:O,name:ne,projects:[],grantee:"app:terminal",paused_at:null,created_at:y(),last_used_at:y()};return j(p,t),L(u(),{profileId:p,manifest:t}),m(),{profileId:p,manifest:t}})}o(Ae,"ensureRootProfile");const H=/^[A-Za-z0-9][A-Za-z0-9_-]*$/;function Z(e){return`CRTR_PROFILE_META_${e.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}`}o(Z,"metadataEnvName");function S(e){if(typeof e!="object"||e===null||Array.isArray(e))throw c("metadata must be a map of string keys to string values",{field:"metadata",next:'Pass an object, e.g. {"role": "support"}.'});const t=new Map;for(const[r,n]of Object.entries(e)){if(!H.test(r))throw c(`invalid metadata key: ${JSON.stringify(r)}`,{received:r,field:"metadata",next:"Keys start with a letter or digit, followed by letters, digits, `_`, or `-`."});if(typeof n!="string")throw c(`metadata value for ${r} must be a string`,{received:typeof n,field:"metadata",next:"Every metadata value is an env-var value \u2014 pass strings only."});if(n.includes("\0"))throw c(`metadata value for ${r} contains a NUL byte, which no OS accepts in an environment variable`,{field:"metadata",next:"Remove NUL bytes from the value and retry."});const i=Z(r),a=t.get(i);if(a!==void 0)throw c(`metadata keys ${JSON.stringify(a)} and ${JSON.stringify(r)} both surface as ${i}`,{field:"metadata",next:"Rename or drop one \u2014 keys must stay distinct after uppercasing and `_`-folding."});t.set(i,r)}}o(S,"assertProfileMetadata");function V(e){if(typeof e!="object"||e===null||Array.isArray(e))return{};const t={},r=new Set;for(const[n,i]of Object.entries(e)){if(typeof i!="string"||!H.test(n)||i.includes("\0"))continue;const a=Z(n);r.has(a)||(r.add(a),t[n]=i)}return t}o(V,"sanitizeProfileMetadata");function ue(e,t=[],r={}){const n=e.trim();if(n==="")throw c("profile name must not be empty");r.metadata!==void 0&&S(r.metadata),J(t);const i=q(t.map(s=>({path:K(s.path),memory:s.memory}))),a=ce(n);return P(a,()=>{const s={schema_version:O,name:n,projects:i,paused_at:null,...r.grantee===void 0?{}:{grantee:r.grantee},...r.defaultKind!==void 0?{default_kind:r.defaultKind}:{},...r.metadata!==void 0&&Object.keys(r.metadata).length>0?{metadata:{...r.metadata}}:{},created_at:y(),last_used_at:null};return j(a,s),L(u(),{profileId:a,manifest:s}),m(),{profileId:a,manifest:s}})}o(ue,"createProfile");function Re(e){if(!e.startsWith("app:")||e.length<=4)throw c("an app grantee is required");const t=`app-${e.slice(4)}`,r=v().filter(n=>n.manifest.name===t&&n.manifest.grantee===e);if(r.length>1)throw new Error(`duplicate default profile for ${e}`);return r[0]?r[0]:ue(t,[],{grantee:e})}o(Re,"ensureAppProfile");function Y(e){if(g(e),x(u(),e)===null)throw d(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(Y,"requireExistingProfile");function l(e,t){return Y(e),P(e,()=>{const r=ee(u(),e,t);if(r===null)throw d(`profile not found: ${e}`,{received:e});return r})}o(l,"mutateManifest");function ke(e){return l(e,t=>({...t,last_used_at:y()}))}o(ke,"updateProfileLastUsed");function le(e){if(e==null||e==="")return null;try{return ae(e)}catch{return null}}o(le,"loadProfileManifestOrNull");function Oe(e){if(e==null||e==="")return!1;try{return _(e).manifest.paused_at!==null}catch{return!1}}o(Oe,"isProfilePaused");function de(e){if(e.manifest.paused_at!==null)throw c(`profile "${e.manifest.name}" is paused and cannot start nodes`,{received:e.profileId,next:`Resume it with \`crtr profile resume ${e.profileId}\`.`})}o(de,"assertProfileEntryActive");function Me(e){const t=le(e);return t===null?null:(de(t),t)}o(Me,"assertProfileActive");function De(e){return l(e,t=>({...t,paused_at:t.paused_at??y()}))}o(De,"pauseProfile");function Le(e){let t=null;return{...l(e,n=>(t=n.paused_at,{...n,paused_at:null})),pausedAt:t}}o(Le,"resumeProfile");function Ne(e,t){return l(e,r=>({...r,default_kind:t}))}o(Ne,"setProfileDefaultKind");function ze(e,t,r=[]){return S(t),l(e,n=>{const i={...V(n.metadata),...t};for(const f of r)delete i[f];S(i);const{metadata:a,...s}=n;return{...s,...Object.keys(i).length>0?{metadata:i}:{}}})}o(ze,"updateProfileMetadata");function Ce(e){if(e===null||e==="")return{};try{return V(_(e).manifest.metadata)}catch{return{}}}o(Ce,"readProfileMetadata");function Je(e,t){const r=t.trim();if(r==="")throw c("profile name must not be empty");const n=l(e,i=>({...i,name:r}));return m(),n}o(Je,"renameProfile");function Te(e,t,r){J([{path:t,memory:r.memory}]);const n=K(t),i=l(e,a=>{const f=a.projects.some(h=>h.path===n)?a.projects.map(h=>h.path===n?{...h,memory:r.memory}:h):q([...a.projects,{path:n,memory:r.memory}]);return{...a,projects:f}});return m(),i}o(Te,"addProfileProject");function Ue(e,t){const r=k(t);let n=r;try{n=E(r)}catch{}const i=l(e,a=>{const s=a.projects.filter(f=>f.path!==n&&f.path!==r);if(s.length===a.projects.length)throw d(`project not found on profile: ${t}`,{received:t,next:`Current projects: ${a.projects.length>0?a.projects.map(f=>f.path).join(", "):"(none)"}.`});return{...a,projects:s}});return m(),i}o(Ue,"removeProfileProject");function Fe(e){Y(e),P(e,()=>{const t=$(w(_(e).manifest),e);if(!X(u(),e))throw d(`profile not found: ${e}`,{received:e});A(t.memory,{recursive:!0,force:!0}),A(t.env,{force:!0})}),m()}o(Fe,"deleteProfile");export{p as ROOT_PROFILE_ID,Te as addProfileProject,Me as assertProfileActive,de as assertProfileEntryActive,S as assertProfileMetadata,J as assertProfileProjects,ue as createProfile,Fe as deleteProfile,Re as ensureAppProfile,Ae as ensureRootProfile,Oe as isProfilePaused,v as listProfiles,_ as loadExactProfileManifest,ae as loadProfileManifest,ie as lookupProfile,se as matchProfileOperand,Z as metadataEnvName,De as pauseProfile,Se as profileMemoryDir,Ce as readProfileMetadata,Ue as removeProfileProject,Je as renameProfile,Ee as resolveProfileOperand,Le as resumeProfile,V as sanitizeProfileMetadata,Ne as setProfileDefaultKind,ke as updateProfileLastUsed,ze as updateProfileMetadata,P as withProfileManifestLock};
|
|
1
|
+
var Y=Object.defineProperty;var o=(e,t)=>Y(e,"name",{value:t,configurable:!0});import{randomUUID as G}from"node:crypto";import{existsSync as W,realpathSync as S,rmSync as A,statSync as B}from"node:fs";import{join as E,resolve as R}from"node:path";import{SCHEMA_VERSION as O}from"../../types.js";import{profileSpace as g}from"../layout.js";import{PROFILE_PROJECT_MEMORY_VALUES as k}from"../../api/dto/profiles.js";import{userScopeRoot as c}from"../scope.js";import{ensureDir as M,nowIso as m}from"../fs-utils.js";import{deleteStoredProfile as Q,getStoredProfile as h,insertStoredProfile as D,listStoredProfiles as X,updateStoredProfile as I}from"../scoped-state/profiles.js";import{usage as f,notFound as d,ambiguous as L,general as N}from"../errors.js";import{withExclusiveDirectoryLock as ee}from"../exclusive-lock.js";import{fuzzyMatchProfile as te}from"./fuzzy-match.js";const z=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/,p="root-00000000",re="root";function P(e){return e.grantee??"app:terminal"}o(P,"profileApp");function w(e,t){M(g(P(t),e).memory)}o(w,"scaffoldProfile");function y(e){if(!z.test(e))throw f(`invalid profile id: ${e}`,{received:e,next:"Profile ids look like <slug>-<8-hex-chars> (as printed by `crtr profile new`). Pass an exact id or a profile name, not a raw path."})}o(y,"assertSafeProfileId");function Se(e){y(e);const t=h(c(),e);if(t===null)throw d(`profile not found: ${e}`,{received:e});return g(P(t.manifest),e).memory}o(Se,"profileMemoryDir");function C(e){if(!Array.isArray(e))throw f("projects must be an array of {path} objects",{received:typeof e,field:"projects",next:'Pass entries like {"path": "/abs/dir"}.'});for(const t of e){if(typeof t!="object"||t===null||Array.isArray(t))throw f(`invalid project entry: ${JSON.stringify(t)}`,{field:"projects",next:'Every project is an object like {"path": "/abs/dir"}.'});const{path:r}=t;if(typeof r!="string"||r.trim()==="")throw f(`project entry has no path: ${JSON.stringify(t)}`,{field:"projects",next:"Give every project entry a non-empty directory path."})}}o(C,"assertProfileProjects");function ne(e){const t=k.join(", ");if(typeof e!="object"||e===null||Array.isArray(e))throw f("delivery_limits must be an object mapping owner handles to a level",{received:typeof e,field:"delivery_limits",next:`Pass e.g. {"crouter": "preview"} \u2014 each level is one of: ${t}.`});for(const[r,n]of Object.entries(e)){if(r.trim()==="")throw f("delivery_limits has an empty owner handle",{field:"delivery_limits",next:"Key each limit by an owner handle such as a repo handle or `user`."});if(typeof n!="string"||!k.includes(n))throw f(`invalid delivery limit for ${r}: ${JSON.stringify(n)}`,{received:String(n),field:"delivery_limits",next:`Set ${r} to one of: ${t}.`})}}o(ne,"assertDeliveryLimits");function oe(){return{entries:X(c()),unreadableIds:[]}}o(oe,"enumerateProfiles");function v(){return oe().entries}o(v,"listProfiles");function ie(e){const t=v(),r=J(t,e,_);return r?{kind:"resolved",entry:r}:{kind:"absent"}}o(ie,"lookupProfile");function $(e){y(e);const t=h(c(),e);if(t!==null)return t;throw d(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o($,"loadExactProfileManifest");const _=o(e=>({profileId:e.profileId,name:e.manifest.name}),"entryCandidate");function J(e,t,r){if(z.test(t)){const i=e.find(a=>r(a).profileId===t);if(i!==void 0)return i}const n=e.filter(i=>r(i).name===t);if(n.length===1)return n[0];if(n.length>1){const i=n.map(a=>r(a).profileId);throw L(`profile name "${t}" matches ${i.length} profiles: ${i.join(", ")}`,{received:t,candidates:i,next:`Re-run with one exact profile id: ${i.join(", ")}.`})}return null}o(J,"findExactProfile");function T(e,t,r){const n=e.map(i=>`${r(i).profileId} (${r(i).name})`);return d(`profile not found: ${t}`,{received:t,available:n,next:n.length>0?`Re-run with one of the profiles on this host: ${n.join(", ")} \u2014 or create one with \`crtr profile new --name <name>\`.`:"No profiles exist on this host yet \u2014 create one with `crtr profile new --name <name>`."})}o(T,"profileNotFound");function ae(e){const t=ie(e);if(t.kind==="resolved")return t.entry;throw T(v(),e,_)}o(ae,"loadProfileManifest");function Ae(e){return se(v(),e,_)}o(Ae,"resolveProfileOperand");function se(e,t,r){const n=J(e,t,r);if(n!==null)return n;const{match:i,tied:a}=te(t,e.map(r));if(i!==null){const s=e.find(l=>r(l).profileId===i.profileId);return console.error(`crtr: no profile named "${t}" \u2014 using the closest match: ${r(s).name} (${r(s).profileId})`),s}if(a.length>1){const s=a.map(l=>`${l.profileId} (${l.name})`);throw L(`"${t}" is equally close to ${a.length} profiles: ${s.join(", ")}`,{received:t,candidates:a.map(l=>l.profileId),next:`Re-run with one exact profile id or name: ${s.join(", ")}.`})}throw T(e,t,r)}o(se,"matchProfileOperand");function U(){return E(c(),"profile-locks")}o(U,"locksDir");function x(e,t){return y(e),M(U()),ee(E(U(),`${e}.lock`),t,{timeoutError:o(()=>N(`timed out waiting for the profile lock: ${e}`,{next:"Retry \u2014 another `crtr profile` command may be running concurrently on this profile."}),"timeoutError")})}o(x,"withProfileManifestLock");function F(e){const t=R(e);if(!W(t)||!B(t).isDirectory())throw f(`project directory does not exist or is not a directory: ${e}`,{received:e,next:"Pass an existing directory path."});try{return S(t)}catch{return t}}o(F,"resolveExistingProjectDir");function K(e){const t=new Set,r=[];for(const n of e)t.has(n.path)||(t.add(n.path),r.push(n));return r}o(K,"dedupeProjects");function fe(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return t.length>40&&(t=t.slice(0,40).replace(/-+$/g,"")),t.length>0?t:"profile"}o(fe,"slugify");function le(e){const t=fe(e);for(let r=0;r<20;r++){const n=G().replace(/-/g,"").slice(0,8),i=`${t}-${n}`;if(h(c(),i)===null)return i}throw N(`failed to generate a unique profile id for "${e}" after 20 attempts`)}o(le,"generateProfileId");function Ee(){return x(p,()=>{const e=h(c(),p);if(e!==null)return w(p,e.manifest),e;const t={schema_version:O,name:re,projects:[],grantee:"app:terminal",paused_at:null,created_at:m(),last_used_at:m()};return w(p,t),D(c(),{profileId:p,manifest:t}),{profileId:p,manifest:t}})}o(Ee,"ensureRootProfile");const q=/^[A-Za-z0-9][A-Za-z0-9_-]*$/;function H(e){return`CRTR_PROFILE_META_${e.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}`}o(H,"metadataEnvName");function j(e){if(typeof e!="object"||e===null||Array.isArray(e))throw f("metadata must be a map of string keys to string values",{field:"metadata",next:'Pass an object, e.g. {"role": "support"}.'});const t=new Map;for(const[r,n]of Object.entries(e)){if(!q.test(r))throw f(`invalid metadata key: ${JSON.stringify(r)}`,{received:r,field:"metadata",next:"Keys start with a letter or digit, followed by letters, digits, `_`, or `-`."});if(typeof n!="string")throw f(`metadata value for ${r} must be a string`,{received:typeof n,field:"metadata",next:"Every metadata value is an env-var value \u2014 pass strings only."});if(n.includes("\0"))throw f(`metadata value for ${r} contains a NUL byte, which no OS accepts in an environment variable`,{field:"metadata",next:"Remove NUL bytes from the value and retry."});const i=H(r),a=t.get(i);if(a!==void 0)throw f(`metadata keys ${JSON.stringify(a)} and ${JSON.stringify(r)} both surface as ${i}`,{field:"metadata",next:"Rename or drop one \u2014 keys must stay distinct after uppercasing and `_`-folding."});t.set(i,r)}}o(j,"assertProfileMetadata");function Z(e){if(typeof e!="object"||e===null||Array.isArray(e))return{};const t={},r=new Set;for(const[n,i]of Object.entries(e)){if(typeof i!="string"||!q.test(n)||i.includes("\0"))continue;const a=H(n);r.has(a)||(r.add(a),t[n]=i)}return t}o(Z,"sanitizeProfileMetadata");function ce(e,t=[],r={}){const n=e.trim();if(n==="")throw f("profile name must not be empty");r.metadata!==void 0&&j(r.metadata),C(t);const i=K(t.map(s=>({path:F(s.path)}))),a=le(n);return x(a,()=>{const s={schema_version:O,name:n,projects:i,paused_at:null,...r.grantee===void 0?{}:{grantee:r.grantee},...r.defaultKind!==void 0?{default_kind:r.defaultKind}:{},...r.metadata!==void 0&&Object.keys(r.metadata).length>0?{metadata:{...r.metadata}}:{},created_at:m(),last_used_at:null};return w(a,s),D(c(),{profileId:a,manifest:s}),{profileId:a,manifest:s}})}o(ce,"createProfile");function Re(e){if(!e.startsWith("app:")||e.length<=4)throw f("an app grantee is required");const t=`app-${e.slice(4)}`,r=v().filter(n=>n.manifest.name===t&&n.manifest.grantee===e);if(r.length>1)throw new Error(`duplicate default profile for ${e}`);return r[0]?r[0]:ce(t,[],{grantee:e})}o(Re,"ensureAppProfile");function V(e){if(y(e),h(c(),e)===null)throw d(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(V,"requireExistingProfile");function u(e,t){return V(e),x(e,()=>{const r=I(c(),e,t);if(r===null)throw d(`profile not found: ${e}`,{received:e});return r})}o(u,"mutateManifest");function Oe(e){return u(e,t=>({...t,last_used_at:m()}))}o(Oe,"updateProfileLastUsed");function ue(e){if(e==null||e==="")return null;try{return ae(e)}catch{return null}}o(ue,"loadProfileManifestOrNull");function ke(e){if(e==null||e==="")return!1;try{return $(e).manifest.paused_at!==null}catch{return!1}}o(ke,"isProfilePaused");function de(e){if(e.manifest.paused_at!==null)throw f(`profile "${e.manifest.name}" is paused and cannot start nodes`,{received:e.profileId,next:`Resume it with \`crtr profile resume ${e.profileId}\`.`})}o(de,"assertProfileEntryActive");function Me(e){const t=ue(e);return t===null?null:(de(t),t)}o(Me,"assertProfileActive");function De(e){return u(e,t=>({...t,paused_at:t.paused_at??m()}))}o(De,"pauseProfile");function Le(e){let t=null;return{...u(e,n=>(t=n.paused_at,{...n,paused_at:null})),pausedAt:t}}o(Le,"resumeProfile");function Ne(e,t){return u(e,r=>({...r,default_kind:t}))}o(Ne,"setProfileDefaultKind");function ze(e,t,r=[]){return j(t),u(e,n=>{const i={...Z(n.metadata),...t};for(const l of r)delete i[l];j(i);const{metadata:a,...s}=n;return{...s,...Object.keys(i).length>0?{metadata:i}:{}}})}o(ze,"updateProfileMetadata");function Ce(e){if(e===null||e==="")return{};try{return Z($(e).manifest.metadata)}catch{return{}}}o(Ce,"readProfileMetadata");function Je(e,t){const r=t.trim();if(r==="")throw f("profile name must not be empty");return u(e,i=>({...i,name:r}))}o(Je,"renameProfile");function Te(e,t){C([{path:t}]);const r=F(t);return u(e,i=>({...i,projects:K([...i.projects,{path:r}])}))}o(Te,"addProfileProject");function Ue(e,t,r){return ne({[t]:r}),u(e,n=>{const{[t]:i,...a}=n.delivery_limits??{},s=r==="content"?a:{...a,[t]:r},{delivery_limits:l,...b}=n;return Object.keys(s).length===0?b:{...b,delivery_limits:s}})}o(Ue,"setProfileDeliveryLimit");function Fe(e,t){const r=R(t);let n=r;try{n=S(r)}catch{}return u(e,a=>{const s=a.projects.filter(l=>l.path!==n&&l.path!==r);if(s.length===a.projects.length)throw d(`project not found on profile: ${t}`,{received:t,next:`Current projects: ${a.projects.length>0?a.projects.map(l=>l.path).join(", "):"(none)"}.`});return{...a,projects:s}})}o(Fe,"removeProfileProject");function Ke(e){V(e),x(e,()=>{const t=g(P($(e).manifest),e);if(!Q(c(),e))throw d(`profile not found: ${e}`,{received:e});A(t.memory,{recursive:!0,force:!0}),A(t.env,{force:!0})})}o(Ke,"deleteProfile");export{p as ROOT_PROFILE_ID,Te as addProfileProject,ne as assertDeliveryLimits,Me as assertProfileActive,de as assertProfileEntryActive,j as assertProfileMetadata,C as assertProfileProjects,ce as createProfile,Ke as deleteProfile,Re as ensureAppProfile,Ee as ensureRootProfile,ke as isProfilePaused,v as listProfiles,$ as loadExactProfileManifest,ae as loadProfileManifest,ie as lookupProfile,se as matchProfileOperand,H as metadataEnvName,De as pauseProfile,Se as profileMemoryDir,Ce as readProfileMetadata,Fe as removeProfileProject,Je as renameProfile,Ae as resolveProfileOperand,Le as resumeProfile,Z as sanitizeProfileMetadata,Ne as setProfileDefaultKind,Ue as setProfileDeliveryLimit,Oe as updateProfileLastUsed,ze as updateProfileMetadata,x as withProfileManifestLock};
|
|
@@ -16,7 +16,7 @@ ${r}
|
|
|
16
16
|
`),process.exit(130)),c==="crtr.profile.menu.up"){o=(o-1+n.length)%n.length,m();return}if(c==="crtr.profile.menu.down"){o=(o+1)%n.length,m();return}if(c==="crtr.profile.menu.select"){a(),u({index:o});return}if(c==="crtr.profile.menu.accept-default"){a(),u({index:s.initialIndex??0});return}if(c?.startsWith("crtr.profile.menu.slot.")){const I=Number.parseInt(c.slice(-1),10);I>=1&&I<=i.length&&(o=i[I-1],m());return}const y=n.findIndex(I=>I.bindingId!==void 0&&I.bindingId===c);if(y>=0){a(),u({index:y});return}c!==null&&s.actionBindingIds?.includes(c)===!0&&(a(),u({index:o,action:c}))},"onKey");E(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("keypress",d),m()})}l(Q,"runMenu");function V(t){return ge()?(ie("tmux",["display-popup","-E","-T"," profiles ","-w","90%","-h","85%","-d",t,...Ie(),"crtr sys settings --page profiles"],{stdio:"inherit"}),!0):(process.stdout.write(` ${$("the profile manager needs tmux \u2014 run `crtr sys settings` instead")}
|
|
17
17
|
`),!1)}l(V,"openProfileManager");const _=Symbol("profile-manager-ran");function X(t){return` ${w("\u203A")} ${$(t)} `}l(X,"caret");function Se(t){return`crtr: no profile covers ${t}, and this session is non-interactive \u2014 using the root profile.
|
|
18
18
|
Run \`crtr profile new --name <name> --project ${t}\` to create a dedicated profile, or pass --profile <id-or-name> next time.
|
|
19
|
-
`}l(Se,"rootProfileMessage");async function Ee(t,e){const r=v({input:process.stdin,output:process.stdout});try{Te(`Profile "${t.manifest.name}" doesn't cover this directory`),await Z(r,t,e)}finally{r.close()}}l(Ee,"promptAddDirToProfile");async function Z(t,e,r){const n=(await t.question(X(`add this directory to "${e.manifest.name}"? [Y/n]`))).trim().toLowerCase();n==="n"||n==="no"||(j(e.profileId,r
|
|
19
|
+
`}l(Se,"rootProfileMessage");async function Ee(t,e){const r=v({input:process.stdin,output:process.stdout});try{Te(`Profile "${t.manifest.name}" doesn't cover this directory`),await Z(r,t,e)}finally{r.close()}}l(Ee,"promptAddDirToProfile");async function Z(t,e,r){const n=(await t.question(X(`add this directory to "${e.manifest.name}"? [Y/n]`))).trim().toLowerCase();n==="n"||n==="no"||(j(e.profileId,r),process.stdout.write(` ${w("\u2713")} ${$(`added this directory to "${e.manifest.name}"`)}
|
|
20
20
|
`))}l(Z,"offerAddDirToProfile");async function Ae(t){const e=[...A()].filter(i=>i.profileId!==D).sort((i,o)=>T(i.manifest.last_used_at,o.manifest.last_used_at)?-1:1);if(e.length===0)return process.stdout.write(` ${$("no existing profiles to select")}
|
|
21
21
|
`),null;let r="",n=0;const s=l(()=>r===""?e:e.filter(i=>i.manifest.name.toLowerCase().includes(r)||i.manifest.projects.some(o=>b(o.path).toLowerCase().includes(r))),"matchesOf");return new Promise(i=>{let o=0;const u=l(()=>{const a=s();n>=a.length&&(n=Math.max(0,a.length-1));let d=`
|
|
22
22
|
${x("Select an existing profile")}
|
|
@@ -28,8 +28,8 @@ Run \`crtr profile new --name <name> --project ${t}\` to create a dedicated prof
|
|
|
28
28
|
${w("\u203A")} ${r}${$("\u2588")}
|
|
29
29
|
`,d+=` ${$(`type to filter ${g(t,"crtr.profile.search.up")}/${g(t,"crtr.profile.search.down")} move ${g(t,"crtr.profile.search.pick")} pick ${g(t,"crtr.profile.search.back")} back`)}
|
|
30
30
|
`,process.stdout.write((o>0?z(o)+G:"")+d),o=J(d)},"draw"),h=l(()=>{process.stdin.off("keypress",m),process.stdin.isTTY&&process.stdin.setRawMode(!1),process.stdin.pause()},"cleanup"),m=l((a,d)=>{const p=ve(t,L(a,d));if(p==="crtr.profile.search.abort"&&(h(),process.stdout.write(`
|
|
31
|
-
`),process.exit(130)),p==="crtr.profile.search.back"){h(),i(null);return}const f=s();if(p==="crtr.profile.search.pick"){f.length>0&&(h(),i(f[n].profileId));return}if(p==="crtr.profile.search.up"){f.length>0&&(n=(n-1+f.length)%f.length,u());return}if(p==="crtr.profile.search.down"){f.length>0&&(n=(n+1)%f.length,u());return}if(p==="crtr.profile.search.delete"){r=r.slice(0,-1),n=0,u();return}a!==void 0&&a.length===1&&a>=" "&&d.ctrl!==!0&&(r+=a.toLowerCase(),n=0,u())},"onKey");E(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("keypress",m),u()})}l(Ae,"promptSelectExistingProfile");async function ee(t,e){const r=ce(e)||"profile",n=(await t.question(X(`name the new profile [${r}]`))).trim(),s=n!==""?n:r,i=me(s,[{path:e
|
|
31
|
+
`),process.exit(130)),p==="crtr.profile.search.back"){h(),i(null);return}const f=s();if(p==="crtr.profile.search.pick"){f.length>0&&(h(),i(f[n].profileId));return}if(p==="crtr.profile.search.up"){f.length>0&&(n=(n-1+f.length)%f.length,u());return}if(p==="crtr.profile.search.down"){f.length>0&&(n=(n+1)%f.length,u());return}if(p==="crtr.profile.search.delete"){r=r.slice(0,-1),n=0,u();return}a!==void 0&&a.length===1&&a>=" "&&d.ctrl!==!0&&(r+=a.toLowerCase(),n=0,u())},"onKey");E(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("keypress",m),u()})}l(Ae,"promptSelectExistingProfile");async function ee(t,e){const r=ce(e)||"profile",n=(await t.question(X(`name the new profile [${r}]`))).trim(),s=n!==""?n:r,i=me(s,[{path:e}]).profileId;return process.stdout.write(` ${w("\u2713")} ${$(`created profile "${s}"`)}
|
|
32
32
|
`),i}l(ee,"createProfileHere");async function je(t,e){const r=[{label:"create a profile here",detail:"",bindingId:"crtr.profile.menu.create"},{label:"select an existing profile",detail:"",bindingId:"crtr.profile.menu.search-existing"},{label:$("use the root profile"),detail:"",bindingId:"crtr.profile.menu.use-root",isDefault:!0}];for(;;){const n=await Q(e,"No profile covers this directory",void 0,r,{initialIndex:2,actionBindingIds:["crtr.profile.menu.manage"],hint:`${g(e,"crtr.profile.menu.manage")}=manage profiles`});if(n.action==="crtr.profile.menu.manage"){if(V(t))return _;continue}if(n.index===0){const s=v({input:process.stdin,output:process.stdout});try{return await ee(s,t)}finally{s.close()}}if(n.index===1){const s=await Ae(e);if(s===null)continue;const i=pe(s),o=v({input:process.stdin,output:process.stdout});try{await Z(o,i,t)}finally{o.close()}return i.profileId}return k().profileId}}l(je,"promptCreateOrRoot");async function C(t,e,r,n,s){const i=[...t].sort((c,y)=>T(c.manifest.last_used_at,y.manifest.last_used_at)?-1:1),o=n!==null?i.find(c=>c.profileId===n)??null:null,u=o!==null?[o,...i.filter(c=>c!==o)]:i,h=Math.max(...u.map(c=>c.manifest.name.length)),m=u.map((c,y)=>{const I=c.manifest.projects.length,te=r?`${K(c.manifest.last_used_at)}${I>1?` \xB7 ${I} dirs total`:""}`:(()=>{const R=c.manifest.projects.find(ne=>B(e,ne.path))??c.manifest.projects[0];return I>1?`matches ${b(R.path)} \xB7 ${I} dirs total`:`matches ${b(R.path)}`})(),re=o!==null&&u[0]===o?"default (pinned)":"default";return{label:x(c.manifest.name.padEnd(h)),detail:te,isDefault:y===0,defaultText:re}});m.push({label:$("create a new profile here"),detail:"",bindingId:"crtr.profile.menu.create"});const a=["crtr.profile.menu.set-default","crtr.profile.menu.manage"];r||a.push("crtr.profile.menu.add-directory"),o!==null&&a.push("crtr.profile.menu.unpin");const d=[`${g(s,"crtr.profile.menu.set-default")}=set default`];r||d.push(`${g(s,"crtr.profile.menu.add-directory")}=add dir here`),o!==null&&d.push(`${g(s,"crtr.profile.menu.unpin")}=unpin`),d.push(`${g(s,"crtr.profile.menu.manage")}=manage profiles`);const p=await Q(s,r?"Choose a profile":"Select a profile",r?"Several profiles claim this directory as their project":"This directory falls under existing profile(s)",m,{actionBindingIds:a,hint:d.join(" ")});if(p.action==="crtr.profile.menu.manage")return V(e)?_:await C(t,e,r,n,s);if(p.index>=u.length){const c=v({input:process.stdin,output:process.stdout});try{return await ee(c,e)}finally{c.close()}}const f=u[p.index];return p.action==="crtr.profile.menu.unpin"?(O(e),process.stdout.write(` ${w("\u2713")} ${$("cleared the default for this directory")}
|
|
33
33
|
`),f.profileId):(p.action==="crtr.profile.menu.set-default"?($e(e,f.profileId),process.stdout.write(` ${w("\u2713")} ${$(`"${f.manifest.name}" is now the default here`)}
|
|
34
|
-
`)):p.action==="crtr.profile.menu.add-directory"&&(j(f.profileId,e
|
|
34
|
+
`)):p.action==="crtr.profile.menu.add-directory"&&(j(f.profileId,e),process.stdout.write(` ${w("\u2713")} ${$(`added this directory to "${f.manifest.name}"`)}
|
|
35
35
|
`)),f.profileId)}l(C,"promptPickProfileOrCreate");async function Qe(t,e,r=!1){fe({kind:"user",root:ue()});const n=Y(t),s=ye();if(e!=null&&e!==""){const i=de(e);return!F(i,n)&&H()&&await Ee(i,n),P(i.profileId),i.profileId}for(;;){const{covering:i,exact:o,pinnedId:u,pinned:h}=U(n);if(u!==null&&h===null&&O(n),h!==null&&!r)return P(h.profileId),h.profileId;if(!r&&h===null&&o.length===1)return P(o[0].profileId),o[0].profileId;if(!H()){const d=o.length>0?o:i;if(d.length>0){const f=W(d);return P(f.profileId),f.profileId}const p=k();return process.stderr.write(Se(n)),p.profileId}const m=h!==null?h.profileId:null,a=o.length>1?await C(o,n,!0,m,s):i.length>0?await C(i,n,!1,m,s):await je(n,s);if(a!==_)return P(a),a}}l(Qe,"selectProfileForCwd");export{F as profileCoversCwd,be as resolveProfileMenuAction,ve as resolveProfileSearchAction,Qe as selectProfileForCwd,Je as selectProfileForCwdReadOnly};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var s=Object.defineProperty;var n=(o,e)=>s(o,"name",{value:e,configurable:!0});import{commitBindingRequest as w}from"../human/requests.js";import{getReview as _}from"./store.js";import{discardStaging as a,stageReview as c}from"./stage.js";import{realizeReview as d}from"./realize.js";async function f(o){const e=await c(o);if(e.existing!==void 0){await d(e.existing.request_id);const r=_(e.existing.request_id);if(r===null)throw new Error(`realized review disappeared: ${e.existing.request_id}`);return r}let i;try{i=w({request_id:e.row.review_id,idempotency_key:e.row.idempotency_key,requester_node_id:e.row.origin_node_id,companion_node_id:e.row.companion_node_id,request_dir:e.row.review_dir,file:e.row.file,specification:{origin_kind:e.row.origin_kind,origin_session_file:e.row.origin_session_file,origin_session_id:e.row.origin_session_id,origin_leaf_id:e.row.origin_leaf_id,model_spec:e.row.model_spec,branch_file:e.row.branch_file,baseline_sha256:e.row.baseline_sha256,baseline_bytes:e.row.baseline_bytes,captured_at:e.row.captured_at,output_path:e.row.output_path,document_id:e.row.document_id,document_name:e.row.document_name,document_base:e.row.document_base},anchor_base_sha256:e.row.anchor_base_sha256,anchor_base_bytes:e.row.anchor_base_bytes,created_at:e.row.created,subtitle:e.row.subtitle,...e.row.document_name===null?{}:{title:e.row.document_name},inbox_listed:e.row.origin_kind==="ticket"})}catch(r){throw a(e.row.review_id,e.row.branch_file),r}i.won||a(e.row.review_id,e.row.branch_file),await d(i.request_id);const t=_(i.request_id);if(t===null)throw new Error(`realized review disappeared: ${i.request_id}`);return t}n(f,"createReview");export{f as createReview};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var y=Object.defineProperty;var
|
|
1
|
+
var y=Object.defineProperty;var s=(e,o)=>y(e,"name",{value:o,configurable:!0});import{randomUUID as v}from"node:crypto";import{conversationIdFromPath as u,conversationStore as w,ConversationNotFoundError as p}from"../conversation-store/index.js";import{basename as F,isAbsolute as c}from"node:path";import{BrokerClient as x}from"../broker-client/index.js";import{deleteNode as M,getNode as g}from"../canvas/index.js";import{expandModelCandidates as C,selectInitialModelRoute as E}from"../model-routes.js";import{buildLaunchSpec as L}from"../runtime/launch.js";import{openModelRegistry as B}from"../runtime/model-registry.js";import{isBrokerLive as O}from"../runtime/model-swap.js";import{spawnNode as R}from"../runtime/nodes.js";import{SessionManager as D}from"../runtime/broker-sdk.js";import{isReviewBoundary as P}from"../runtime/session-visibility.js";import{forkNodeLedger as $}from"../runtime/ledger.js";import{ReviewOperationError as b}from"./types.js";const I=/^[^/\s:]+\/[^/\s:]+:(?:off|minimal|low|medium|high|xhigh|max)$/,q=100;function N(e){return new b("review_origin_missing","review origin was not found",{origin_node_id:e})}s(N,"originMissing");function f(e,o,r={}){return new b("review_origin_unforkable","review origin has no forkable exact session",{origin_node_id:e,reason:o,...r})}s(f,"originUnforkable");async function k(e,o,r){const n=u(o.sourceFile);if(!c(o.sourceFile)||n===null||n!==o.sourceSessionId||o.leafId===null||o.leafId==="")throw f(e,"no_forkable_session");try{w().header(n)}catch(i){throw i instanceof p?f(e,"no_forkable_session"):i}if(o.modelSpec===null||!I.test(o.modelSpec))throw f(e,"model_unresolvable");const t=E({kind:"exact",spec:o.modelSpec},r??await B(),{cwd:o.cwd,profileId:o.profileId});if(t.selected===void 0)throw f(e,"model_unresolvable",{model_reason:t.rejected[0]?.reason});return{sourceFile:o.sourceFile,sourceSessionId:o.sourceSessionId,leafId:o.leafId,modelSpec:o.modelSpec}}s(k,"validateCapture");function U(e){return new Promise((o,r)=>{const n=new x(e);let t=!1;function i(d){t||(t=!0,n.close(),d())}s(i,"finish"),n.on("error",d=>i(()=>r(d))),n.on("close",()=>i(()=>r(new Error("origin broker closed before fork coordinates were read")))),n.on("connect",()=>{n.send({type:"hello",role:"observer",client_id:v()}),n.request({type:"get_human_fork_coordinates"}).then(d=>{if(d.kind!=="human_fork_coordinates"){i(()=>r(new Error("origin broker returned an unexpected fork-coordinate response")));return}i(()=>o(d))}).catch(d=>i(()=>r(d)))}),n.connect()})}s(U,"captureLiveOrigin");async function re(e,o={}){const r=g(e);if(r===null)throw N(e);if(O(r)){const a=await U(e);return k(e,{...a,cwd:r.cwd,profileId:r.profile_id},o.registry)}const n=typeof r.pi_session_file=="string"?r.pi_session_file:"";let t="",i=null,d=null;const h=u(n);if(c(n)&&h!==null)try{const a=w().read(h),m=D.inMemory(a.header.cwd,void 0,[a.header,...a.entries]);t=m.getSessionId(),i=m.getLeafId();const _=r.launch?.model,l=typeof _=="string"?C({kind:"exact",spec:_},r.cwd,r.profile_id)[0]:void 0;if(l!==void 0){const S=l.thinkingLevel??(m.buildSessionContext().thinkingLevel||"off");d=`${l.providerId}/${l.modelId}:${S}`}}catch(a){if(!(a instanceof p))throw a}return k(e,{sourceFile:n,sourceSessionId:t,leafId:i,modelSpec:d,cwd:r.cwd,profileId:r.profile_id},o.registry)}s(re,"captureOrigin");async function ne(e){if(!c(e.branchFile)||!c(e.targetFile))throw new Error("review companion requires absolute branch and target paths");if(!I.test(e.modelSpec))throw new Error("review companion requires an exact model spec");const{launch:o}=L("review/companion","base",{lifecycle:"resident",hasManager:!1,model:e.modelSpec,modelExact:!0,cwd:e.cwd,profileId:e.profileId}),r=await R({nodeId:e.nodeId,kind:"review/companion",mode:"base",lifecycle:"resident",cwd:e.cwd,profile_id:e.profileId,parent:e.originNodeId,creator:e.originNodeId,subscribe:!1,forkFrom:e.branchFile,forkSourceFile:e.branchFile,modelOverride:e.modelSpec,reviewBinding:{review_id:e.reviewId,origin_node_id:e.originNodeId,branch_file:e.branchFile,target_file:e.targetFile},name:`review ${F(e.targetFile)}`,launch:o});try{$(r.node_id,e.originNodeId)}catch(n){throw M(r.node_id),n}}s(ne,"spawnReviewCompanion");function A(e){const o=g(e),r=o?.review_binding,n=o?.pi_session_file,t=typeof n=="string"?u(n):null;if(r==null||o?.pi_session_id==null||t===null)return!1;try{return w().read(t).entries.some(i=>P(i,r.review_id))}catch(i){if(i instanceof p)return!1;throw i}}s(A,"isReviewCompanionBound");async function ie(e,o){const r=Date.now()+Math.max(0,o);for(;;){if(A(e))return!0;const n=r-Date.now();if(n<=0)return!1;await new Promise(t=>setTimeout(t,Math.min(q,n)))}}s(ie,"awaitCompanionBind");export{ie as awaitCompanionBind,re as captureOrigin,A as isReviewCompanionBound,ne as spawnReviewCompanion};
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { type HumanRequestRecord } from '../human/requests.js';
|
|
2
2
|
import { type NewReviewRow, type ReviewOriginKind } from './types.js';
|
|
3
|
+
/** The document a review is of: the head the origin read, snapshotted into the review dir. */
|
|
4
|
+
export interface ReviewedDocument {
|
|
5
|
+
id: string;
|
|
6
|
+
/** `<owner>/<name>`. */
|
|
7
|
+
name: string;
|
|
8
|
+
/** The heads the snapshot was read from — the base of the save on submit. */
|
|
9
|
+
base: string;
|
|
10
|
+
body: string;
|
|
11
|
+
}
|
|
12
|
+
/** Exactly one of `file` (an inline review of a file) or `document`. */
|
|
3
13
|
export interface StageReviewArgs {
|
|
4
14
|
origin_kind: ReviewOriginKind;
|
|
5
15
|
origin_node_id: string;
|
|
6
|
-
file
|
|
16
|
+
file?: string;
|
|
17
|
+
document?: ReviewedDocument;
|
|
7
18
|
idempotency_key: string;
|
|
8
19
|
subtitle?: string;
|
|
9
20
|
output_path?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var v=Object.defineProperty;var o=(e,n)=>v(e,"name",{value:n,configurable:!0});import{createHash as g}from"node:crypto";import{existsSync as y,readFileSync as b,realpathSync as S,rmSync as F,statSync as I,writeFileSync as k}from"node:fs";import{isAbsolute as x,join as R}from"node:path";import{getNode as O}from"../canvas/index.js";import{conversationIdFromPath as j,conversationStore as z,ConversationNotFoundError as D}from"../conversation-store/index.js";import{ensureReviewDir as E,reviewDir as l}from"../canvas/paths.js";import{checkReviewableFile as B}from"../human/visible-paths.js";import{newNodeId as w}from"../runtime/nodes.js";import{captureOrigin as N}from"./companion.js";import{materializeSessionBranch as q}from"../runtime/session-branch.js";import{getRequestByIdempotencyKey as A}from"../human/requests.js";import{ReviewOperationError as r}from"./types.js";function a(e,n){return new r("review_target_unreviewable","review target cannot be staged",{phase:"create",file:e,reason:n})}o(a,"targetError");function h(e){if(!x(e))throw a(e,"not_absolute");if(!y(e))throw a(e,"missing");try{if(!I(e).isFile())throw a(e,"not_a_file")}catch(i){throw i instanceof r?i:a(e,"missing")}const n=B(e);if(!n.ok){const i=n.reason==="file is not UTF-8 text"?"binary":n.reason==="file is too large to review (2 MB limit)"?"too_large":n.reason==="file is too long to review (5,000 line limit)"?"too_many_lines":"not_a_file";throw a(e,i)}try{return S(e)}catch{throw a(e,"missing")}}o(h,"validateReviewFile");function U(e){return new r("review_branch_unavailable","review branch could not be materialized",{reason:"materialize_failed",origin_node_id:e})}o(U,"branchUnavailable");async function C(e){try{return await N(e)}catch(n){throw n instanceof r&&n.code==="review_origin_missing"?new r("review_origin_missing","review origin was not found",{origin_node_id:e,reason:"origin_missing"}):n}}o(C,"captureStagedOrigin");function H(e,n){try{return q(n)}catch{throw U(e)}}o(H,"materialize");function K(e,n){if(n!==void 0){const i=j(n);if(i===null)throw new Error(`invalid staged conversation path: ${n}`);try{z().delete(i)}catch(c){if(!(c instanceof D))throw c}}try{F(l(e),{recursive:!0,force:!0})}catch{}}o(K,"discardStaging");async function ee(e){const n=A(e.idempotency_key);if(n!==null)return{existing:n};if(O(e.origin_node_id)===null)throw new r("review_origin_missing","review origin was not found",{origin_node_id:e.origin_node_id,reason:"origin_missing"});const i=w(),c=w();let d,s=e.document===void 0?h(e.file??""):"";try{if(E(i),e.document!==void 0){const m=R(l(i),"document.md");k(m,e.document.body),s=h(m)}const t=await C(e.origin_node_id),p=new Date().toISOString(),_=b(s),u=g("sha256").update(_).digest("hex");d=H(e.origin_node_id,t);const f=new Date().toISOString();return{row:{review_id:i,idempotency_key:e.idempotency_key,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,companion_node_id:c,review_dir:l(i),file:s,origin_session_file:t.sourceFile,origin_session_id:t.sourceSessionId,origin_leaf_id:t.leafId,model_spec:t.modelSpec,branch_file:d,baseline_sha256:u,baseline_bytes:_.length,anchor_base_sha256:u,anchor_base_bytes:_,state:"binding",created:f,captured_at:p,opened_at:null,submit_requested_at:null,output_path:e.output_path??null,document_id:e.document?.id??null,document_name:e.document?.name??null,document_base:e.document?.base??null,subtitle:e.subtitle??null,approved_at:null,approved_sha256:null,changed:null,comments_total:null,comments_unresolved:null,result_json:null,canceled_at:null,cancel_reason:null,cancel_actor:null,delivery_entry_id:null,delivered_at:null,delivery_error:null,projected_at:null,projection_error:null},review_dir:l(i)}}catch(t){throw K(i,d),t}}o(ee,"stageReview");export{K as discardStaging,ee as stageReview};
|
|
@@ -24,6 +24,8 @@ export declare function listBindingReviews(): ReviewRecord[];
|
|
|
24
24
|
export declare function listSubmitRequestedReviews(): ReviewRecord[];
|
|
25
25
|
export declare function listUnprojectedTerminalReviews(): ReviewRecord[];
|
|
26
26
|
export declare function openReviewRow(reviewId: string, openedAt: string): boolean;
|
|
27
|
+
/** Put a deferred submit back to not-requested, so the person sees the review open again. */
|
|
28
|
+
export declare function clearReviewSubmit(reviewId: string): void;
|
|
27
29
|
export declare function requestReviewSubmit(reviewId: string, at: string): boolean;
|
|
28
30
|
export declare function approveReviewLocked(db: DatabaseSync, args: ApproveReviewArgs): boolean;
|
|
29
31
|
export declare function cancelReviewRow(reviewId: string, args: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var t=(e,n)=>u(e,"name",{value:n,configurable:!0});import{existsSync as c}from"node:fs";import{withCanvasWrite as a}from"../canvas/db.js";import{getRequest as d,getRequestByCompanion as l,getRequestByIdempotencyKey as _,listBindingRequests as p,listRequests as s,listSubmitRequestedRequests as m,listUnprojectedReviews as v,markProjected as w,markProjectionError as f,openRequest as h,readAnchorBase as R,replaceAnchorBaseLocked as E,requestSubmit as y}from"../human/requests.js";import{ReviewOperationError as j}from"./types.js";function k(e){try{const n=JSON.parse(e.specification_json);if(typeof n!="object"||n===null)throw new Error("not an object");return n}catch(n){throw new Error(`corrupt review specification: ${e.request_id}`,{cause:n})}}t(k,"specification");function b(e){return e.state!=="settled"?e.state:e.outcome==="approved"?"approved":"canceled"}t(b,"state");function i(e){if(e.kind!=="review")throw new Error(`human request is not a review: ${e.request_id}`);const n=k(e),r=b(e),o=e.settled_at;return{review_id:e.request_id,idempotency_key:e.idempotency_key??"",origin_kind:n.origin_kind??(e.inbox_listed?"ticket":"inline"),origin_node_id:e.requester_node_id??"",companion_node_id:e.companion_node_id??"",review_dir:e.request_dir,file:e.file??"",origin_session_file:n.origin_session_file,origin_session_id:n.origin_session_id,origin_leaf_id:n.origin_leaf_id,model_spec:n.model_spec,branch_file:n.branch_file,baseline_sha256:n.baseline_sha256,baseline_bytes:n.baseline_bytes,anchor_base_sha256:e.anchor_base_sha256??"",state:r,created:e.created_at,captured_at:n.captured_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,output_path:n.output_path??null,document_id:n.document_id??null,document_name:n.document_name??null,document_base:n.document_base??null,subtitle:e.subtitle,approved_at:r==="approved"?o:null,approved_sha256:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").approved_sha256??null}catch{return null}})():null,changed:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").changed??null}catch{return null}})():null,comments_total:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").comments_total??null}catch{return null}})():null,comments_unresolved:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").comments_unresolved??null}catch{return null}})():null,result_json:e.result_json,canceled_at:r==="canceled"?o:null,cancel_reason:r==="canceled"?(()=>{try{return JSON.parse(e.result_json??"{}").reason??null}catch{return null}})():null,cancel_actor:r==="canceled"?(()=>{try{return JSON.parse(e.result_json??"{}").actor??null}catch{return null}})():null,delivery_entry_id:e.settlement_delivery_id,delivered_at:e.settlement_delivery_id===null?null:o,delivery_error:null,projected_at:e.projected_at,projection_error:e.projection_error,source_missing:!c(e.file??"")}}t(i,"record");function g(e){const n=d(e);return n?.kind==="review"?n:null}t(g,"requestForReview");function x(e){const n=g(e);return n===null?null:i(n)}t(x,"getReview");function L(e){const n=x(e);if(n===null||n.state==="binding")throw new j("unknown_review","review was not found",{received:e});return n}t(L,"requireVisibleReview");function q(e){const n=_(e);return n?.kind==="review"?i(n):null}t(q,"getReviewByIdempotencyKey");function T(e){const n=l(e);return n?.kind==="review"?i(n):null}t(T,"getReviewByCompanion");function I(e){return s({kind:"review",...e.origin_node_id===void 0?{}:{requester_node_id:e.origin_node_id},...e.file===void 0?{}:{file:e.file}}).map(i).filter(n=>n.state!=="binding"&&(e.state===void 0||n.state===e.state))}t(I,"listReviews");function N(e){const n=new Set(e);return s({kind:"review"}).filter(r=>r.requester_node_id!==null&&n.has(r.requester_node_id)).map(r=>r.request_id)}t(N,"reviewIdsByOriginNodes");function P(e){const n=N(e);return n.length===0?[]:(a(r=>{const o=n.map(()=>"?").join(",");r.prepare(`DELETE FROM review_comment_events WHERE review_id IN (${o})`).run(...n),r.prepare(`DELETE FROM review_comments WHERE review_id IN (${o})`).run(...n),r.prepare(`DELETE FROM human_requests WHERE request_id IN (${o})`).run(...n)}),n)}t(P,"deleteReviewsByOriginNodes");function J(){return p().map(i)}t(J,"listBindingReviews");function U(){return m().map(i)}t(U,"listSubmitRequestedReviews");function W(){return v().map(i)}t(W,"listUnprojectedTerminalReviews");function H(e,n){return h(e,n)}t(H,"openReviewRow");function $(e){a(n=>n.prepare("UPDATE human_requests SET submit_requested_at = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(new Date().toISOString(),e))}t($,"clearReviewSubmit");function F(e,n){return y(e,n)}t(F,"requestReviewSubmit");function C(e,n){return e.prepare("UPDATE human_requests SET state = 'settled', outcome = 'approved', result_json = ?, settled_at = ?, progress_json = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(n.result_json,n.approved_at,n.approved_at,n.review_id).changes>0}t(C,"approveReviewLocked");function M(e,n){return a(r=>r.prepare("UPDATE human_requests SET state = 'settled', outcome = 'canceled', result_json = ?, settled_at = ?, progress_json = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.at,...n.reason===""?{}:{reason:n.reason},...n.actor===null?{}:{actor:n.actor}}),n.at,n.at,e).changes>0)}t(M,"cancelReviewRow");function K(e,n){w(e,n)}t(K,"markProjected");function V(e,n){f(e,n)}t(V,"markProjectionError");function z(e,n,r){}t(z,"markDelivered");function G(e,n){}t(G,"markDeliveryError");function Q(e){return R(e)}t(Q,"readAnchorBase");function X(e,n,r,o){E(e,n,r,o)}t(X,"replaceAnchorBaseLocked");export{C as approveReviewLocked,M as cancelReviewRow,$ as clearReviewSubmit,P as deleteReviewsByOriginNodes,x as getReview,T as getReviewByCompanion,q as getReviewByIdempotencyKey,J as listBindingReviews,I as listReviews,U as listSubmitRequestedReviews,W as listUnprojectedTerminalReviews,z as markDelivered,G as markDeliveryError,K as markProjected,V as markProjectionError,H as openReviewRow,Q as readAnchorBase,X as replaceAnchorBaseLocked,F as requestReviewSubmit,L as requireVisibleReview,N as reviewIdsByOriginNodes};
|
|
@@ -9,7 +9,7 @@ export type ReviewOriginKind = 'ticket' | 'inline';
|
|
|
9
9
|
export type CommentStatus = 'open' | 'resolved' | 'deleted';
|
|
10
10
|
export type CommentAuthorKind = 'human' | 'node';
|
|
11
11
|
export type CommentEventKind = 'created' | 'edited' | 'resolved' | 'reopened' | 'deleted' | 'reanchored' | 'notified' | 'notify_failed';
|
|
12
|
-
export type ReviewErrorCode = 'review_origin_missing' | 'review_origin_unforkable' | 'review_branch_unavailable' | 'branch_lost' | 'review_companion_unbound' | 'review_bridge_unsubscribed' | 'review_target_unreviewable' | 'source_unreadable' | 'delivery_unroutable' | 'unknown_review' | 'review_terminal' | 'review_required' | 'stale_document' | 'unknown_comment' | 'comment_deleted' | 'invalid_anchor' | 'anchor_out_of_range' | 'text_too_long' | 'comment_limit_reached' | 'stale_comment' | 'range_batch_incomplete' | 'range_batch_stale';
|
|
12
|
+
export type ReviewErrorCode = 'review_origin_missing' | 'review_origin_unforkable' | 'review_branch_unavailable' | 'branch_lost' | 'review_companion_unbound' | 'review_bridge_unsubscribed' | 'review_target_unreviewable' | 'source_unreadable' | 'delivery_unroutable' | 'unknown_review' | 'review_terminal' | 'review_required' | 'stale_document' | 'stale_revision' | 'unknown_comment' | 'comment_deleted' | 'invalid_anchor' | 'anchor_out_of_range' | 'text_too_long' | 'comment_limit_reached' | 'stale_comment' | 'range_batch_incomplete' | 'range_batch_stale';
|
|
13
13
|
/** Limits */
|
|
14
14
|
export declare const COMMENT_TEXT_MAX = 8000;
|
|
15
15
|
export declare const COMMENT_QUOTE_MAX = 4000;
|
|
@@ -51,6 +51,12 @@ export interface ReviewRow {
|
|
|
51
51
|
* until the companion goes quiet and the daemon completes the approval. */
|
|
52
52
|
submit_requested_at: string | null;
|
|
53
53
|
output_path: string | null;
|
|
54
|
+
/** A document review: the document's object id, its `<owner>/<name>`, and the heads it was
|
|
55
|
+
* snapshotted from — the base the reviewed text is saved against on submit. All null for a
|
|
56
|
+
* file review. */
|
|
57
|
+
document_id: string | null;
|
|
58
|
+
document_name: string | null;
|
|
59
|
+
document_base: string | null;
|
|
54
60
|
subtitle: string | null;
|
|
55
61
|
approved_at: string | null;
|
|
56
62
|
approved_sha256: string | null;
|
package/dist/core/runs/events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var v=Object.defineProperty;var o=(e,t)=>v(e,"name",{value:t,configurable:!0});import{openDb as R,withCanvasWrite as _}from"../canvas/db.js";import{repairRunConversations as S}from"../canvas/sessions.js";const i=new Map;function p(e,t,n,s,u={}){const r=e.prepare("SELECT event_cursor, grantee, metadata_json FROM
|
|
1
|
+
var v=Object.defineProperty;var o=(e,t)=>v(e,"name",{value:t,configurable:!0});import{openDb as R,withCanvasWrite as _}from"../canvas/db.js";import{repairRunConversations as S}from"../canvas/sessions.js";const i=new Map;function p(e,t,n,s,u={}){const r=e.prepare("SELECT event_cursor, grantee, metadata_json FROM node_rows WHERE node_id = ? AND run_id = ?").get(t,t);if(!r||r.event_cursor===null)throw new Error(`missing run event cursor: ${t}`);const a={type:s,run_id:t,node_id:n,sequence_number:r.event_cursor,ts:new Date().toISOString(),metadata:r.metadata_json?JSON.parse(r.metadata_json):{},...u};return e.prepare("INSERT INTO run_events (run_id, sequence_number, node_id, type, ts, body_json, grantee) VALUES (?, ?, ?, ?, ?, ?, ?)").run(t,a.sequence_number,n,s,a.ts,JSON.stringify(a),r.grantee),e.prepare("UPDATE nodes SET event_cursor = event_cursor + 1, last_activity_at = ? WHERE node_id = ?").run(a.ts,t),queueMicrotask(()=>{for(const E of i.get(t)??[])E()}),a}o(p,"appendRunEvent");function l(e,t,n,s={}){return _(u=>p(u,e,t,n,s))}o(l,"emitRunEvent");function d(e,t,n,s){_(u=>{u.prepare("SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND type = ? AND json_extract(body_json, '$.outcome.revision') = ? LIMIT 1").get(e,t,n,s.outcome.revision)||p(u,e,t,n,s)})}o(d,"emitRunSettlement");function b(e,t=0){S(e);const n=R(),s=n.prepare("SELECT event_cursor FROM nodes WHERE node_id = ? AND run_id = ?").get(e,e);if(!s)throw new Error(`run not found: ${e}`);const u=n.prepare("SELECT MIN(sequence_number) AS sequence FROM run_events WHERE run_id = ?").get(e),r=n.prepare("SELECT COUNT(*) AS count, COALESCE(SUM(LENGTH(body_json)), 0) AS bytes FROM run_events WHERE run_id = ? AND sequence_number > ?").get(e,t);return{events:(r.count>1e3||r.bytes>32*1024*1024?[]:n.prepare("SELECT body_json FROM run_events WHERE run_id = ? AND sequence_number > ? ORDER BY sequence_number LIMIT 1000").all(e,t)).map(E=>JSON.parse(E.body_json)),earliest_sequence:u.sequence,latest_sequence:s.event_cursor-1,backlog_count:r.count,backlog_bytes:r.bytes}}o(b,"readRunEvents");function T(e,t){let n=i.get(e);return n||(n=new Set,i.set(e,n)),n.add(t),()=>{n.delete(t),n.size===0&&i.delete(e)}}o(T,"subscribeRunEvents");function N(e){queueMicrotask(()=>{for(const t of i.get(e)??[])t()})}o(N,"notifyRunDeleted");function O(e){return Number(e.prepare("UPDATE run_events SET grantee = 'app:terminal' WHERE grantee = 'user:local'").run().changes)}o(O,"rewriteLocalRunEventGrantee");function D(e){_(t=>{t.prepare("DELETE FROM run_events WHERE ts < ?").run(new Date(e-720*60*60*1e3).toISOString())})}o(D,"expireRunEvents");const c=new Map;function M(e,t){let n=c.get(e);return n||(n=new Set,c.set(e,n)),n.add(t),()=>{n.delete(t),n.size===0&&c.delete(e)}}o(M,"registerGrantStream");function w(e){const t=[...c.get(e)??[]];for(const n of t)n();return t.length}o(w,"closeGrantStreams");export{p as appendRunEvent,w as closeGrantStreams,l as emitRunEvent,d as emitRunSettlement,D as expireRunEvents,N as notifyRunDeleted,b as readRunEvents,M as registerGrantStream,O as rewriteLocalRunEventGrantee,T as subscribeRunEvents};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
var ae=Object.defineProperty;var p=(e,t)=>ae(e,"name",{value:t,configurable:!0});import{createHash as
|
|
1
|
+
var ae=Object.defineProperty;var p=(e,t)=>ae(e,"name",{value:t,configurable:!0});import{createHash as de}from"node:crypto";import{SessionManager as ce}from"@earendil-works/pi-coding-agent";import{covers as M}from"@north-light/crouter-identity";import{openDb as ue,withCanvasWrite as W}from"../canvas/db.js";import{deleteNodeWithOwned as me}from"../graph/deletion.js";import{getById as pe}from"../graph/objects.js";import{repairRunConversations as H}from"../canvas/sessions.js";import{getNode as h,nodeFiles as le,removeNodeFiles as _e,updateNode as fe}from"../canvas/canvas.js";import{fullName as Ee}from"../canvas/labels.js";import{renameWindow as ge}from"../runtime/placement.js";import{liveExecutionForNode as q}from"../canvas/executions.js";import{conversationStore as U,isConversationNotFound as we}from"../conversation-store/index.js";import{enqueueNodeMail as ye}from"../feed/messages.js";import{newestReportBody as Re}from"../feed/reports.js";import{ensureAppProfile as he,loadExactProfileManifest as Se}from"../profiles/manifest.js";import{stopNodeSandboxes as B}from"../spaces/stop.js";import{BrokerUnreachableError as Ne}from"../runtime/broker-request.js";import{interruptLive as ve}from"../runtime/interactive-deliver.js";import{isBrokerLive as P}from"../runtime/model-swap.js";import{newNodeId as Oe}from"../runtime/nodes.js";import{writeGoal as Te}from"../runtime/kickoff.js";import{reviveNode as $}from"../runtime/revive.js";import{spawnChildPrepared as be}from"../runtime/spawn.js";import{resolveRunKind as De}from"../runtime/launch-target.js";import{cycleAwareMessages as Ae}from"../runtime/session-cycles.js";import{originFor as j}from"../runtime/stamp/protocol.js";import{readOutputResult as Me}from"../runtime/structured-output.js";import{toRunOutcomeDTO as Le}from"../../daemon/api/map.js";import{openAssistantMessageStartSequence as Ce}from"../../daemon/runs/observer.js";import{closeNode as J}from"../runtime/close.js";import{parseScope as Ie}from"@north-light/crouter-identity";import{appendRunEvent as G,subscribeRunEvents as ke}from"./events.js";import{cancelOpenQuestions as Y,openQuestionIds as X}from"./questions.js";import{appSpace as xe}from"../layout.js";import{ensureAppSpace as Fe}from"../spaces/space.js";import{assertUploadsUsable as z,resolveStorageUrls as We}from"../storage/attachments.js";import{storageClient as He,storageConfig as qe}from"../storage/client.js";import{deleteUploadRow as Ue,insertUploadUses as Q,releaseRunUploads as Be}from"../storage/tables.js";const V=p((e,t,r)=>We(t,e,r),"defaultResolver"),Pe=3e3;function Mt(e){return Number(e.prepare("UPDATE idempotency_keys SET grantee = 'app:terminal' WHERE grantee = 'user:local'").run().changes)}p(Mt,"rewriteLocalIdempotencyGrantee");class y extends Error{static{p(this,"RunError")}status;code;param;details;scope;retryable;constructor(t,r,n,a,d,i,s=t===503){super(n),this.status=t,this.code=r,this.param=a,this.details=d,this.scope=i,this.retryable=s}}const b=p((e,t)=>new y(400,"invalid_request",e,t),"invalid"),I=p(()=>new y(404,"not_found","run not found"),"missing"),k=p(()=>({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),"usage"),S=p(()=>ue(),"db");function L(e,t,r=!1){const n=h(e);if(!n||n.parent!==null||n.run_id!==e||n.grantee!==t||!r&&n.deleting_at)throw I();return n}p(L,"ownedRun");const x=["waiting_on_user","idle","settled"];function D(e){if(e.status==="canceled"||e.status==="dead"||e.status==="done"&&e.intent!=="parked")return"settled";const t=S().prepare(`SELECT 1 FROM node_rows n WHERE n.run_id = ? AND n.status = 'active' AND
|
|
2
2
|
(n.last_settled_at IS NULL OR EXISTS (
|
|
3
3
|
SELECT 1 FROM run_events e WHERE e.run_id = ? AND e.node_id = n.node_id AND e.type = 'node.turn.started'
|
|
4
4
|
AND e.sequence_number > COALESCE((SELECT MAX(c.sequence_number) FROM run_events c
|
|
5
5
|
WHERE c.run_id = e.run_id AND c.node_id = e.node_id AND c.type = 'node.turn.completed'), 0)
|
|
6
|
-
)) LIMIT 1`).get(e.node_id,e.node_id),
|
|
6
|
+
)) LIMIT 1`).get(e.node_id,e.node_id),r=S().prepare("SELECT 1 FROM deliveries WHERE destination_kind = 'node_inbox' AND destination_id IN (SELECT node_id FROM nodes WHERE run_id = ?) AND state IN ('armed', 'pending') AND wake = 1 LIMIT 1").get(e.node_id);return t||r||!e.last_settled_at?"running":X(e.node_id).length?"waiting_on_user":"idle"}p(D,"runStatus");function A(e){H(e.node_id),e=h(e.node_id)??e;const t=D(e),r=t==="settled"?[]:X(e.node_id),n=Re(e.node_id)||void 0,a=t==="settled"?Le(e):null,d=a?.kind==="result"?Me(e.node_id,e.grantee):void 0;return{run_id:e.node_id,name:e.name,status:t,...a?{outcome:a}:{},...d===void 0?{}:{result:d},...n!==void 0?{last_report:n}:{},pending_question_ids:r,usage:JSON.parse(e.usage_json??JSON.stringify(k())),payer:"user",scopes:e.scopes,metadata:e.metadata_json?JSON.parse(e.metadata_json):{},created_at:e.created,...t==="settled"&&e.outcome_at?{settled_at:e.outcome_at}:{},latest_sequence:(e.event_cursor??1)-1,last_activity_at:e.last_activity_at}}p(A,"runObject");async function Lt(e,t,r,n=V){const a=de("sha256").update(JSON.stringify(t)).digest("hex");if(r){const c=S().prepare("SELECT body_hash, run_id, response_json, created_at FROM idempotency_keys WHERE grantee = ? AND key = ?").get(e.grantee,r);if(c&&Date.now()-Date.parse(c.created_at)<864e5){if(c.body_hash!==a)throw new y(409,"idempotency_conflict","key used with a different request");const _=L(c.run_id,e.grantee);return!_.pi_pid&&D(_)==="running"&&await $(_.node_id,{resume:!0,capacity:"freeze"}),JSON.parse(c.response_json)}}await Fe(e.grantee);const d=t.profile===void 0?he(e.grantee):Se(t.profile),i=d.manifest.grantee??"app:terminal";if(i!==e.grantee){const c=`crtr:memory:rw:${i}:profile:${d.profileId}`;if(!e.resolved.some(_=>M(_,c))||t.scopes!==null&&!t.scopes.some(_=>M(_,c)))throw new y(403,"scope_missing",`missing scope ${c}`,"profile",void 0,c)}const s=Oe(),o=await n(s,e.grantee,t.prompt),l=o.text;let E;try{await be({kind:De(d),mode:"base",root:!0,rootLifecycle:"resident",readiness:"launch",cwd:xe(e.grantee).files,profile:d.profileId,prompt:l,nodeId:s,...t.scopes===null?{}:{scopes:t.scopes},run:{grantee:e.grantee,sub:e.sub,grant_id:e.grant,client_id:e.client_id,metadata_json:JSON.stringify(t.metadata),run_id:s,event_cursor:1,usage_json:JSON.stringify(k())},withinCreate:p((c,_)=>{o.uses.length&&(z(e.grantee,o.uses,c),Q(o.uses.map(({upload_id:m,path:g})=>({upload_id:m,path:g,run_id:s})),c)),Te(s,l),E={run_id:s,node_id:s,grantee:e.grantee,grant:e.grant,rev:e.rev,scopes:t.scopes,payer:"user",status:"running",created_at:_.created,metadata:t.metadata,sequence_number:0},G(c,s,s,"run.started",{served_model:_.launch?.model??null,scopes:t.scopes,payer:"user",usage:k()}),r&&(c.prepare("DELETE FROM idempotency_keys WHERE grantee = ? AND key = ? AND created_at <= ?").run(e.grantee,r,new Date(Date.now()-864e5).toISOString()),c.prepare("INSERT INTO idempotency_keys (grantee, key, body_hash, run_id, response_json, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(e.grantee,r,a,s,JSON.stringify(E),_.created))},"withinCreate")})}catch(c){throw h(s)||o.cleanup(),c}if(!E)throw new Error("run creation did not commit");return E}p(Lt,"startRun");function Ct(e,t){let r;if(t.after)try{const s=JSON.parse(Buffer.from(t.after,"base64url").toString());if(!s||typeof s!="object"||!("activity"in s)||typeof s.activity!="string"||!("id"in s)||typeof s.id!="string")throw new Error("invalid cursor");r={activity:s.activity,id:s.id}}catch{throw b("invalid list cursor","after")}const a=S().prepare(`SELECT node_id, COALESCE(last_activity_at, created) AS activity FROM node_rows
|
|
7
7
|
WHERE run_id = node_id AND deleting_at IS NULL ${e===null?"":"AND grantee = ?"}
|
|
8
|
-
ORDER BY activity DESC, node_id DESC`).all(...e===null?[]:[e]).filter(({activity:
|
|
8
|
+
ORDER BY activity DESC, node_id DESC`).all(...e===null?[]:[e]).filter(({activity:s,node_id:o})=>!r||s<r.activity||s===r.activity&&o<r.id).map(s=>({root:h(s.node_id),activity:s.activity})).filter(({root:s})=>!t.status||D(s)===t.status),d=a.slice(0,t.limit),i=d.at(-1);return{runs:d.map(({root:s})=>A(s)),next:a.length>t.limit&&i?Buffer.from(JSON.stringify({activity:i.activity,id:i.root.node_id})).toString("base64url"):null}}p(Ct,"listRuns");async function It(e,t,r){const n=L(e,t),a=p(()=>A(L(e,t)),"read");return!r||x.includes(D(n))?a():new Promise((d,i)=>{const s=p(()=>{clearTimeout(E),clearInterval(l),o();try{d(a())}catch(c){i(c)}},"finish"),o=ke(e,()=>{try{x.includes(String(a().status))&&s()}catch(c){clearTimeout(E),clearInterval(l),o(),i(c)}}),l=setInterval(()=>{x.includes(String(a().status))&&s()},250),E=setTimeout(s,r*1e3)})}p(It,"waitRun");async function kt(e,t,r=V){if(e.status==="canceled"||e.outcome_reason==="closed")throw new y(409,"run_settled","canceled run cannot receive a message");const n=e.grantee??"app:terminal",a=await r(e.node_id,n,t),d=a.text;let i;try{if(e.final_report&&!e.pi_pid){const{commitReopenResident:o}=await import("../runtime/reopen.js");o(e.node_id)}i=ye(e.node_id,{kind:"message",label:d.slice(0,120),senderNodeId:"human",bodyJson:{body:d},urgency:"normal",wake:1,withinEnqueue:p((o,l)=>{a.uses.length&&(z(n,a.uses,o),Q(a.uses.map(({upload_id:E,path:c})=>({upload_id:E,path:c,run_id:e.node_id})),o)),G(o,e.node_id,e.node_id,"node.message.accepted",{message_id:l})},"withinEnqueue")})}catch(o){throw a.cleanup(),o}const s=S().prepare("SELECT event_cursor FROM nodes WHERE node_id = ?").get(e.node_id).event_cursor-1;return e.pi_pid||await $(e.node_id,{resume:!0,capacity:"freeze"}),{run_id:e.node_id,message_id:i.messageId,sequence_number:s}}p(kt,"messageRun");async function $e(e){const t=p(()=>new y(503,"server_error",`node ${e} broker was unavailable before the interrupt reached it`),"unavailable");for(let r=0;r<2;r++){const n=h(e);if(!n)throw I();if(!P(n)){if(n.streaming)throw t();return}const a=q(e)?.executionId;try{await ve(e);return}catch(d){if(!(d instanceof Ne))throw d;const i=h(e);if(!i)throw I();if(!i.streaming)return;if(r===0&&P(i)&&q(e)?.executionId!==a)continue;throw t()}}throw t()}p($e,"interruptNode");async function xt(e,t="stop"){const r=t==="stop"?S().prepare("SELECT node_id FROM nodes WHERE run_id = ?").all(e.node_id).map(({node_id:n})=>n):[e.node_id];return await Promise.all(r.map(n=>$e(n))),A(h(e.node_id)??e)}p(xt,"interruptRun");async function Ft(e,t={}){const r=S().prepare("SELECT node_id FROM nodes WHERE run_id = ? ORDER BY created DESC").all(e.node_id).map(i=>i.node_id),n=[];if(D(e)!=="settled")n.push(...J(e.node_id,{preserveEmpty:!0,stopReason:"run_canceled"}).closed);else for(const i of r){if(i===e.node_id)continue;const s=h(i);s&&s.status!=="done"&&s.status!=="canceled"&&s.status!=="dead"&&n.push(...J(i,{preserveEmpty:!0,stopReason:"run_canceled"}).closed)}if(await Y({run_id:e.node_id},"the run was canceled"),(await Promise.all([...new Set([e.node_id,...n])].map(i=>B(i,"run_canceled")))).some(i=>!i.confirmed))throw new y(500,"server_error","run process teardown could not be confirmed",void 0,void 0,void 0,!0);const d=h(e.node_id);return A(d??e)}p(Ft,"cancelRun");const Z=200;function Wt(e,t){if(typeof t!="string"||!t.trim())throw b("name is required","name");const r=t.trim();if(r.length>Z)throw b(`name exceeds ${Z} characters`,"name");const n=fe(e.node_id,{name:r});return n.window&&ge(n.window,Ee(n)),A(n)}p(Wt,"renameRun");async function Ht(e,t={config:qe,client:He}){await Y({run_id:e.node_id},"the run was deleted");const r=W(o=>(o.prepare("UPDATE nodes SET deleting_at = COALESCE(deleting_at, ?) WHERE node_id = ?").run(new Date().toISOString(),e.node_id),o.prepare("SELECT node_id FROM nodes WHERE run_id = ? ORDER BY created DESC").all(e.node_id).map(l=>l.node_id)));if((await Promise.all(r.map(o=>B(o,"run_deleted",{deleting:!0})))).some(o=>!o.confirmed))throw new y(500,"server_error","run process teardown could not be confirmed",void 0,void 0,void 0,!0);const a=r.map(o=>{const l=le(o);if(l.app===null)throw new Error(`run node missing during deletion: ${o}`);return l}),d=S().prepare("SELECT DISTINCT session_id FROM sessions WHERE session_id IS NOT NULL AND node_id IN (SELECT node_id FROM nodes WHERE run_id = ?)").all(e.node_id);for(const{session_id:o}of d)try{U().delete(o)}catch(l){if(!we(l))throw l}const i=W(o=>{for(const _ of r){const m=pe(o,_);m!==null&&m.deleted_at===null&&me(o,m)}const l=Be([e.node_id],o);o.prepare("DELETE FROM run_events WHERE run_id = ?").run(e.node_id),o.prepare("DELETE FROM idempotency_keys WHERE run_id = ?").run(e.node_id);const E=r.map(()=>"?").join(","),c=o.prepare(`SELECT message_id FROM messages WHERE sender_node_id IN (${E}) UNION SELECT message_id FROM deliveries WHERE destination_kind = 'node_inbox' AND destination_id IN (${E})`).all(...r,...r);o.prepare(`DELETE FROM deliveries WHERE destination_kind = 'node_inbox' AND destination_id IN (${E})`).run(...r);for(const{message_id:_}of c)o.prepare("DELETE FROM messages WHERE message_id = ? AND NOT EXISTS (SELECT 1 FROM deliveries WHERE message_id = ?)").run(_,_);return l});for(const o of a)_e(o);const{notifyRunDeleted:s}=await import("./events.js");return s(e.node_id),{uploads_pending:await je(i,t)}}p(Ht,"deleteRun");async function je(e,t){if(!e.length||!t.config())return e.length;let r;try{r=t.client()}catch{return e.length}const n=new Set,a=e.map(i=>r.deleteUpload(i).then(()=>{Ue(i),n.add(i)},()=>{}));let d;return await Promise.race([Promise.all(a),new Promise(i=>{d=setTimeout(i,t.budgetMs??Pe),d.unref?.()})]),clearTimeout(d),e.length-n.size}p(je,"deleteReleasedUploads");function qt(e,t,r){L(e,t),H(e);const n=S();n.exec("BEGIN");try{const d=n.prepare("SELECT node_id, parent FROM nodes WHERE run_id = ? ORDER BY CASE WHEN node_id = ? THEN 0 ELSE 1 END, created, node_id").all(e,e).map(m=>({node_id:m.node_id,parent_node_id:m.parent,conversations:n.prepare("SELECT DISTINCT session_id FROM sessions WHERE node_id = ? ORDER BY created_at").all(m.node_id).map(({session_id:g})=>{const{header:v,entries:w}=U().read(g);if(r==="entries")return{conversation_id:g,header:v,entries:w};const K=ce.inMemory(v.cwd,void 0,[v,...w]),ee=Ae(K)??[],F=new Map(w.map((f,N)=>[f.id,N])),te=w.filter(f=>f.type==="custom"&&f.customType==="crtr-system-prompt").map(f=>({id:f.id,message:{role:"custom",customType:"crtr-system-prompt",data:"data"in f?f.data:void 0,timestamp:f.timestamp}})),ne=m.node_id===e?w.find(f=>{if(f.type!=="message"||f.message.role!=="user")return!1;const N=j(w,f.message.timestamp);return N?.type==="runtime"&&N.kind==="kickoff"})?.id:void 0,re=[...ee,...te].sort((f,N)=>(F.get(f.id)??Number.MAX_SAFE_INTEGER)-(F.get(N.id)??Number.MAX_SAFE_INTEGER)).map(({id:f,message:N})=>{const u=N,O=u.usage,C=u.role==="user"?j(w,Number(u.timestamp)):null,se=C?.type==="human"||f===ne,T=u.role==="toolResult"?"tool_result":u.role==="bashExecution"?"bash_execution":u.role==="compactionSummary"?"compaction_summary":u.role==="branchSummary"?"branch_summary":u.role==="custom"&&u.customType==="crtr-system-prompt"?"system":u.role==="user"?se?"user":"custom":u.role,oe=T==="custom"?u.role==="custom"?u.customType:C?.type==="runtime"?C.kind:"unknown":void 0,ie=T==="system"&&u.customType==="crtr-system-prompt"?[{type:"text",text:u.data?.text??""}]:typeof u.content=="string"?[{type:"text",text:u.content}]:Array.isArray(u.content)?u.content.map(R=>R.type==="toolCall"?{type:"tool_call",tool_call_id:R.id,name:R.name,arguments:R.arguments}:R.type==="image"?{type:"image",mime_type:R.mimeType}:R.type==="thinking"?{type:"thinking",text:R.thinking}:R):[];return{entry_id:f,role:T,...T==="custom"?{custom_type:oe}:{},time:typeof u.timestamp=="string"?u.timestamp:new Date(Number(u.timestamp??Date.now())).toISOString(),content:ie,...T==="assistant"?{model:u.model,provider:u.provider,stop_reason:u.stopReason,...u.errorMessage?{error_message:u.errorMessage}:{},...O?{usage:{input_tokens:O.input??0,output_tokens:O.output??0,cache_read_tokens:O.cacheRead??0,cache_write_tokens:O.cacheWrite??0,cost_usd:O.cost?.total??0}}:{}}:{},...T==="tool_result"?{tool_call_id:u.toolCallId,tool_name:u.toolName,is_error:u.isError}:{}}})??[];return{conversation_id:g,messages:re}})})),s=n.prepare("SELECT event_cursor FROM nodes WHERE node_id = ?").get(e).event_cursor-1,o=new Map(d.map(m=>[m.node_id,Ce(m.node_id)])),l=n.prepare(`SELECT node_id, sequence_number FROM run_events
|
|
9
9
|
WHERE run_id = ? AND sequence_number <= ? AND type IN ('node.thinking.done', 'node.output_text.done', 'usage')
|
|
10
|
-
ORDER BY sequence_number`).all(e,
|
|
10
|
+
ORDER BY sequence_number`).all(e,s);for(const m of l){const g=o.get(m.node_id);g!=null&&m.sequence_number>=g&&o.set(m.node_id,null)}const E=n.prepare(`SELECT node_id, sequence_number, type, body_json FROM run_events
|
|
11
11
|
WHERE run_id = ? AND sequence_number <= ? AND type IN ('node.thinking.delta', 'node.output_text.delta')
|
|
12
|
-
ORDER BY sequence_number`).all(e,
|
|
12
|
+
ORDER BY sequence_number`).all(e,s),c=new Map;for(const m of E){const g=o.get(m.node_id);if(g==null||m.sequence_number<g)continue;const v=JSON.parse(m.body_json),w=c.get(m.node_id)??{thinking:"",text:""};m.type==="node.thinking.delta"?w.thinking+=v.delta:w.text+=v.delta,c.set(m.node_id,w)}const _=d.map(m=>({...m,in_progress_message:o.get(m.node_id)==null?null:c.get(m.node_id)??{thinking:"",text:""}}));return n.exec("COMMIT"),{run_id:e,latest_sequence:s,nodes:_}}catch(a){throw n.exec("ROLLBACK"),a}}p(qt,"traceRun");function Ut(e,t,r){if(t===void 0){if(!e.some(n=>M(n,"crtr:llm")))throw new y(403,"scope_missing","missing scope crtr:llm",void 0,void 0,"crtr:llm");return null}if(!Array.isArray(t)||t.some(n=>typeof n!="string"))throw b("scopes must be a list of scope strings","scopes");for(const n of t){try{Ie(n)}catch{throw b(`invalid scope ${n}`,"scopes")}if(/^crtr:files:(?:read|rw):app:/.test(n)&&n.split(":")[4]===r.slice(4))throw b(`own-app files cannot narrow a run: ${n}`,"scopes");if(!(/^crtr:memory:(?:read|rw):app:/.test(n)&&n.split(":")[4]===r.slice(4))&&!e.some(d=>M(d,n)))throw new y(403,"scope_missing",`missing scope ${n}`,void 0,void 0,n)}if(!t.includes("crtr:llm"))throw new y(403,"scope_missing","missing scope crtr:llm",void 0,void 0,"crtr:llm");return t}p(Ut,"requestedScopes");export{Pe as RUN_DELETE_STORAGE_BUDGET_MS,Z as RUN_NAME_MAX,y as RunError,Ft as cancelRun,Ht as deleteRun,xt as interruptRun,Ct as listRuns,kt as messageRun,L as ownedRun,Wt as renameRun,Ut as requestedScopes,Mt as rewriteLocalIdempotencyGrantee,A as runObject,Lt as startRun,qt as traceRun,It as waitRun};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var p=Object.defineProperty;var i=(n,e)=>p(n,"name",{value:e,configurable:!0});import{openDb as o}from"../canvas/db.js";import{getRequest as
|
|
1
|
+
var p=Object.defineProperty;var i=(n,e)=>p(n,"name",{value:e,configurable:!0});import{openDb as o}from"../canvas/db.js";import{getRequest as _}from"../human/requests.js";import{appendRunEvent as d}from"./events.js";function c(n,e){return e===null?null:n.prepare("SELECT node_id, run_id, grantee FROM node_rows WHERE node_id = ? AND run_id IS NOT NULL").get(e)??null}i(c,"askingNode");function f(n){return JSON.parse(n.specification_json)}i(f,"manifestOf");function s(n,e=o()){return n.kind!=="page"||!n.settleable?null:c(e,n.requester_node_id)}i(s,"questionRun");function a(n,e){const t=f(n);return{question_id:n.request_id,initiating_app:e.grantee,title:n.title,...n.subtitle?{subtitle:n.subtitle}:{},steps:t.steps,slots:t.slots.map(r=>({...r.id===void 0?{}:{id:r.id},kind:r.kind,step:r.step,config:r.config}))}}i(a,"questionFields");function x(n,e){const t=s(e,n);t===null||e.state!=="open"||d(n,t.run_id,t.node_id,"waiting_on_user",a(e,t))}i(x,"appendWaitingOnUser");function D(n,e){if(e.outcome!=="answered"||e.result_json===null)return;const t=s(e,n);if(t===null)return;const r=JSON.parse(e.result_json);d(n,t.run_id,t.node_id,"question.answered",{question_id:e.request_id,answer:r.responses??{}})}i(D,"appendQuestionAnswered");function A(n,e=o()){return e.prepare(`SELECT h.request_id FROM human_requests h JOIN node_rows n ON n.node_id = h.requester_node_id
|
|
2
2
|
WHERE n.run_id = ? AND h.kind = 'page' AND h.state = 'open' AND h.settleable = 1
|
|
3
|
-
ORDER BY h.created_at, h.request_id`).all(n).map(t=>t.request_id)}i(A,"openQuestionIds");function N(n){return n.state!=="settled"?"open":n.outcome==="answered"?"answered":"canceled"}i(N,"questionStatus");function m(n){if(n.result_json===null)return null;const e=JSON.parse(n.result_json);return n.outcome==="answered"?e.responses??{}:e}i(m,"questionResult");function S(n,e){const t=N(n);return{...a(n,e),run_id:e.run_id,node_id:e.node_id,status:t,...t==="answered"?{answer:m(n)}:{}}}i(S,"questionObject");function k(n){const e=
|
|
3
|
+
ORDER BY h.created_at, h.request_id`).all(n).map(t=>t.request_id)}i(A,"openQuestionIds");function N(n){return n.state!=="settled"?"open":n.outcome==="answered"?"answered":"canceled"}i(N,"questionStatus");function m(n){if(n.result_json===null)return null;const e=JSON.parse(n.result_json);return n.outcome==="answered"?e.responses??{}:e}i(m,"questionResult");function S(n,e){const t=N(n);return{...a(n,e),run_id:e.run_id,node_id:e.node_id,status:t,...t==="answered"?{answer:m(n)}:{}}}i(S,"questionObject");function k(n){const e=_(n);if(e===null)return null;const t=s(e);return t===null?null:{request:e,run:t}}i(k,"getQuestion");function h(n){const[e,t]="run_id"in n?["n.run_id = ?",n.run_id]:"node_id"in n?["n.node_id = ?",n.node_id]:["n.grantee = ?",n.grantee];return o().prepare(`SELECT h.request_id FROM human_requests h JOIN node_rows n ON n.node_id = h.requester_node_id
|
|
4
4
|
WHERE ${e} AND n.run_id IS NOT NULL AND h.kind = 'page' AND h.state = 'open' AND h.settleable = 1`).all(t).map(r=>r.request_id)}i(h,"openQuestionIdsFor");async function L(n,e){const t=h(n);if(!t.length)return 0;const{cancelHumanTicket:r}=await import("../../daemon/human/finish.js");let u=0;for(const l of t)(await r(l,{reason:e,actor:"crtrd"})).outcome==="settled"&&(u+=1);return u}i(L,"cancelOpenQuestions");export{D as appendQuestionAnswered,x as appendWaitingOnUser,L as cancelOpenQuestions,k as getQuestion,A as openQuestionIds,h as openQuestionIdsFor,S as questionObject,m as questionResult,s as questionRun,N as questionStatus};
|
|
@@ -7,9 +7,11 @@ export declare function escapeAttribute(value: string): string;
|
|
|
7
7
|
* document substrate, so this wrapper stays environment-only. It always emits
|
|
8
8
|
* because the environment snapshot is always present. */
|
|
9
9
|
export declare function buildProjectContextBlock(cwd: string): string;
|
|
10
|
-
/** The context-directory note —
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
/** The documents-and-context-directory note — says where documents written for
|
|
11
|
+
* another reader live (canvas documents the node owns, pointed at by name) and
|
|
12
|
+
* names the context directory path INLINE (no XML attribute, so it never scopes
|
|
13
|
+
* a sibling block) as the place for files that are not documents. Present for
|
|
14
|
+
* every node, rendered as the `## Your documents and context directory`
|
|
13
15
|
* subsection of <crtr-bearings>. */
|
|
14
16
|
export declare function contextDirNote(nodeId: string, grantee?: string): string;
|
|
15
17
|
/** The profile-purview note — rendered ONLY when the profile resolves to a
|
|
@@ -22,10 +24,14 @@ export declare function contextDirNote(nodeId: string, grantee?: string): string
|
|
|
22
24
|
* purview, not a redacted count. */
|
|
23
25
|
export declare function profileNote(cwd: string, profileId: string | null | undefined): string;
|
|
24
26
|
/** Orchestrator-only framing: a resident orchestrator survives refresh cycles,
|
|
25
|
-
* so
|
|
26
|
-
* Used inside the bearings block AND in the promotion
|
|
27
|
-
* promoted node gets the same note a born-orchestrator gets. */
|
|
28
|
-
export declare function orchestratorContextNote(
|
|
27
|
+
* so the documents it owns are also where a future cycle of itself resumes the
|
|
28
|
+
* work. Used inside the bearings block (both lanes) AND in the promotion
|
|
29
|
+
* guidance, so a promoted node gets the same note a born-orchestrator gets. */
|
|
30
|
+
export declare function orchestratorContextNote(): string;
|
|
31
|
+
/** The fork's context note: the fork's own context directory replaces the
|
|
32
|
+
* source's for files, and the source's documents stay the source's — a bare
|
|
33
|
+
* document name in the copied conversation now needs the source's prefix. */
|
|
34
|
+
export declare function forkContextNote(nodeId: string, grantee: string | undefined, sourceId: string): string;
|
|
29
35
|
export interface RelativeLabelNode extends NamedNode {
|
|
30
36
|
node_id: string;
|
|
31
37
|
kind: string;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
var b=Object.defineProperty;var s=(e,t)=>b(e,"name",{value:t,configurable:!0});import{contextDir as
|
|
2
|
-
`).filter(c=>c!=="").length,i=
|
|
3
|
-
`),a=
|
|
1
|
+
var b=Object.defineProperty;var s=(e,t)=>b(e,"name",{value:t,configurable:!0});import{contextDir as m}from"../canvas/paths.js";import{fullName as w}from"../canvas/labels.js";import{tmuxSessionsReachable as v}from"./tmux-driver.js";import{spawnSync as x}from"node:child_process";import{readdirBeneath as k}from"../spaces/open-beneath.js";import{hostname as _}from"node:os";import{loadProfileManifest as C}from"../profiles/manifest.js";function D(e){return e.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<").replaceAll(">",">")}s(D,"escapeAttribute");function N(){const e=v();return`Host: ${[`${process.platform} ${process.arch}`,_(),`node ${process.version}`,`tmux server: ${e?"reachable":"none"}`].join(" \xB7 ")}`}s(N,"runtimeLine");function T(e){try{const n=k("/",e).sort((i,a)=>i.isDirectory()!==a.isDirectory()?i.isDirectory()?-1:1:i.name.localeCompare(a.name)),r=n.slice(0,50).map(i=>`${i.name}${i.isDirectory()?"/":""}`),o=n.length-r.length;return o>0?[...r,`[+${o} more]`]:r}catch{return["Directory listing: unavailable (cwd missing or unreadable)."]}}s(T,"directoryListingLines");function f(e,t,n,r){const o=x(t,n,{cwd:e,encoding:"utf8",...r===void 0?{}:{env:r}});return o.error!==void 0?{ok:!1,stdout:"",stderr:o.error.message}:{ok:o.status===0,stdout:(o.stdout??"").trim(),stderr:(o.stderr??"").trim()}}s(f,"runCommand");function $(){const e={...process.env,GIT_OPTIONAL_LOCKS:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_GLOBAL:"/dev/null"};return delete e.GIT_CONFIG_PARAMETERS,delete e.GIT_CONFIG_COUNT,e}s($,"gitEnv");function d(e,t){const n=f(e,"git",t,$());return n.ok?n.stdout:""}s(d,"runGit");function A(e){const t=[];let n={};for(const r of e)r.startsWith("worktree ")?(n.path!==void 0&&t.push({path:n.path,branch:n.branch??"detached HEAD"}),n={path:r.slice(9)}):r.startsWith("branch ")&&(n.branch=r.slice(7).replace(/^refs\/heads\//,""));return n.path!==void 0&&t.push({path:n.path,branch:n.branch??"detached HEAD"}),t}s(A,"parseWorktrees");function G(e){const t=f(e,"git",["rev-parse","--is-inside-work-tree"],$());if(!t.ok)return/not a git repository/i.test(t.stderr)?["Git: not a git repository."]:[`Git: unavailable (${t.stderr||"git command failed"}).`];const n=d(e,["branch","--show-current"])||d(e,["rev-parse","--abbrev-ref","HEAD"])||"HEAD",r=d(e,["rev-parse","--short","HEAD"])||"unknown",o=d(e,["status","--porcelain"]).split(`
|
|
2
|
+
`).filter(c=>c!=="").length,i=d(e,["worktree","list","--porcelain"]).split(`
|
|
3
|
+
`),a=A(i),u=o===0?"clean":`${o} uncommitted change${o===1?"":"s"}`,h=`Git: ${n} @ ${r}; ${u}; ${a.length} worktree${a.length===1?"":"s"}.`,l=a.length===0?"Worktrees: none.":`Worktrees: ${a.map(c=>`${c.path} (${c.branch})`).join(", ")}`;return[h,l]}s(G,"gitSnapshotLines");function B(e){const t=T(e),n=G(e);let r=`<project_context>
|
|
4
4
|
|
|
5
|
-
`;return
|
|
6
|
-
`,
|
|
7
|
-
`,
|
|
5
|
+
`;return r+=`<environment cwd="${D(e)}">
|
|
6
|
+
`,r+=`${N()}
|
|
7
|
+
`,r+=`Directory:
|
|
8
8
|
${t.map(o=>` ${o}`).join(`
|
|
9
9
|
`)}
|
|
10
|
-
`,
|
|
10
|
+
`,r+=`${n.map(o=>`${o}`).join(`
|
|
11
11
|
`)}
|
|
12
|
-
`,
|
|
13
|
-
</project_context>`,
|
|
14
|
-
`)}s(
|
|
15
|
-
`)}s(
|
|
12
|
+
`,r+=`</environment>
|
|
13
|
+
</project_context>`,r}s(B,"buildProjectContextBlock");function W(e,t){return`Documents you write for another reader \u2014 specs, designs, findings, maps, plans \u2014 are canvas documents you own: write one with \`crtr doc write <name>\` (see \`crtr doc write -h\`), and point at it by the name it prints, \`[[${e}/<name>]]\`, never by a file path; other nodes read it with \`crtr canvas read\`, and inside this node the bare name resolves too. Your context directory \`${m(e,t)}\` (also \`$CRTR_CONTEXT_DIR\`) holds only what is not a document: scripts, data, logs and page modules. Your working dir is the project, NOT this directory, so a bare relative \`context/...\` lands in the repo, not here.`}s(W,"contextDirNote");function P(e,t){if(t==null||t==="")return"";let n;try{n=C(t)}catch{return""}const r=n.manifest.projects.map(o=>o.path);return r.length===0?"":`Your working dir is \`${e}\`. Your profile **${n.manifest.name}** also has purview over: ${r.join(", ")}.`}s(P,"profileNote");function M(){return"Because you persist across refresh cycles, the documents you own are also where a future cycle of you resumes the work: your document `roadmap` loads at every new session, and it points at the documents holding the decisions and findings a refreshed you would need, alongside the ones you share with the nodes you spawn."}s(M,"orchestratorContextNote");function F(e,t,n){return`Context directory: \`${m(e,t)}\` (\`$CRTR_CONTEXT_DIR\`), for files only; use it in place of every source-node context path above. Documents you write are yours. The source node's documents stay the source's: read them as \`[[${n}/<name>]]\`, and a bare document name in the copied conversation that meant one of them now needs that prefix.`}s(F,"forkContextNote");function y(e){const t=w(e),n=t!==""&&t!==e.kind&&t!==e.name?` \u2014 ${t}`:"";return`${e.node_id} (${e.kind} \xB7 ${e.status})${n}`}s(y,"relativeLabel");const O=5;function X(e,t,n,r,o){if(r.length===0&&o.length===0)return"";const i=s(c=>" ".repeat(c),"indent"),a=["Your place in the canvas graph (ancestry above you, your direct children below):"];r.forEach((c,p)=>{a.push(`${i(p)}${p===0?"":"\u2514 "}${y(c)}`)});const u=r.length;a.push(`${i(u)}${u===0?"":"\u2514 "}\u25CF you: ${e} (${t}, ${n})`);const h=o.slice(0,O),l=o.length-h.length;return h.forEach((c,p)=>{const g=p===h.length-1&&l===0;a.push(`${i(u+1)}${g?"\u2514 ":"\u251C "}${y(c)}`)}),l>0&&a.push(`${i(u+1)}\u2514 +${l} more`),a.join(`
|
|
14
|
+
`)}s(X,"renderGraphMap");function z(e,t,n,r,o){const i=[`You are node ${e} \u2014 kind ${t}, mode ${n}.`];return r!=null&&r!==""&&i.push("",`You are a new FORK of ${o}, not ${o}. Pi copied the earlier conversation into this session. Treat that first-person history as reference material, not your own past.`),i.join(`
|
|
15
|
+
`)}s(z,"buildIdentityAssertion");function K(e){return e?.state!=="open"?"":`Branch: \`${e.branch}\`
|
|
16
16
|
Worktree: \`${e.path}\`
|
|
17
17
|
Base: \`${e.base_ref}\` @ \`${e.base_sha}\`
|
|
18
|
-
Commit work here. Before finishing, land it with \`crtr node worktree close\` or keep the checkout and branch when the worktree is clean and its exact tip exists on any branch on origin. Auto-drop applies only when the worktree is clean (no uncommitted changes) and nothing remains to land (zero commits ahead of the base, or its commits are already contained in the base); otherwise, unlanded commits or uncommitted changes block finalization.`}s(
|
|
18
|
+
Commit work here. Before finishing, land it with \`crtr node worktree close\` or keep the checkout and branch when the worktree is clean and its exact tip exists on any branch on origin. Auto-drop applies only when the worktree is clean (no uncommitted changes) and nothing remains to land (zero commits ahead of the base, or its commits are already contained in the base); otherwise, unlanded commits or uncommitted changes block finalization.`}s(K,"worktreeNote");export{z as buildIdentityAssertion,B as buildProjectContextBlock,W as contextDirNote,D as escapeAttribute,F as forkContextNote,M as orchestratorContextNote,P as profileNote,y as relativeLabel,X as renderGraphMap,K as worktreeNote};
|