@north-light/cli 0.3.530 → 0.3.532
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/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/viewer.js +508 -508
- package/dist/core/async-array.d.ts +7 -0
- package/dist/core/async-array.js +1 -0
- package/dist/core/audit.d.ts +1 -1
- package/dist/core/audit.js +2 -2
- package/dist/core/canvas/attention.d.ts +4 -4
- package/dist/core/canvas/attention.js +1 -1
- package/dist/core/canvas/boot.d.ts +4 -4
- package/dist/core/canvas/boot.js +1 -1
- package/dist/core/canvas/canvas.d.ts +59 -59
- package/dist/core/canvas/canvas.js +19 -19
- package/dist/core/canvas/context-strip.js +2 -2
- package/dist/core/canvas/crons.d.ts +27 -27
- package/dist/core/canvas/crons.js +11 -11
- package/dist/core/canvas/daemon-actions.d.ts +10 -10
- package/dist/core/canvas/daemon-actions.js +8 -8
- package/dist/core/canvas/daemon-owner.d.ts +3 -3
- package/dist/core/canvas/daemon-owner.js +2 -2
- package/dist/core/canvas/db.d.ts +19 -30
- package/dist/core/canvas/db.js +3 -2
- package/dist/core/canvas/deliveries.d.ts +16 -16
- package/dist/core/canvas/deliveries.js +24 -24
- package/dist/core/canvas/executions.d.ts +8 -8
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/focuses.d.ts +8 -8
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.d.ts +3 -3
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/install-id.d.ts +1 -1
- package/dist/core/canvas/install-id.js +1 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
- package/dist/core/canvas/memory-reads.d.ts +6 -6
- package/dist/core/canvas/memory-reads.js +1 -1
- package/dist/core/canvas/nav-model.d.ts +13 -13
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/node-agent-paths.d.ts +6 -6
- package/dist/core/canvas/node-agent-paths.js +1 -1
- package/dist/core/canvas/node-tokens.d.ts +7 -7
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/outcome-actions.d.ts +5 -5
- package/dist/core/canvas/outcome-actions.js +3 -3
- package/dist/core/canvas/recovery.d.ts +26 -26
- package/dist/core/canvas/recovery.js +2 -2
- package/dist/core/canvas/render-source.d.ts +1 -1
- package/dist/core/canvas/render-source.js +1 -1
- package/dist/core/canvas/sessions.d.ts +10 -10
- package/dist/core/canvas/sessions.js +4 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/structured-requests.d.ts +15 -15
- package/dist/core/canvas/structured-requests.js +5 -5
- package/dist/core/canvas/tree.d.ts +9 -9
- package/dist/core/canvas/tree.js +5 -5
- package/dist/core/canvas/waits.d.ts +13 -13
- package/dist/core/canvas/waits.js +6 -6
- package/dist/core/canvas/worktrees.d.ts +15 -15
- package/dist/core/canvas/worktrees.js +1 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/conversation-store/file-store.d.ts +7 -7
- package/dist/core/conversation-store/file-store.js +9 -9
- package/dist/core/conversation-store/index.d.ts +16 -14
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/listener.js +5 -5
- package/dist/core/conversation-store/patch.d.ts +3 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/feed/feed.js +3 -3
- package/dist/core/feed/inbox.d.ts +2 -2
- package/dist/core/feed/inbox.js +1 -1
- package/dist/core/feed/messages.d.ts +11 -12
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/feed/reports.d.ts +4 -4
- package/dist/core/feed/reports.js +2 -2
- package/dist/core/grants/cover.d.ts +1 -1
- package/dist/core/grants/cover.js +1 -1
- package/dist/core/grants/local.d.ts +1 -1
- package/dist/core/grants/local.js +1 -1
- package/dist/core/grants/mirror.d.ts +19 -19
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/grants/on-sync.d.ts +1 -1
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/graph/access.d.ts +17 -17
- package/dist/core/graph/access.js +3 -3
- package/dist/core/graph/custom.d.ts +16 -16
- package/dist/core/graph/custom.js +9 -9
- package/dist/core/graph/deletion.d.ts +3 -7
- package/dist/core/graph/deletion.js +4 -4
- package/dist/core/graph/documents.d.ts +24 -27
- package/dist/core/graph/documents.js +7 -7
- package/dist/core/graph/edges.d.ts +13 -13
- package/dist/core/graph/edges.js +1 -1
- package/dist/core/graph/events.d.ts +7 -9
- package/dist/core/graph/events.js +8 -8
- package/dist/core/graph/exposures.d.ts +6 -6
- package/dist/core/graph/exposures.js +4 -4
- package/dist/core/graph/jobs.d.ts +6 -8
- package/dist/core/graph/jobs.js +2 -2
- package/dist/core/graph/kinds/action.js +1 -1
- package/dist/core/graph/kinds/custom.js +2 -2
- package/dist/core/graph/kinds/document.d.ts +1 -0
- package/dist/core/graph/kinds/document.js +4 -4
- package/dist/core/graph/kinds/dto.d.ts +2 -2
- package/dist/core/graph/kinds/dto.js +1 -1
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/kinds/kind.d.ts +6 -8
- package/dist/core/graph/kinds/kind.js +1 -1
- package/dist/core/graph/kinds/node.js +5 -5
- package/dist/core/graph/kinds/owner.js +2 -2
- package/dist/core/graph/kinds/registry.d.ts +6 -9
- package/dist/core/graph/kinds/registry.js +1 -1
- package/dist/core/graph/names.d.ts +6 -6
- package/dist/core/graph/names.js +3 -3
- package/dist/core/graph/object-waits.d.ts +4 -7
- package/dist/core/graph/object-waits.js +1 -1
- package/dist/core/graph/objects.d.ts +14 -14
- package/dist/core/graph/objects.js +9 -9
- package/dist/core/graph/package-docs.d.ts +2 -7
- package/dist/core/graph/package-docs.js +5 -5
- package/dist/core/graph/package-kinds.d.ts +2 -5
- package/dist/core/graph/package-kinds.js +1 -1
- package/dist/core/graph/package-reconcile.d.ts +2 -5
- package/dist/core/graph/package-reconcile.js +1 -1
- package/dist/core/graph/reader.d.ts +18 -18
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/receivers.d.ts +4 -4
- package/dist/core/graph/receivers.js +5 -5
- package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/repo-sync/repos.d.ts +7 -5
- package/dist/core/graph/repo-sync/repos.js +3 -3
- package/dist/core/graph/repo-sync/sync.d.ts +3 -6
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/graph/rules.d.ts +5 -5
- package/dist/core/graph/rules.js +3 -3
- package/dist/core/graph/spaces/app.js +1 -1
- package/dist/core/graph/spaces/index.d.ts +4 -5
- package/dist/core/graph/spaces/index.js +1 -1
- package/dist/core/graph/spaces/own-memory.d.ts +4 -4
- package/dist/core/graph/spaces/own-memory.js +1 -1
- package/dist/core/graph/spaces/person.js +3 -3
- package/dist/core/graph/spaces/repo.d.ts +1 -1
- package/dist/core/graph/spaces/repo.js +1 -1
- package/dist/core/graph/watches.d.ts +15 -15
- package/dist/core/graph/watches.js +10 -10
- package/dist/core/human/feedback-companion.d.ts +2 -2
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/feedback.d.ts +3 -3
- package/dist/core/human/feedback.js +1 -1
- package/dist/core/human/requests.d.ts +34 -33
- package/dist/core/human/requests.js +20 -20
- package/dist/core/human/scan.d.ts +2 -2
- package/dist/core/human/scan.js +1 -1
- package/dist/core/human/tickets.d.ts +9 -9
- package/dist/core/human/tickets.js +1 -1
- package/dist/core/llm/app-rungs.d.ts +1 -1
- package/dist/core/llm/app-rungs.js +1 -1
- package/dist/core/llm/run.js +2 -2
- package/dist/core/peer/directory.d.ts +1 -1
- package/dist/core/peer/directory.js +1 -1
- package/dist/core/peer/envelope.d.ts +3 -3
- package/dist/core/peer/envelope.js +1 -1
- package/dist/core/peer/home.d.ts +13 -7
- package/dist/core/peer/home.js +2 -2
- package/dist/core/peer/ingest.d.ts +6 -6
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/outbox-store.d.ts +14 -14
- package/dist/core/peer/outbox-store.js +5 -5
- package/dist/core/peer/receiver.d.ts +2 -2
- package/dist/core/peer/receiver.js +1 -1
- package/dist/core/peer/stubs.d.ts +10 -10
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/providers/approval.d.ts +2 -2
- package/dist/core/providers/approval.js +2 -2
- package/dist/core/providers/audit.d.ts +3 -3
- package/dist/core/providers/audit.js +2 -2
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +2 -2
- package/dist/core/providers/call.js +1 -1
- package/dist/core/providers/files.d.ts +1 -1
- package/dist/core/providers/files.js +1 -1
- package/dist/core/providers/mint.js +1 -1
- package/dist/core/providers/receipts.d.ts +1 -1
- package/dist/core/providers/receipts.js +2 -2
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/comments.d.ts +19 -19
- package/dist/core/review/comments.js +5 -5
- package/dist/core/review/companion.d.ts +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/document.d.ts +3 -3
- package/dist/core/review/document.js +2 -2
- package/dist/core/review/fork.js +2 -2
- package/dist/core/review/realize.js +1 -1
- package/dist/core/review/remap.d.ts +2 -2
- package/dist/core/review/remap.js +4 -4
- package/dist/core/review/stage.d.ts +1 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/store.d.ts +21 -21
- package/dist/core/review/store.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +5 -5
- package/dist/core/runs/confinement.d.ts +7 -7
- package/dist/core/runs/confinement.js +2 -2
- package/dist/core/runs/events.d.ts +12 -12
- package/dist/core/runs/events.js +4 -4
- package/dist/core/runs/operations.d.ts +11 -11
- package/dist/core/runs/operations.js +5 -5
- package/dist/core/runs/questions.d.ts +10 -10
- package/dist/core/runs/questions.js +3 -3
- package/dist/core/runtime/auth-reload.js +1 -1
- package/dist/core/runtime/bearings.d.ts +5 -5
- package/dist/core/runtime/bearings.js +6 -6
- package/dist/core/runtime/broker-inventory.js +1 -1
- package/dist/core/runtime/broker-request.js +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +3 -3
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/fleet.d.ts +2 -2
- package/dist/core/runtime/host.d.ts +3 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/kickoff.d.ts +12 -12
- package/dist/core/runtime/kickoff.js +17 -17
- package/dist/core/runtime/launch-target.d.ts +1 -1
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/ledger.d.ts +3 -3
- package/dist/core/runtime/ledger.js +3 -3
- package/dist/core/runtime/lifecycle.d.ts +1 -1
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/memory-admission.js +1 -1
- package/dist/core/runtime/model-swap.d.ts +2 -2
- package/dist/core/runtime/model-swap.js +1 -1
- package/dist/core/runtime/node-read.d.ts +1 -1
- package/dist/core/runtime/node-read.js +2 -2
- package/dist/core/runtime/nodes.d.ts +6 -6
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +1 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/persona.d.ts +3 -3
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/placement.d.ts +11 -11
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.d.ts +3 -3
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.d.ts +5 -5
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/reset.d.ts +4 -4
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive-all.d.ts +2 -2
- package/dist/core/runtime/revive-all.js +1 -1
- package/dist/core/runtime/revive.d.ts +4 -4
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/roadmap.d.ts +6 -6
- package/dist/core/runtime/roadmap.js +5 -5
- package/dist/core/runtime/session-branch.d.ts +1 -1
- package/dist/core/runtime/session-branch.js +1 -1
- package/dist/core/runtime/session-list-cache.js +1 -1
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn.d.ts +2 -2
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +2 -2
- package/dist/core/runtime/stop-guard.js +3 -3
- package/dist/core/runtime/warm-pool.d.ts +2 -2
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/spaces/mounts.d.ts +2 -2
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/permissions.d.ts +1 -1
- package/dist/core/spaces/permissions.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/process.js +1 -1
- package/dist/core/spaces/space.js +1 -1
- package/dist/core/spaces/stop.d.ts +3 -3
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +6 -6
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +2 -2
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/shares.d.ts +2 -2
- package/dist/core/storage/shares.js +1 -1
- package/dist/core/storage/tables.d.ts +21 -21
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/substrate/delivery/corpus.d.ts +5 -8
- package/dist/core/substrate/delivery/corpus.js +3 -3
- package/dist/core/substrate/delivery/deliver.d.ts +10 -15
- package/dist/core/substrate/delivery/deliver.js +3 -3
- package/dist/core/substrate/delivery/plan.d.ts +2 -12
- package/dist/core/substrate/delivery/plan.js +3 -3
- package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
- package/dist/core/substrate/delivery/render-boot.js +18 -18
- package/dist/core/substrate/delivery/render-event.d.ts +7 -14
- package/dist/core/substrate/delivery/render-event.js +4 -4
- package/dist/core/substrate/subject.d.ts +2 -2
- package/dist/core/substrate/subject.js +1 -1
- package/dist/core/usage/ledger.d.ts +6 -6
- package/dist/core/usage/ledger.js +4 -4
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +7 -7
- package/dist/core/worktree-quarantine.js +1 -1
- package/dist/core/worktree-sweep.d.ts +1 -1
- package/dist/core/worktree-sweep.js +6 -6
- package/dist/core/worktree.d.ts +5 -5
- package/dist/core/worktree.js +13 -13
- package/dist/daemon/analytics/compute.d.ts +2 -2
- package/dist/daemon/analytics/compute.js +1 -1
- package/dist/daemon/api/app-listener.d.ts +4 -4
- package/dist/daemon/api/app-listener.js +13 -13
- package/dist/daemon/api/bridge.js +5 -5
- package/dist/daemon/api/document-listener.js +6 -6
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.d.ts +1 -1
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/chat-inventory.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
- package/dist/daemon/api/handlers/custom-objects.js +3 -3
- package/dist/daemon/api/handlers/delivery-retry.js +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.d.ts +4 -4
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/feedback-comments.js +3 -3
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/focus.js +1 -1
- package/dist/daemon/api/handlers/health.js +3 -3
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox-page.d.ts +1 -1
- package/dist/daemon/api/handlers/inbox-page.js +1 -1
- package/dist/daemon/api/handlers/inbox.d.ts +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/llm.d.ts +1 -1
- package/dist/daemon/api/handlers/llm.js +3 -3
- package/dist/daemon/api/handlers/memory-reads.js +1 -1
- package/dist/daemon/api/handlers/memory.d.ts +5 -5
- package/dist/daemon/api/handlers/memory.js +5 -5
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/node-events.d.ts +2 -2
- package/dist/daemon/api/handlers/node-events.js +3 -3
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.js +2 -2
- package/dist/daemon/api/handlers/nodes.d.ts +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/package-docs.js +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
- package/dist/daemon/api/handlers/profiles.d.ts +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.d.ts +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/questions.js +1 -1
- package/dist/daemon/api/handlers/reports.d.ts +1 -1
- package/dist/daemon/api/handlers/reports.js +5 -5
- package/dist/daemon/api/handlers/review-comments.js +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/subscriptions.js +1 -1
- package/dist/daemon/api/handlers/transfer.js +1 -1
- package/dist/daemon/api/map.d.ts +3 -3
- package/dist/daemon/api/map.js +1 -1
- package/dist/daemon/api/principal.d.ts +1 -1
- package/dist/daemon/api/principal.js +1 -1
- package/dist/daemon/api/reader.d.ts +5 -5
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +5 -5
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/broker-signals/bus.d.ts +1 -1
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/companion-retire.js +1 -1
- package/dist/daemon/cron/armed-context.d.ts +2 -2
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/authority.d.ts +2 -2
- package/dist/daemon/cron/authority.js +1 -1
- package/dist/daemon/cron/disposition.js +1 -1
- package/dist/daemon/cron/ended.d.ts +1 -1
- package/dist/daemon/cron/ended.js +2 -2
- package/dist/daemon/cron/escalation.js +3 -3
- package/dist/daemon/cron/folders.d.ts +1 -1
- package/dist/daemon/cron/folders.js +1 -1
- package/dist/daemon/cron/held.d.ts +1 -1
- package/dist/daemon/cron/held.js +1 -1
- package/dist/daemon/cron/lease-recovery.d.ts +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/passes.d.ts +2 -2
- package/dist/daemon/cron/passes.js +1 -1
- package/dist/daemon/cron/run-socket.d.ts +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron/settle.js +1 -1
- package/dist/daemon/cron/sinks.d.ts +1 -1
- package/dist/daemon/cron/sinks.js +2 -2
- package/dist/daemon/cron-run.d.ts +12 -3
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd.js +6 -6
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +3 -3
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.d.ts +3 -3
- package/dist/daemon/due.js +7 -7
- package/dist/daemon/fleet.d.ts +2 -2
- package/dist/daemon/fleet.js +11 -11
- package/dist/daemon/human/finish.js +3 -3
- package/dist/daemon/human/settle.d.ts +1 -1
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/human/sweep.js +1 -1
- package/dist/daemon/joined-owner.d.ts +2 -2
- package/dist/daemon/joined-owner.js +1 -1
- package/dist/daemon/messaging/node-message.js +1 -1
- package/dist/daemon/park-activity.d.ts +2 -2
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/peer/authority.js +1 -1
- package/dist/daemon/peer/forward.d.ts +13 -6
- package/dist/daemon/peer/forward.js +1 -1
- package/dist/daemon/peer/handlers.js +1 -1
- package/dist/daemon/peer/ingress.d.ts +4 -4
- package/dist/daemon/peer/ingress.js +1 -1
- package/dist/daemon/peer/outbox.d.ts +2 -2
- package/dist/daemon/peer/outbox.js +1 -1
- package/dist/daemon/peer/relay-service.js +1 -1
- package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
- package/dist/daemon/plugin-objects/read-leaf.js +2 -2
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/readiness.d.ts +2 -2
- package/dist/daemon/readiness.js +1 -1
- package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/action-lane.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.js +2 -2
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
- package/dist/daemon/reconcilers/controller-death.js +1 -1
- package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +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/node-lifecycle/respawn-policy.d.ts +3 -3
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/storage-due-work.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
- package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/review/comment-notify.js +2 -2
- package/dist/daemon/review/companion.d.ts +3 -3
- package/dist/daemon/review/companion.js +1 -1
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/review/sweep.js +1 -1
- package/dist/daemon/run-notices.d.ts +4 -4
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +2 -2
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +2 -2
- package/dist/daemon/runs/observer.js +2 -2
- package/dist/daemon/structured-requests/boot.d.ts +1 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
- package/dist/migrations/004-canvas-documents/apply.js +1 -1
- package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/migrations/activation.js +2 -2
- package/docs/public-api.md +11 -0
- package/package.json +3 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
var C=Object.defineProperty;var
|
|
1
|
+
var C=Object.defineProperty;var u=(e,r)=>C(e,"name",{value:r,configurable:!0});import{existsSync as v}from"node:fs";import{assertGranteeRunsHere as $}from"../runtime/unsandboxed.js";import{randomUUID as N}from"node:crypto";import{join as g}from"node:path";import{getNode as R}from"../canvas/canvas.js";import{nodeAgentDir as O,nodeHome as k,nodeRunDir as H}from"../canvas/paths.js";import{appSpace as K}from"../layout.js";import{activeGrant as h,activeGrantForApp as _,grantFor as I,grantsGeneration as S}from"../grants/mirror.js";import{readConfig as B}from"../config.js";import{emitEvent as y}from"../events/emit.js";import{ensureAppSpace as F}from"./space.js";import{compileLaunch as G,launchStillGranted as M}from"./mounts.js";import{pinSandboxRuntimeHome as j}from"./runtime-home.js";import{sandboxCacheEnv as q}from"./cache-env.js";import{launcherRequest as b}from"../../launcher/client.js";import{LAUNCHER_SOCKET as T}from"../../launcher/spec.js";function U(e){return`cron-${e}`}u(U,"cronLaunchId");function ce(){if(process.platform!=="linux")return!1;if(v(T))return!0;throw new Error("root launcher socket is unavailable; refusing an unsandboxed app process")}u(ce,"appProcessSandboxed");function fe(){return A??(process.platform==="linux"&&v(T))}u(fe,"appProcessesSandboxed");let A;function le(e){A=e}u(le,"__setAppProcessesSandboxedForTest");async function me(e,r,n,o=!1,t,d){const a=n===void 0?null:await R(n),s=d!==void 0?d.grantId?await h(d.grantId):await I(e,d.sub):a?null:await _(e);if(d!==void 0?!s&&!(d.grantId===null&&e==="app:terminal"):!a&&!s)throw new Error(`no active grant for ${e}`);return(await G({nodeId:n??"proc-cwd-check",app:e,...d!==void 0?{sub:d.sub,grantId:s?.id??null,scopes:d.scopes}:{sub:a?a.sub??"user:local":s.sub,grantId:a?a.grant_id??null:s.id,scopes:a?.scopes??null},command:["true"],env:{},...n===void 0?{withoutNode:!0}:{},...t===void 0?{}:{folder:t},isolated:a?.isolated===!0||o,auditMissing:u(()=>{},"auditMissing")})).mounts.some(({source:c})=>r===c||r.startsWith(c==="/"?"/":`${c}/`))}u(me,"cwdIsMounted");async function D(e,r="SIGKILL",n){if(!("ok"in await b({operation:"stop",pid:e,signal:r,...n===void 0?{}:{nodeId:n}})))throw new Error("launcher did not stop process")}u(D,"stopAppProcess");function W(e,r,n,o,t){return o?t??O(e,r):n}u(W,"appProcessCwd");async function pe(e){if(e.cron!==void 0&&(e.nodeId!==void 0||e.principal===void 0))throw new Error("a cron launch has a stored principal and no node");const r=e.nodeId===void 0?null:await R(e.nodeId);if(e.nodeId!==void 0&&!r)throw new Error(`missing node ${e.nodeId}`);const n=r?.grantee??e.app??"app:terminal";if($(n),e.app!==void 0&&e.app!==n)throw new Error("app does not match node");const o=e.principal;let t=null;if(o!==void 0){if(t=o.grantId?await h(o.grantId):await I(n,o.sub),!(t===null&&o.grantId===null&&n==="app:terminal"&&!B("user").runtime?.issuer)&&(!t||t.grantee!==n||t.sub!==o.sub))throw new Error(`no active grant for ${n}`)}else if(r){if(n!=="app:terminal"&&!(r.grant_id?await h(r.grant_id):await I(n,r.sub??"user:local")))throw new Error(`no active grant for ${n}`)}else if(t=await _(n),!t)throw new Error(`no active grant for ${n}`);await F(n);const d=e.cron===void 0?e.nodeId??`proc-${N()}`:U(e.cron.executionId),a=r?.isolated===!0||e.isolated===!0;if(a&&!r&&e.folder===void 0)throw new Error("isolated process requires a live node");const s=K(n),m=W(d,n,e.cwd,a,e.folder),c=r?k(d,n,a):a&&e.folder!==void 0?g(e.folder,"home"):s.home,L=j(Object.fromEntries(Object.entries({...e.env,...process.platform==="linux"?q(n):{},HOME:c,PI_CODING_AGENT_DIR:g(c,".pi","agent"),PWD:m,...e.nodeId===void 0&&e.cron===void 0?{}:{CRTR_API_SOCKET:g(H(d),"cli.sock")}}).filter(i=>i[1]!==void 0))),E=o!==void 0?{nodeId:d,app:n,sub:o.sub,grantId:t?.id??null,scopes:o.scopes}:{nodeId:d,app:n,sub:r?r.sub??"user:local":t.sub,grantId:r?r.grant_id??null:t.id,scopes:r?.scopes??null},P=u(async()=>{const i=await G({...E,command:e.command,env:L,...e.nodeId===void 0?{withoutNode:!0}:{},isolated:a,cwd:m,...e.folder===void 0?{}:{folder:e.folder},...e.cron===void 0?{}:{cron:e.cron.anchorDir===void 0?{}:{anchorDir:e.cron.anchorDir}},...e.pluginRoot===void 0?{}:{pluginRoot:e.pluginRoot},auditMissing:u(w=>y({level:"warn",event:"process.mount.missing",...e.nodeId===void 0?{}:{node_id:e.nodeId},fields:{source:w}}),"auditMissing")});if(e.pluginRoot!==void 0&&(i.pluginRoot=e.pluginRoot),e.capture===!1){if(e.nodeId===void 0||e.stdin!==void 0)throw new Error("uncaptured process requires a node and no stdin")}else i.capture={stdoutBytes:e.stdoutBytes??256*1024,stderrBytes:e.stderrBytes??256*1024,...e.stderrTail?{stderrTail:!0}:{},...e.stdin===void 0?{}:{stdin:e.stdin}};return i},"compile");let f;for(let i=0;i<2&&f===void 0;i++){const w=await S(),x=await P(),l=await b({operation:"launch",spec:x});if(!("pid"in l))throw new Error("launcher did not return a process id");if(await S()===w||await M(E,x)){f=l.pid;break}y({level:"info",event:"process.launch.regranted",...e.nodeId===void 0?{}:{node_id:e.nodeId},fields:{pid:l.pid}}),await D(l.pid,"SIGKILL").catch(()=>{})}if(f===void 0)throw new Error("grant changed during every launch attempt");const p=f;return{pid:p,get completion(){return b({operation:"wait",pid:p}).then(i=>{if(!("result"in i))throw new Error("launcher did not return process completion");return i.result})},stop:u((i="SIGKILL")=>D(p,i,e.cron===void 0?e.nodeId:d),"stop")}}u(pe,"launchAppProcess");export{le as __setAppProcessesSandboxedForTest,W as appProcessCwd,ce as appProcessSandboxed,fe as appProcessesSandboxed,U as cronLaunchId,me as cwdIsMounted,pe as launchAppProcess,D as stopAppProcess};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
var f=Object.defineProperty;var n=(o,r)=>f(o,"name",{value:r,configurable:!0});import{chownSync as a,chmodSync as d,existsSync as l,mkdirSync as c,readFileSync as h,statSync as m}from"node:fs";import{appSpace as g,appsRoot as w,userFilesRoot as y}from"../layout.js";import{launcherRequest as S}from"../../launcher/client.js";import{LAUNCHER_SOCKET as x}from"../../launcher/spec.js";import{allocateAppUser as E,uidForApp as v}from"./users.js";function p(){const o=h("/etc/group","utf8").split(`
|
|
2
|
-
`).find(e=>e.startsWith("crtr-data:"));if(!o)throw new Error("crtr-data group is required on sandboxed Linux");const r=Number(o.split(":")[2]);if(!Number.isInteger(r))throw new Error("invalid crtr-data group id");return r}n(p,"dataGroup");function L(){const o=y(),r=p();c(o,{recursive:!0,mode:1528});const e=m(o),t=e.mode&4095;if(!e.isDirectory()||e.gid!==r||t!==1528){if(!e.isDirectory()||e.uid!==process.getuid())throw new Error(`${o} has owner ${e.uid}, group ${e.gid}, mode ${t.toString(8).padStart(4,"0")}; requires an crtr-data (${r}) directory with mode 2770; only its owner can repair it`);e.gid!==r&&a(o,e.uid,r),t!==1528&&d(o,1528)}}n(L,"ensureUserFiles");async function N(o){const r=g(o);if(!(process.platform==="linux"&&l(x))){if(process.platform==="linux")throw new Error("app space requires the root launcher on Linux");for(const i of[r.root,r.profiles,r.conversations,r.nodes,r.files,r.home,r.cache])c(i,{recursive:!0});return{uid:v(o),gid:process.getgid(),root:r.root}}const t=p(),s=E(o),u=await S({operation:"user.create",app:r.root.slice(w().length+1),uid:s.uid});if(!("uid"in u)||u.uid!==s.uid)throw new Error(`launcher did not create OS user for ${o}`);for(const i of[r.root,r.profiles,r.conversations,r.nodes,r.files,r.home,r.cache])c(i,{recursive:!0,mode:1528}),a(i,process.getuid(),t),d(i,1528);return{uid:s.uid,gid:t,root:r.root}}n(N,"ensureAppSpace");export{N as ensureAppSpace,L as ensureUserFiles};
|
|
2
|
+
`).find(e=>e.startsWith("crtr-data:"));if(!o)throw new Error("crtr-data group is required on sandboxed Linux");const r=Number(o.split(":")[2]);if(!Number.isInteger(r))throw new Error("invalid crtr-data group id");return r}n(p,"dataGroup");function L(){const o=y(),r=p();c(o,{recursive:!0,mode:1528});const e=m(o),t=e.mode&4095;if(!e.isDirectory()||e.gid!==r||t!==1528){if(!e.isDirectory()||e.uid!==process.getuid())throw new Error(`${o} has owner ${e.uid}, group ${e.gid}, mode ${t.toString(8).padStart(4,"0")}; requires an crtr-data (${r}) directory with mode 2770; only its owner can repair it`);e.gid!==r&&a(o,e.uid,r),t!==1528&&d(o,1528)}}n(L,"ensureUserFiles");async function N(o){const r=g(o);if(!(process.platform==="linux"&&l(x))){if(process.platform==="linux")throw new Error("app space requires the root launcher on Linux");for(const i of[r.root,r.profiles,r.conversations,r.nodes,r.files,r.home,r.cache])c(i,{recursive:!0});return{uid:await v(o),gid:process.getgid(),root:r.root}}const t=p(),s=await E(o),u=await S({operation:"user.create",app:r.root.slice(w().length+1),uid:s.uid});if(!("uid"in u)||u.uid!==s.uid)throw new Error(`launcher did not create OS user for ${o}`);for(const i of[r.root,r.profiles,r.conversations,r.nodes,r.files,r.home,r.cache])c(i,{recursive:!0,mode:1528}),a(i,process.getuid(),t),d(i,1528);return{uid:s.uid,gid:t,root:r.root}}n(N,"ensureAppSpace");export{N as ensureAppSpace,L as ensureUserFiles};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CanvasDb } from '../canvas/db.js';
|
|
2
2
|
import type { ObjectRow } from '../graph/types.js';
|
|
3
3
|
import { type TeardownResult } from '../runtime/host.js';
|
|
4
4
|
/** End the job object of a backgrounded command as killed. A command that was never backgrounded
|
|
5
5
|
* has no job object; that answers false. Daemon-only: opens canvas.db. */
|
|
6
|
-
export declare function killBashJobObject(jobId: string, killedBy: (db:
|
|
6
|
+
export declare function killBashJobObject(jobId: string, killedBy: (db: CanvasDb) => Promise<ObjectRow | null>, reason?: string): Promise<boolean>;
|
|
7
7
|
/** Record a backgrounded command as its node's job object (id = job id); an existing job
|
|
8
8
|
* object is returned as is. The one path for both the broker's record call and the
|
|
9
9
|
* daemon adopting a job the broker backgrounded while exiting. Daemon-only. */
|
|
@@ -11,7 +11,7 @@ export declare function recordBashJobObject(nodeId: string, jobId: string, spec:
|
|
|
11
11
|
command: string;
|
|
12
12
|
jobDir: string;
|
|
13
13
|
logPath: string;
|
|
14
|
-
}): ObjectRow
|
|
14
|
+
}): Promise<ObjectRow>;
|
|
15
15
|
/** Stop the broker first so it cannot start another job during the job scan. */
|
|
16
16
|
export declare function stopNodeSandboxes(nodeId: string, reason: string, options?: {
|
|
17
17
|
excludePid?: number;
|
package/dist/core/spaces/stop.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var _=Object.defineProperty;var
|
|
2
|
-
AND type IN ('node.turn.started', 'node.turn.completed') ORDER BY sequence_number DESC LIMIT 1`).get(
|
|
1
|
+
var _=Object.defineProperty;var s=(t,e)=>_(t,"name",{value:e,configurable:!0});import{randomUUID as g}from"node:crypto";import{activeBackgroundBashJobs as x,stopBackgroundBashJob as R}from"../bash-jobs.js";import{getNode as T}from"../canvas/index.js";import{withCanvasWrite as b,openDb as D}from"../canvas/db.js";import{finishJob as S,startJob as J}from"../graph/jobs.js";import{getById as h,nodeObject as O}from"../graph/objects.js";import{readLiveSession as M}from"../canvas/sessions.js";import{contextDir as N}from"../canvas/node-agent-paths.js";import{conversationStore as W}from"../conversation-store/index.js";import{requestBrokerTeardown as $}from"../runtime/host.js";import{holdRecovery as C}from"../runtime/recovery-hold.js";async function L(t,e,o){return await b(async n=>{const r=await h(n,t);return r===null||r.type!=="job"?!1:(await S(n,r,{killedBy:await e(n),...o===void 0?{}:{reason:o}}),!0)})}s(L,"killBashJobObject");async function X(t,e,o){return await b(async n=>{const r=await h(n,e);if(r!==null){if(r.type!=="job")throw new Error(`${e} names a ${r.type}`);return r}return await J(n,await O(n,t),{id:e,...o})})}s(X,"recordBashJobObject");const d=new Map;async function Z(t,e,o={}){const n=d.get(t);if(n)return n;const r=await T(t);if(!r)return Promise.resolve({confirmed:!1,error:new Error(`missing node ${t}`)});const l=(await M(t))?.sessionId,m=s(async()=>await(await D()).prepare(`SELECT type, body_json FROM run_events WHERE node_id = ?
|
|
2
|
+
AND type IN ('node.turn.started', 'node.turn.completed') ORDER BY sequence_number DESC LIMIT 1`).get(t),"latestTurn"),v=r.run_id!==null&&r.pi_pid!==null&&(await m())?.type==="node.turn.started",E=o.holdRecovery?C(t):()=>{},j=$(t,{excludePid:o.excludePid}),c=(async()=>{const u=await j;if(!u.confirmed)return u;try{const a=await N(t);for(const p of x(a,!0)){const i=await R(a,p.jobId,!0,t,e);if(i.kind==="not-stoppable")throw new Error(`background bash job ${p.jobId} could not be stopped`);i.kind!=="stopped"||o.deleting||await L(p.jobId,async()=>null,e)}if(v&&l&&!o.deleting){if((await m())?.type!=="node.turn.started")return await o.after?.(),u;const i=W(),{entries:k}=await i.read(l),B=k.at(-1),f=new Date().toISOString(),w=e==="permission_revoked",y={type:"message",id:g(),parentId:B?.id??null,timestamp:f,message:{role:"assistant",content:[],api:"openai-completions",provider:"crouter",model:"",usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:w?"error":"aborted",errorMessage:e,timestamp:Date.now()}};await i.append(l,[y,{type:"custom",id:g(),parentId:y.id,timestamp:f,customType:"crtr-turn-end",data:w?{stop_reason:"error",error:{code:"model_error",message:e}}:{stop_reason:"aborted"}}])}return await o.after?.(),u}catch(a){return{confirmed:!1,error:a instanceof Error?a:new Error(String(a))}}})();return d.set(t,c),c.finally(()=>{E(),d.get(t)===c&&d.delete(t)}),c}s(Z,"stopNodeSandboxes");export{L as killBashJobObject,X as recordBashJobObject,Z as stopNodeSandboxes};
|
|
@@ -5,15 +5,15 @@ export interface AppUser {
|
|
|
5
5
|
status: 'active' | 'removed';
|
|
6
6
|
}
|
|
7
7
|
/** The launcher is absent on macOS; there is no app uid on that host. */
|
|
8
|
-
export declare function uidForApp(app: string): number
|
|
8
|
+
export declare function uidForApp(app: string): Promise<number>;
|
|
9
9
|
/** An app has at most one active row. A removed app that reconnects gets a new
|
|
10
10
|
* row above every uid ever allocated, so a uid is never reused. */
|
|
11
|
-
export declare function allocateAppUser(app: string): AppUser
|
|
12
|
-
export declare function activeAppUsers(): Array<{
|
|
11
|
+
export declare function allocateAppUser(app: string): Promise<AppUser>;
|
|
12
|
+
export declare function activeAppUsers(): Promise<Array<{
|
|
13
13
|
app: string;
|
|
14
14
|
uid: number;
|
|
15
|
-
}
|
|
15
|
+
}>>;
|
|
16
16
|
/** The app's OS-user row not yet marked removed, if any. */
|
|
17
|
-
export declare function activeAppUser(app: string): AppUser | null
|
|
17
|
+
export declare function activeAppUser(app: string): Promise<AppUser | null>;
|
|
18
18
|
/** The removal cascade's last write (runtime spec, "On removal"). */
|
|
19
|
-
export declare function markAppUserRemoved(uid: number): void
|
|
19
|
+
export declare function markAppUserRemoved(uid: number): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var o=Object.defineProperty;var e=(t,a)=>o(t,"name",{value:a,configurable:!0});import{existsSync as c}from"node:fs";import{withCanvasWrite as E,openDb as p}from"../canvas/db.js";import{APP_UID_MAX as d,APP_UID_MIN as u,LAUNCHER_SOCKET as w}from"../../launcher/spec.js";async function l(t){return process.platform!=="linux"||!c(w)?process.getuid?.()??0:(await A(t)).uid}e(l,"uidForApp");async function A(t){if(process.platform!=="linux")throw new Error("app OS users exist only on Linux");return await E(async a=>{const s=await a.prepare("SELECT app, uid, created, status FROM app_users WHERE app = ? AND status = 'active'").get(t);if(s)return s;const n=(await a.prepare("SELECT MAX(uid) AS uid FROM app_users").get()).uid,r=Math.max(u,(n??u-1)+1);if(r>d)throw new Error("app OS user range exhausted");const i=new Date().toISOString();return await a.prepare("INSERT INTO app_users (app, uid, created, status) VALUES (?, ?, ?, ?)").run(t,r,i,"active"),{app:t,uid:r,created:i,status:"active"}})}e(A,"allocateAppUser");async function v(){return(await(await p()).prepare("SELECT app, uid FROM app_users WHERE status = 'active'").all()).map(a=>({app:a.app.startsWith("app:")?a.app.slice(4):a.app,uid:a.uid}))}e(v,"activeAppUsers");async function _(t){return await(await p()).prepare("SELECT app, uid, created, status FROM app_users WHERE app = ? AND status = 'active'").get(t)??null}e(_,"activeAppUser");async function R(t){await(await p()).prepare("UPDATE app_users SET status = 'removed', removed_at = ? WHERE uid = ? AND status = 'active'").run(new Date().toISOString(),t)}e(R,"markAppUserRemoved");export{_ as activeAppUser,v as activeAppUsers,A as allocateAppUser,R as markAppUserRemoved,l as uidForApp};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
2
1
|
import { type StorageClient, type StorageConfig } from './client.js';
|
|
2
|
+
import type { CanvasDb } from '../canvas/db.js';
|
|
3
3
|
/** The fetch step of one `run.start` or `run.message` is bounded to 110 s in
|
|
4
4
|
* total (the hosting router waits 120 s for its headers). */
|
|
5
5
|
export declare const ATTACHMENT_FETCH_BUDGET_MS = 110000;
|
|
@@ -24,7 +24,7 @@ export interface ResolveOptions {
|
|
|
24
24
|
/** Re-check, inside the accepting write, that every used upload is still this
|
|
25
25
|
* grantee's and not pending delete (the due-work tick or an app removal may
|
|
26
26
|
* have released it while its bytes were fetched). */
|
|
27
|
-
export declare function assertUploadsUsable(grantee: string, uses: readonly AttachmentUse[], db:
|
|
27
|
+
export declare function assertUploadsUsable(grantee: string, uses: readonly AttachmentUse[], db: CanvasDb): Promise<void>;
|
|
28
28
|
/** Fetch every upload a storage URL in `text` names into
|
|
29
29
|
* `appSpace(grantee).nodes/<rootId>/attachments/` and replace exactly each
|
|
30
30
|
* URL's span with the file's absolute runtime path. Without configured
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var N=Object.defineProperty;var i=(e,
|
|
1
|
+
var N=Object.defineProperty;var i=(e,o)=>N(e,"name",{value:o,configurable:!0});import{constants as Z,createWriteStream as j}from"node:fs";import{extname as q,join as E}from"node:path";import{Transform as G}from"node:stream";import{pipeline as X}from"node:stream/promises";import{appSpace as Y}from"../layout.js";import{RunError as v}from"../runs/operations.js";import{createFileBeneath as J,existsBeneath as z,openBeneath as K,removeTreeBeneath as O,setModeBeneath as P,unlinkBeneath as Q,withDirBeneath as V}from"../spaces/open-beneath.js";import{ensureAppSpace as ee}from"../spaces/space.js";import{storageClient as te,storageConfig as ne,StorageRefused as oe}from"./client.js";import{getUpload as k}from"./tables.js";const re=11e4,p=i((e,o)=>new v(400,"invalid_request",o,void 0,{url:e}),"refused"),y=i(e=>new v(503,"storage_unavailable",e,void 0,void 0,void 0,!0),"unavailable");function x(e,o){return/^[^\s<>"'`)\]]*/.exec(e.slice(o))[0].replace(/[.,;:!?]+$/,"")}i(x,"shownUrl");async function ae(e,o,r,c,d){const l=`${o}/`,_=[];let h=0;for(let u=e.indexOf(l,h);u!==-1;u=e.indexOf(l,h)){const t=x(e,u),f=/^([A-Za-z0-9_-]+)\/([A-Za-z0-9_-]+)\//.exec(e.slice(u+l.length));if(!f)throw p(t,`storage URL ${t} does not name an upload`);if(f[1]!==r)throw p(t,`storage URL ${t} names another runtime`);const s=await k(f[2],d);if(!s||s.grantee!==c)throw p(t,`storage URL ${t} names an unknown upload`);if(s.delete_pending_since)throw p(t,`storage URL ${t} names a deleted upload`);const $=u+l.length+f[0].length,m=encodeURIComponent(s.name);if(!e.startsWith(m,$))throw p(t,`storage URL ${t} does not match the upload's name`);_.push({start:u,end:$+m.length,upload:s}),h=$+m.length}return _}i(ae,"matchStorageUrls");async function _e(e,o,r){for(const c of o){const d=await k(c.upload_id,r);if(!d||d.grantee!==e||d.delete_pending_since)throw p(c.url,`storage URL ${c.url} names an upload deleted while it was fetched`)}}i(_e,"assertUploadsUsable");function se(e,o){if(o===1)return e;const r=q(e);return r&&r!==e?`${e.slice(0,-r.length)}-${o}${r}`:`${e}-${o}`}i(se,"candidate");async function $e(e,o,r,c={}){const d={text:r,uses:[],cleanup:i(()=>{},"cleanup")},l=(c.config??ne)();if(!l||!r.includes(`${l.base_url}/`))return d;const _=(c.client??te)(),h=await ae(r,l.base_url,_.runtimeId,e);if(!h.length)return d;const u=await ee(e),t=Y(e).nodes,f=E(t,o),s=E(f,"attachments"),$={uid:process.getuid?.()??0,gid:u.gid},m=!z(t,f),I=!m&&!z(t,s),C=[];let D=!1;const M=i(()=>{if(!D){D=!0;for(const n of C)try{Q(t,n)}catch{}try{m?O(t,f):I&&O(t,s)}catch{}}},"cleanup"),U=AbortSignal.timeout(c.budgetMs??re),b=new Map;try{V(t,s,()=>{},!0);for(const{upload:n,start:B}of h){if(b.has(n.upload_id))continue;const g=x(r,B);let L;try{L=await _.fetchUpload(n.upload_id,U)}catch(a){throw a instanceof oe?p(g,a.status===409?`storage URL ${g} names an upload that was never finished`:`storage URL ${g} names an unknown upload`):U.aborted?y("attachments could not be fetched within 110 s"):a}let w="";for(let a=1;;a++){w=E(s,se(n.name,a));try{J(t,w,Buffer.alloc(0),432);break}catch(A){if(A.code!=="EEXIST")throw L.body.destroy(),A}}C.push(w);let T=0;const W=new G({transform(a,A,H){T+=a.length,H(null,a)}}),F=K(t,w,Z.O_WRONLY);try{await X(L.body,W,j("",{fd:F,autoClose:!0}),{signal:U})}catch(a){throw U.aborted?y("attachments could not be fetched within 110 s"):a instanceof v?a:y(`storage stopped sending ${n.name}: ${a instanceof Error?a.message:String(a)}`)}if(T!==n.size)throw y(`storage sent ${T} of ${n.size} bytes of ${n.name}`);P(t,w,432,$),b.set(n.upload_id,{path:w,url:g})}}catch(n){throw M(),n}let R="",S=0;for(const n of h)R+=r.slice(S,n.start)+b.get(n.upload.upload_id).path,S=n.end;return R+=r.slice(S),{text:R,uses:[...b].map(([n,{path:B,url:g}])=>({upload_id:n,path:B,url:g})),cleanup:M}}i($e,"resolveStorageUrls");export{re as ATTACHMENT_FETCH_BUDGET_MS,_e as assertUploadsUsable,$e as resolveStorageUrls};
|
|
@@ -21,9 +21,9 @@ export declare function createShare(caller: FileCaller, input: {
|
|
|
21
21
|
expires_at: string | null;
|
|
22
22
|
}>;
|
|
23
23
|
/** `share.list`: the shares `createdBy` created. */
|
|
24
|
-
export declare function listOwnShares(createdBy: string): {
|
|
24
|
+
export declare function listOwnShares(createdBy: string): Promise<{
|
|
25
25
|
shares: ShareView[];
|
|
26
|
-
}
|
|
26
|
+
}>;
|
|
27
27
|
/** `share.delete`: turn the share off, then delete its stored copy. A storage
|
|
28
28
|
* failure leaves `object_deleted_at` unset for the due-work tick to retry. */
|
|
29
29
|
export declare function deleteOwnShare(createdBy: string, shareId: string): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var g=Object.defineProperty;var n=(e,t)=>g(e,"name",{value:t,configurable:!0});import{closeSync as x,read as v}from"node:fs";import{promisify as O}from"node:util";import{basename as $,relative as u,sep as d}from"node:path";import{Readable as _}from"node:stream";import{appsRoot as m,appSpace as A}from"../layout.js";import{RunError as s}from"../runs/operations.js";import{scopeAllowed as k}from"../scopes.js";import{invalidStorageName as q,storageClient as w,UPLOAD_MAX_BYTES as D}from"./client.js";import{contentTypeFor as E,openCallerFile as C}from"./download.js";import{getShare as R,insertShare as T,listShares as B,markShareObjectDeleted as N,turnShareOff as F}from"./tables.js";const f="crtr:files:share";function y(e,t){const
|
|
1
|
+
var g=Object.defineProperty;var n=(e,t)=>g(e,"name",{value:t,configurable:!0});import{closeSync as x,read as v}from"node:fs";import{promisify as O}from"node:util";import{basename as $,relative as u,sep as d}from"node:path";import{Readable as _}from"node:stream";import{appsRoot as m,appSpace as A}from"../layout.js";import{RunError as s}from"../runs/operations.js";import{scopeAllowed as k}from"../scopes.js";import{invalidStorageName as q,storageClient as w,UPLOAD_MAX_BYTES as D}from"./client.js";import{contentTypeFor as E,openCallerFile as C}from"./download.js";import{getShare as R,insertShare as T,listShares as B,markShareObjectDeleted as N,turnShareOff as F}from"./tables.js";const f="crtr:files:share";function y(e,t){const a=u(e,t);return a===""||a!==".."&&!a.startsWith(`..${d}`)&&!a.startsWith(d)}n(y,"contains");function M(e){if(y(m(),e)){const t=u(m(),e).split(d)[0];if(t)return`app:${t}`}return"user"}n(M,"spaceOf");const b=n(e=>new s(503,"storage_unavailable",e,void 0,void 0,void 0,!0),"unavailable"),P=O(v);async function*U(e,t){let a=0;for(;a<t;){const r=Buffer.allocUnsafe(Math.min(1048576,t-a)),{bytesRead:i}=await P(e,r,0,r.length,a);if(i===0)throw new Error("shared file shrank while it was being copied");a+=i,yield r.subarray(0,i)}}n(U,"chunks");async function W(e,t,a,r){const i=_.from(U(t,a));let c;try{c=await fetch(e,{method:"PUT",signal:AbortSignal.timeout(11e4),headers:{"Content-Type":r,"Content-Length":String(a)},body:_.toWeb(i),duplex:"half"})}catch(p){throw b(`storage could not be reached: ${p instanceof Error?p.message:String(p)}`)}finally{i.destroy()}if(await c.body?.cancel().catch(()=>{}),!c.ok)throw b(`storage answered ${c.status} to the share upload`)}n(W,"putBytes");async function Z(e,t){if(typeof t.path!="string"||!t.path)throw new s(400,"invalid_request","path is required","path");let a;if(t.expires_at!==void 0&&t.expires_at!==null){const i=typeof t.expires_at=="string"?Date.parse(t.expires_at):NaN;if(!Number.isFinite(i))throw new s(400,"invalid_request","expires_at must be an ISO 8601 time","expires_at");if(i<=Date.now())throw new s(400,"invalid_request","expires_at must be in the future","expires_at");a=new Date(i).toISOString()}const r=C(e,t.path);try{if(!k(e.resolved,f)&&!y(A(e.app).root,r.path))throw new s(403,"scope_missing",`missing scope ${f}: without it only files in the app's own space can be shared`,void 0,void 0,f);if(r.size>D)throw new s(400,"invalid_request","file exceeds 100 MiB","path");const i=$(r.path),c=q(i);if(c)throw new s(400,"invalid_request",`file name cannot be shared: ${c}`,"path");const p=E(r.path),h=w(),o=await h.createShare({name:i,media_type:p,size:r.size,...a?{expires_at:a}:{}});try{await W(o.upload_link,r.fd,r.size,p)}catch(S){throw await h.deleteShare(o.share_id).catch(()=>{}),S}const l=o.expires_at??a??null;return await T({share_id:o.share_id,source_space:M(r.path),source_path:r.path,storage_key:`${h.runtimeId}/shares/${o.share_id}/${i}`,url:o.url,created_by:e.app,created_at:new Date().toISOString(),expires_at:l}),{share_id:o.share_id,url:o.url,expires_at:l}}finally{x(r.fd)}}n(Z,"createShare");function j(e){return{share_id:e.share_id,url:e.url,source_path:e.source_path,created_by:e.created_by,created_at:e.created_at,expires_at:e.expires_at,status:e.status}}n(j,"view");async function ee(e){return{shares:(await B(e)).map(j)}}n(ee,"listOwnShares");async function te(e,t){const a=await R(t);if(!a||a.created_by!==e)throw new s(404,"not_found","share not found");if(await F(t),!a.object_deleted_at)try{await w().deleteShare(t),await N(t)}catch(r){if(!(r instanceof s&&r.code==="storage_unavailable"))throw r}return{share_id:t,status:"off"}}n(te,"deleteOwnShare");export{f as SHARE_SCOPE,Z as createShare,te as deleteOwnShare,ee as listOwnShares};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CanvasDb } from '../canvas/db.js';
|
|
2
2
|
/** Row helpers for the v60 file-transfer tables. Each takes an optional handle
|
|
3
3
|
* so a caller inside `withCanvasWrite` passes its transaction. */
|
|
4
4
|
export interface UploadRow {
|
|
@@ -27,37 +27,37 @@ export interface ShareRow {
|
|
|
27
27
|
status: 'on' | 'off';
|
|
28
28
|
object_deleted_at: string | null;
|
|
29
29
|
}
|
|
30
|
-
export declare function insertUpload(row: Omit<UploadRow, 'delete_pending_since'>, db?:
|
|
31
|
-
export declare function getUpload(uploadId: string, db?:
|
|
32
|
-
export declare function deleteUploadRow(uploadId: string, db?:
|
|
30
|
+
export declare function insertUpload(row: Omit<UploadRow, 'delete_pending_since'>, db?: CanvasDb): Promise<void>;
|
|
31
|
+
export declare function getUpload(uploadId: string, db?: CanvasDb): Promise<UploadRow | null>;
|
|
32
|
+
export declare function deleteUploadRow(uploadId: string, db?: CanvasDb): Promise<void>;
|
|
33
33
|
/** Uploads the runtime owes storage a delete for, oldest first. */
|
|
34
|
-
export declare function pendingUploadDeletes(db?:
|
|
34
|
+
export declare function pendingUploadDeletes(db?: CanvasDb): Promise<UploadRow[]>;
|
|
35
35
|
/** Mark uploads for deletion (idempotent: keeps the first mark). */
|
|
36
|
-
export declare function markUploadsDeletePending(uploadIds: readonly string[], db?:
|
|
37
|
-
export declare function insertUploadUses(uses: readonly UploadUseRow[], db?:
|
|
36
|
+
export declare function markUploadsDeletePending(uploadIds: readonly string[], db?: CanvasDb, at?: string): Promise<void>;
|
|
37
|
+
export declare function insertUploadUses(uses: readonly UploadUseRow[], db?: CanvasDb): Promise<void>;
|
|
38
38
|
/** Remove one recorded use (a file result undone after it was recorded). */
|
|
39
|
-
export declare function deleteUploadUse(use: UploadUseRow, db?:
|
|
39
|
+
export declare function deleteUploadUse(use: UploadUseRow, db?: CanvasDb): Promise<void>;
|
|
40
40
|
/** Record the size storage actually holds for an upload created with `max_size`. */
|
|
41
|
-
export declare function setUploadSize(uploadId: string, size: number, db?:
|
|
41
|
+
export declare function setUploadSize(uploadId: string, size: number, db?: CanvasDb): Promise<void>;
|
|
42
42
|
/** The use recorded at `path`, if any. */
|
|
43
|
-
export declare function uploadUseAt(path: string, db?:
|
|
43
|
+
export declare function uploadUseAt(path: string, db?: CanvasDb): Promise<UploadUseRow | null>;
|
|
44
44
|
/** Delete a run's uses and mark each of its uploads that no other run uses for
|
|
45
45
|
* deletion. Returns the upload ids newly owed a storage delete. */
|
|
46
|
-
export declare function releaseRunUploads(runIds: readonly string[], db?:
|
|
46
|
+
export declare function releaseRunUploads(runIds: readonly string[], db?: CanvasDb): Promise<string[]>;
|
|
47
47
|
/** Uploads never used 24 h after creation (the tick marks them for deletion). */
|
|
48
|
-
export declare function staleUnusedUploads(before: string, db?:
|
|
49
|
-
export declare function insertShare(row: Omit<ShareRow, 'status' | 'object_deleted_at'>, db?:
|
|
50
|
-
export declare function getShare(shareId: string, db?:
|
|
48
|
+
export declare function staleUnusedUploads(before: string, db?: CanvasDb): Promise<string[]>;
|
|
49
|
+
export declare function insertShare(row: Omit<ShareRow, 'status' | 'object_deleted_at'>, db?: CanvasDb): Promise<void>;
|
|
50
|
+
export declare function getShare(shareId: string, db?: CanvasDb): Promise<ShareRow | null>;
|
|
51
51
|
/** Shares `created_by` owns; `null` (the person) lists every share. */
|
|
52
|
-
export declare function listShares(createdBy: string | null, db?:
|
|
53
|
-
export declare function turnShareOff(shareId: string, db?:
|
|
52
|
+
export declare function listShares(createdBy: string | null, db?: CanvasDb): Promise<ShareRow[]>;
|
|
53
|
+
export declare function turnShareOff(shareId: string, db?: CanvasDb): Promise<void>;
|
|
54
54
|
/** Turn every share `created_by` owns off; returns their ids. */
|
|
55
|
-
export declare function turnSharesOffFor(createdBy: string, db?:
|
|
55
|
+
export declare function turnSharesOffFor(createdBy: string, db?: CanvasDb): Promise<string[]>;
|
|
56
56
|
/** Shares `on` whose `expires_at` has passed turn `off`; returns their ids. */
|
|
57
|
-
export declare function expireShares(at?: string, db?:
|
|
57
|
+
export declare function expireShares(at?: string, db?: CanvasDb): Promise<string[]>;
|
|
58
58
|
/** Shares `off` whose stored object storage has not confirmed deleted. */
|
|
59
|
-
export declare function sharesOwingObjectDelete(db?:
|
|
60
|
-
export declare function markShareObjectDeleted(shareId: string, db?:
|
|
59
|
+
export declare function sharesOwingObjectDelete(db?: CanvasDb): Promise<ShareRow[]>;
|
|
60
|
+
export declare function markShareObjectDeleted(shareId: string, db?: CanvasDb, at?: string): Promise<void>;
|
|
61
61
|
/** Mark every upload `grantee` created for deletion (app removal); returns the
|
|
62
62
|
* ids newly marked. */
|
|
63
|
-
export declare function markGranteeUploadsDeletePending(grantee: string, db?:
|
|
63
|
+
export declare function markGranteeUploadsDeletePending(grantee: string, db?: CanvasDb, at?: string): Promise<string[]>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
AND NOT EXISTS (SELECT 1 FROM upload_uses x WHERE x.upload_id = u.upload_id)`).all(
|
|
3
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'on', NULL)`).run(
|
|
1
|
+
var E=Object.defineProperty;var t=(a,e)=>E(a,"name",{value:e,configurable:!0});import{openDb as l}from"../canvas/db.js";import{filterAsync as _}from"../async-array.js";const n=t(async a=>a??await l(),"handle"),d=t(()=>new Date().toISOString(),"now");async function w(a,e){await(await n(e)).prepare("INSERT INTO uploads (upload_id, grantee, name, media_type, size, created_at, delete_pending_since) VALUES (?, ?, ?, ?, ?, ?, NULL)").run(a.upload_id,a.grantee,a.name,a.media_type,a.size,a.created_at)}t(w,"insertUpload");async function T(a,e){return await(await n(e)).prepare("SELECT * FROM uploads WHERE upload_id = ?").get(a)??null}t(T,"getUpload");async function f(a,e){await(await n(e)).prepare("DELETE FROM uploads WHERE upload_id = ?").run(a)}t(f,"deleteUploadRow");async function L(a){return await(await n(a)).prepare("SELECT * FROM uploads WHERE delete_pending_since IS NOT NULL ORDER BY delete_pending_since, upload_id").all()}t(L,"pendingUploadDeletes");async function u(a,e,r=d()){const i=(await n(e)).prepare("UPDATE uploads SET delete_pending_since = COALESCE(delete_pending_since, ?) WHERE upload_id = ?");for(const s of a)await i.run(r,s)}t(u,"markUploadsDeletePending");async function O(a,e){const r=(await n(e)).prepare("INSERT INTO upload_uses (upload_id, run_id, path) VALUES (?, ?, ?)");for(const i of a)await r.run(i.upload_id,i.run_id,i.path)}t(O,"insertUploadUses");async function D(a,e){await(await n(e)).prepare("DELETE FROM upload_uses WHERE upload_id = ? AND run_id = ? AND path = ?").run(a.upload_id,a.run_id,a.path)}t(D,"deleteUploadUse");async function U(a,e,r){await(await n(r)).prepare("UPDATE uploads SET size = ? WHERE upload_id = ?").run(e,a)}t(U,"setUploadSize");async function x(a,e){return await(await n(e)).prepare("SELECT upload_id, run_id, path FROM upload_uses WHERE path = ? ORDER BY run_id LIMIT 1").get(a)??null}t(x,"uploadUseAt");async function y(a,e){const r=await n(e);if(!a.length)return[];const i=a.map(()=>"?").join(","),s=(await r.prepareUncached(`SELECT DISTINCT upload_id FROM upload_uses WHERE run_id IN (${i})`).all(...a)).map(o=>o.upload_id);await r.prepareUncached(`DELETE FROM upload_uses WHERE run_id IN (${i})`).run(...a);const p=await _(s,async o=>!await r.prepare("SELECT 1 FROM upload_uses WHERE upload_id = ? LIMIT 1").get(o));return await u(p,r),p}t(y,"releaseRunUploads");async function N(a,e){return(await(await n(e)).prepare(`SELECT upload_id FROM uploads u WHERE delete_pending_since IS NULL AND created_at <= ?
|
|
2
|
+
AND NOT EXISTS (SELECT 1 FROM upload_uses x WHERE x.upload_id = u.upload_id)`).all(a)).map(r=>r.upload_id)}t(N,"staleUnusedUploads");async function g(a,e){await(await n(e)).prepare(`INSERT INTO shares (share_id, source_space, source_path, storage_key, url, created_by, created_at, expires_at, status, object_deleted_at)
|
|
3
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'on', NULL)`).run(a.share_id,a.source_space,a.source_path,a.storage_key,a.url,a.created_by,a.created_at,a.expires_at)}t(g,"insertShare");async function A(a,e){return await(await n(e)).prepare("SELECT * FROM shares WHERE share_id = ?").get(a)??null}t(A,"getShare");async function C(a,e){return a===null?await(await n(e)).prepare("SELECT * FROM shares ORDER BY created_at DESC, share_id").all():await(await n(e)).prepare("SELECT * FROM shares WHERE created_by = ? ORDER BY created_at DESC, share_id").all(a)}t(C,"listShares");async function c(a,e){await(await n(e)).prepare("UPDATE shares SET status = 'off' WHERE share_id = ?").run(a)}t(c,"turnShareOff");async function H(a,e){const r=await n(e),i=(await r.prepare("SELECT share_id FROM shares WHERE created_by = ? AND status = 'on'").all(a)).map(s=>s.share_id);return await r.prepare("UPDATE shares SET status = 'off' WHERE created_by = ? AND status = 'on'").run(a),i}t(H,"turnSharesOffFor");async function W(a=d(),e){const r=await n(e),i=(await r.prepare("SELECT share_id FROM shares WHERE status = 'on' AND expires_at IS NOT NULL AND expires_at <= ?").all(a)).map(s=>s.share_id);for(const s of i)await c(s,r);return i}t(W,"expireShares");async function m(a){return await(await n(a)).prepare("SELECT * FROM shares WHERE status = 'off' AND object_deleted_at IS NULL ORDER BY created_at, share_id").all()}t(m,"sharesOwingObjectDelete");async function M(a,e,r=d()){await(await n(e)).prepare("UPDATE shares SET object_deleted_at = COALESCE(object_deleted_at, ?) WHERE share_id = ?").run(r,a)}t(M,"markShareObjectDeleted");async function F(a,e,r=d()){const i=await n(e),s=(await i.prepare("SELECT upload_id FROM uploads WHERE grantee = ? AND delete_pending_since IS NULL").all(a)).map(p=>p.upload_id);return await u(s,i,r),s}t(F,"markGranteeUploadsDeletePending");export{f as deleteUploadRow,D as deleteUploadUse,W as expireShares,A as getShare,T as getUpload,g as insertShare,w as insertUpload,O as insertUploadUses,C as listShares,F as markGranteeUploadsDeletePending,M as markShareObjectDeleted,u as markUploadsDeletePending,L as pendingUploadDeletes,y as releaseRunUploads,U as setUploadSize,m as sharesOwingObjectDelete,N as staleUnusedUploads,c as turnShareOff,H as turnSharesOffFor,x as uploadUseAt};
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
/** The documents delivery may consider for one reader: rule rows of the
|
|
2
|
-
* owners in the reader's view, joined to their objects and documents, and
|
|
3
|
-
* filtered by `canRead`. */
|
|
4
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
5
1
|
import type { ObjectRow, Reader, RuleOn } from '../../graph/types.js';
|
|
6
2
|
import type { ProfileManifest } from '../../../types.js';
|
|
7
3
|
import { type NodeConfigSubject } from '../subject.js';
|
|
8
4
|
import type { Rung } from '../schema.js';
|
|
9
5
|
import type { DeliveryDoc } from './types.js';
|
|
6
|
+
import type { CanvasDb } from '../../canvas/db.js';
|
|
10
7
|
export declare function ownerHandle(owner: ObjectRow): string;
|
|
11
8
|
/** The key that names one owner exactly in `delivery_limits`: `<type>:<handle>`,
|
|
12
9
|
* the typed form `resolveName` accepts (`repo:crouter`, `person:user`, `app:terminal`). */
|
|
@@ -18,10 +15,10 @@ export declare function typedLimitKey(owner: ObjectRow): string;
|
|
|
18
15
|
export declare function deliveryLimitFor(manifest: ProfileManifest | null, owner: ObjectRow, reader?: Reader): Rung;
|
|
19
16
|
/** Documents with a rule on one of `on` whose owner is in the reader's view,
|
|
20
17
|
* in view order. At `boot` a node's own documents come in even without a boot rule. */
|
|
21
|
-
export declare function loadCorpus(db:
|
|
18
|
+
export declare function loadCorpus(db: CanvasDb, reader: Reader, on: RuleOn[]): Promise<DeliveryDoc[]>;
|
|
22
19
|
/** One document as a delivery document for `reader`, with all its rules (an explicit read). */
|
|
23
|
-
export declare function deliveryDocOf(db:
|
|
20
|
+
export declare function deliveryDocOf(db: CanvasDb, reader: Reader, doc: ObjectRow): Promise<DeliveryDoc>;
|
|
24
21
|
/** Every listed document of one owner the reader can read, for prefix listings. */
|
|
25
|
-
export declare function listingCorpus(db:
|
|
22
|
+
export declare function listingCorpus(db: CanvasDb, reader: Reader, owner: ObjectRow): Promise<DeliveryDoc[]>;
|
|
26
23
|
/** The node reader's gate subject, with `repo` from the reader's eligible repos (cwd's, then its profile projects'). */
|
|
27
|
-
export declare function nodeSubject(_db:
|
|
24
|
+
export declare function nodeSubject(_db: CanvasDb, reader: Reader): Promise<NodeConfigSubject>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
WHERE o.type = 'document' AND o.deleted_at IS NULL AND ${e} ORDER BY o.rowid`).all(...
|
|
3
|
-
ORDER BY number DESC LIMIT 1`).get(e.rowid,...
|
|
1
|
+
var $=Object.defineProperty;var r=(n,e)=>$(n,"name",{value:e,configurable:!0});import{canRead as D}from"../../graph/access.js";import{bodyOf as k}from"../../graph/bodies.js";import{resolveName as M,viewOf as m}from"../../graph/names.js";import{rulesForOwners as S,rulesOf as R}from"../../graph/rules.js";import{loadExactProfileManifest as L}from"../../profiles/manifest.js";import{assembleNodeSubject as C}from"../subject.js";import{filterAsync as N,mapAsync as _}from"../../async-array.js";function y(n){return n.type==="node"?n.id:n.name}r(y,"ownerHandle");function H(n){return`${n.type}:${y(n)}`}r(H,"typedLimitKey");function b(n,e,t){if(t?.class==="node"&&t.profile!==null&&t.profile.rowid===e.rowid)return"content";const o=n?.delivery_limits;return o?o[H(e)]??o[y(e)]??"content":"content"}r(b,"deliveryLimitFor");async function h(n,e){if(e.class!=="node"||e.profile===null)return null;const t=await n.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'profile'").get(e.profile.rowid);if(!t)throw new Error(`profile object ${e.profile.id} has no profile identity`);return L(t.external_id).manifest}r(h,"readerManifest");async function f(n,e,t){return await n.prepareUncached(`SELECT o.*, d.heads_key, d.unlisted, d.source_path FROM objects o JOIN documents d ON d.object = o.rowid
|
|
2
|
+
WHERE o.type = 'document' AND o.deleted_at IS NULL AND ${e} ORDER BY o.rowid`).all(...t)}r(f,"documentRows");async function A(n,e){const t=e.heads_key.split(","),o=await n.prepareUncached(`SELECT body_hash FROM revisions WHERE document = ? AND rev_id IN (${t.map(()=>"?").join(",")})
|
|
3
|
+
ORDER BY number DESC LIMIT 1`).get(e.rowid,...t);if(!o)throw new Error(`document ${e.id} has no head revision ${e.heads_key}`);return o.body_hash}r(A,"headBodyHash");function E(n,e,t){const o=new Map;return{view:t,readable:r(async i=>{let s=o.get(i.rowid);return s===void 0&&o.set(i.rowid,s=await D(n,e,i)),s},"readable")}}r(E,"resolveContext");async function j(n,e,t,o,i,s){const{view:w}=t,u=w.findIndex(O=>O.rowid===i.owner),l=u>=0?w[u]:await n.prepare("SELECT * FROM objects WHERE rowid = ?").get(i.owner),p=y(l),d=await M(n,e,i.name,t),a=await A(n,i),{heads_key:c,unlisted:g,source_path:v,...x}=i;return{object:x,owner:l,ownerHandle:p,viewRank:u>=0?u:w.length,ownNode:e.class==="node"&&i.owner===e.node.rowid,shipped:v!==null,kind:i.kind==="preference"?"preference":"knowledge",name:i.name,displayName:"object"in d&&d.object.rowid===i.rowid?i.name:`${p}/${i.name}`,preview:i.preview,unlisted:g!==0,headsKey:c,bodyHash:a,body:r(()=>k(a,v),"body"),rules:s,limit:b(o,l,e)}}r(j,"toDeliveryDoc");async function J(n,e,t){const o=await m(n,e),i=E(n,e,o),s=await h(n,e),w=new Map;for(const a of await S(n,t,o.map(c=>c.rowid)))w.set(a.object,[...w.get(a.object)??[],a]);const u=e.class==="node"&&t.includes("boot")?await f(n,"o.owner = ?",[e.node.rowid]):[],l=[...new Set([...w.keys(),...u.map(a=>a.rowid)])],p=l.length===0?[]:await f(n,`o.rowid IN (${l.map(()=>"?").join(",")})`,l),d=new Map(o.map((a,c)=>[a.rowid,c]));return await _((await N(p,i.readable)).sort((a,c)=>d.get(a.owner)-d.get(c.owner)||a.rowid-c.rowid),async a=>await j(n,e,i,s,a,w.get(a.rowid)??[]))}r(J,"loadCorpus");async function P(n,e,t){const o=(await f(n,"o.rowid = ?",[t.rowid]))[0];if(!o)throw new Error(`document ${t.id} has no documents row`);return await j(n,e,E(n,e,await m(n,e)),await h(n,e),o,await R(n,o))}r(P,"deliveryDocOf");async function q(n,e,t){const o=E(n,e,await m(n,e)),i=await h(n,e);return await _(await N(await f(n,"o.owner = ? AND d.unlisted = 0",[t.rowid]),o.readable),async s=>await j(n,e,o,i,s,await R(n,s)))}r(q,"listingCorpus");async function z(n,e){if(e.class!=="node")throw new Error(`nodeSubject needs a node reader, got ${e.class}`);const t=await C(e.node.id,[...e.repos,...e.projectRepos]);if(t===null)throw new Error(`no node ${e.node.id}`);return t}r(z,"nodeSubject");export{P as deliveryDocOf,b as deliveryLimitFor,q as listingCorpus,J as loadCorpus,z as nodeSubject,y as ownerHandle,H as typedLimitKey};
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/** The one-phase delivery transaction behind `POST /v1/nodes/:id/delivery`:
|
|
2
|
-
* load the node's ledger, render the activity, record a `deliver` watch and a
|
|
3
|
-
* `read` event for every document delivered at content, save the ledger. The
|
|
4
|
-
* caller runs it inside one `withCanvasWrite`, so exposures, watches and
|
|
5
|
-
* events land together or not at all. */
|
|
6
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
7
1
|
import { type ReposFn } from '../../graph/reader.js';
|
|
8
2
|
import type { ObjectRow, Reader } from '../../graph/types.js';
|
|
9
3
|
import type { DeliveryActivity, DeliveryCommandDTO } from '../../../api/dto/delivery.js';
|
|
@@ -11,6 +5,7 @@ import type { RefMeta } from '../../runtime/broker-protocol.js';
|
|
|
11
5
|
import type { NodeConfigSubject } from '../subject-fields.js';
|
|
12
6
|
import { type DeliveryPlan } from './plan.js';
|
|
13
7
|
import { type DeliveredDoc } from './render-event.js';
|
|
8
|
+
import type { CanvasDb } from '../../canvas/db.js';
|
|
14
9
|
export interface DeliveryRequestInput {
|
|
15
10
|
activity: DeliveryActivity;
|
|
16
11
|
subject?: string;
|
|
@@ -27,12 +22,12 @@ export interface DeliveryResult {
|
|
|
27
22
|
}
|
|
28
23
|
/** Record the content deliveries: a `deliver` watch at the delivered heads, a `read` event each,
|
|
29
24
|
* and a `loaded` row in the analytics memory log (a full body that entered the context). */
|
|
30
|
-
export declare function recordContentDelivery(db:
|
|
25
|
+
export declare function recordContentDelivery(db: CanvasDb, reader: Reader, delivered: readonly DeliveredDoc[], reposFn?: ReposFn): Promise<void>;
|
|
31
26
|
/** Activities only a dry run performs: a live node's workspace-open arrives
|
|
32
27
|
* inside its boot, and a document read goes through the read route. */
|
|
33
28
|
export declare const DRY_RUN_ONLY: readonly DeliveryActivity[];
|
|
34
29
|
/** One delivery for a live node. Call inside `withCanvasWrite`. */
|
|
35
|
-
export declare function deliver(db:
|
|
30
|
+
export declare function deliver(db: CanvasDb, reader: Reader, req: DeliveryRequestInput): Promise<DeliveryResult>;
|
|
36
31
|
/** A node that does not exist, described by what delivery reads of one:
|
|
37
32
|
* the directory it would work in, its profile and app, and the fields rule
|
|
38
33
|
* `if` conditions see. Every field but `cwd` has a default. */
|
|
@@ -50,27 +45,27 @@ export interface HypotheticalNode {
|
|
|
50
45
|
}
|
|
51
46
|
/** Fill a hypothetical node's unset fields from a live node, so `--node` with
|
|
52
47
|
* `--cwd` or `--profile` starts from that node and dials away from it. */
|
|
53
|
-
export declare function hypotheticalFrom(nodeId: string, h: Partial<HypotheticalNode>): HypotheticalNode
|
|
48
|
+
export declare function hypotheticalFrom(nodeId: string, h: Partial<HypotheticalNode>): Promise<HypotheticalNode>;
|
|
54
49
|
/** The reader and gate subject of a node that does not exist. Resolving its
|
|
55
50
|
* app, profile and repos may create their owner objects, so call it only
|
|
56
51
|
* inside a transaction that rolls back. */
|
|
57
|
-
export declare function hypotheticalReader(db:
|
|
52
|
+
export declare function hypotheticalReader(db: CanvasDb, h: HypotheticalNode): Promise<{
|
|
58
53
|
reader: Extract<Reader, {
|
|
59
54
|
class: 'node';
|
|
60
55
|
}>;
|
|
61
56
|
subject: NodeConfigSubject;
|
|
62
|
-
}
|
|
57
|
+
}>;
|
|
63
58
|
/** A dry run for inspection: render against an empty ledger and record nothing.
|
|
64
59
|
* `subjectOverride` replaces fields of the gate subject — the node's own, or
|
|
65
60
|
* `baseSubject` for a hypothetical reader. */
|
|
66
|
-
export declare function inspect(db:
|
|
61
|
+
export declare function inspect(db: CanvasDb, reader: Reader, req: DeliveryRequestInput, subjectOverride?: Partial<NodeConfigSubject>, baseSubject?: NodeConfigSubject): Promise<{
|
|
67
62
|
result: DeliveryResult;
|
|
68
63
|
plan: DeliveryPlan | null;
|
|
69
|
-
}
|
|
64
|
+
}>;
|
|
70
65
|
/** Watched documents with a revision created after `since` that the node did not author (D8). */
|
|
71
|
-
export declare function changedWhileDone(db:
|
|
66
|
+
export declare function changedWhileDone(db: CanvasDb, node: ObjectRow, since: string): Promise<Array<{
|
|
72
67
|
doc: ObjectRow;
|
|
73
68
|
from: number | null;
|
|
74
69
|
to: number;
|
|
75
70
|
authors: string[];
|
|
76
|
-
}
|
|
71
|
+
}>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),delivered:[...e.delivered,...o.delivered]}}
|
|
1
|
+
var I=Object.defineProperty;var d=(t,e)=>I(t,"name",{value:e,configurable:!0});import{dirname as L}from"node:path";import{clearLedger as F,demoteTranscript as $,freezePreferences as b,loadLedger as M,saveLedger as P}from"../../graph/exposures.js";import{recordWatch as T}from"../../graph/watches.js";import{publish as H}from"../../graph/events.js";import{viewOf as x}from"../../graph/names.js";import{checkoutsForCwd as y}from"../../graph/repo-sync/repos.js";import{liveLookups as W,profileObject as Y,viewRepos as U}from"../../graph/reader.js";import{ownerForGrantee as B}from"../../graph/objects.js";import{resolveName as G}from"../../graph/names.js";import{SCOPE_VOCABULARY as J}from"../../scopes.js";import{getNode as K}from"../../canvas/index.js";import{recordMemoryReadsIn as V}from"../../canvas/memory-reads.js";import{lookupProfile as X}from"../../profiles/manifest.js";import{getDefaultProfileId as z}from"../../profiles/default-binding.js";import{effectiveScopes as Q,profileNameFor as Z,scopeForCwd as q}from"../subject-fields.js";import{spineDepth as ee}from"../subject.js";import{appForNode as te}from"../../canvas/node-agent-paths.js";import{interpolateNodePaths as oe}from"../../canvas/paths.js";import{readableProjectForScopes as ne}from"../../spaces/permissions.js";import{ApiError as u}from"../../../api/errors.js";import{buildContextBearings as re}from"../../runtime/bearings.js";import{deliveryDocOf as g,listingCorpus as ie,loadCorpus as w,nodeSubject as j}from"./corpus.js";import{listingPrefixes as ae}from"./listings.js";import{planDelivery as se}from"./plan.js";import{renderEvent as N,renderExplicitRead as O}from"./render-event.js";import{renderConfigDelta as ce,renderKnowledge as de,renderPreferences as k,renderWorkspaceOpen as _}from"./render-boot.js";import{mapAsync as le}from"../../async-array.js";function f(t){if(t.class!=="node")throw new Error(`delivery needs a node reader, got ${t.class}`);return t}d(f,"nodeOf");const R=-1;function v(t){return t.node.rowid===R}d(v,"isHypothetical");async function S(t,e){if(!v(e))return await te(e.node.id);const o=await t.prepare("SELECT external_id FROM identities WHERE object = ?").get(e.app.rowid);if(!o)throw new Error(`app object ${e.app.id} has no identity`);return o.external_id}d(S,"granteeOf");async function pe(t,e,o,r=async i=>await y(t,i)){const i=f(e).node,c=new Set,n=new Date().toISOString(),a=[];for(const{doc:s,level:l}of o)l!=="content"||c.has(s.object.rowid)||(c.add(s.object.rowid),await T(t,i,s.object,"deliver",{readHeadsKey:s.headsKey}),await H(t,{event:"read",object:s.object,actor:i,attrs:{}},r),a.push({name:s.name,scope:s.ownerHandle,at:n,type:"loaded"}));v(f(e))||await V(t,i.id,a)}d(pe,"recordContentDelivery");async function E(t,e,o){const r=(await y(t,L(o))).filter(i=>!e.repos.some(c=>c.rowid===i.repo.rowid));return r.length===0?e:{...e,repos:[...e.repos,...r.map(i=>i.repo)],checkouts:[...e.checkouts,...r]}}d(E,"fileReadReader");async function ue(t,e,o){const r=await S(t,e);if(!(o.startsWith("/")&&(process.platform!=="linux"&&r==="app:terminal"||ne(o,r,e.scopes??[],null))))throw new u(403,"scope_missing","read file is outside the run mounts")}d(ue,"assertReadableFile");async function me(t){const e=f(t.reader),o=e.node,r=await S(t.db,e),i=await w(t.db,t.reader,["slash-command"]),c=i.map(n=>{const a=n.body();return{name:n.displayName,command_name:n.displayName,description:n.preview,canonical_body:a,execution_body:oe(a,o.id,r)}});return{docs:i,commands:c}}d(me,"slashCommands");function fe(t){if(t.shipped)return"builtin";switch(t.owner.type){case"node":return"node";case"repo":return"project";case"profile":return"profile";default:return"user"}}d(fe,"scopeOf");async function we(t,e){const o=[],r=new Set;for(const i of await x(t,e)){const c=await ie(t,e,i);for(const n of c){o.push({name:n.displayName,kind:n.kind,scope:fe(n),shortForm:n.preview,gatewayVisible:!n.shipped}),r.add(n.displayName);const a=n.displayName===n.name?"":`${n.ownerHandle}/`;for(const s of ae(c,n.name))r.add(`${a}${s}`)}}return{refs:o,names:[...r]}}d(we,"composerNames");async function C(t,e){const o=f(t.reader),{db:r,ledger:i}=t,c=d(()=>{if(typeof e.subject!="string"||e.subject==="")throw new u(400,"usage",`delivery activity ${e.activity} requires a subject`);return e.subject},"requireSubject");switch(e.activity){case"boot":{if(e.inherited===!0){for(const[s,l]of i.objects)if(l.transcript===void 0)i.objects.delete(s);else{const{system:p,...m}=l;i.objects.set(s,m)}for(const[s,l]of i.listed)l.transcript===void 0?i.listed.delete(s):i.listed.set(s,{transcript:l.transcript});return i.preferenceSnapshot=null,{result:{content:"",inherited:!0},delivered:[]}}const n=v(o)?await ye(t):await re(o.node.id,t),a=await k({...t,channel:"system"});return b(i,a.content),{result:{content:n.content},delivered:[...n.delivered,...a.delivered]}}case"system-prompt":{if(i.preferenceSnapshot!==null)return{result:{content:i.preferenceSnapshot},delivered:[]};const n=await k({...t,channel:"system"});return{result:{content:b(i,n.content)},delivered:n.delivered}}case"compact":{for(const n of await w(r,o,["pre-command"]))$(i,n.object.rowid);return{result:{content:""},delivered:[]}}case"persona":{const n=await ce(t);return{result:{content:n.content},delivered:n.delivered}}case"file-read":{const n=c();await ue(r,o,n);const a=await E(r,o,n),s={...t,reader:a},l=await N(s,"file-read",{absoluteFile:n},await w(r,a,["file-read"]));return{result:{content:l.content},delivered:l.delivered}}case"command":case"pre-command":{const n=await N(t,e.activity,{command:c()});return{result:{content:n.content},delivered:n.delivered}}case"slash-command":{const{docs:n,commands:a}=await me(t);if(e.subject===void 0||e.subject==="")return{result:{content:"",commands:a},delivered:[]};const s=n.findIndex(m=>m.displayName===e.subject||m.name===e.subject);if(s<0)throw new u(404,"not_found",`no slash command named ${e.subject}`);const l=n[s],p=await O(t,l,!0);return{result:{content:"",execution_body:a[s].execution_body,blocks:p.attachments===""?[]:[p.attachments]},delivered:[{doc:l,level:"content"},...p.delivered]}}case"workspace-open":{const n=await _(t);return{result:{content:n.content},delivered:n.delivered}}case"document-read":{const n=await D(r,o,c()),a=await O(t,await g(r,o,n),!0);return{result:{content:a.attachments},delivered:a.delivered}}case"names":return{result:{content:"",...await we(r,o)},delivered:[]};default:throw new u(400,"usage",`unknown delivery activity ${String(e.activity)}`)}}d(C,"render");async function ye(t){const e=await de(t),o=await _(t);return{content:[e.content,o.content].filter(r=>r!=="").join(`
|
|
2
|
+
`),delivered:[...e.delivered,...o.delivered]}}d(ye,"hypotheticalBearings");async function D(t,e,o){const r=await G(t,e,o);if("object"in r&&r.object.type==="document")return r.object;throw"ambiguous"in r?new u(409,"ambiguous",`${o} names ${r.ambiguous.length} documents; name one as <type>:<owner>/<name>`):new u(404,"not_found",`no document ${o} the reader can read`)}d(D,"readDocument");const ve=["workspace-open","document-read"];async function Ve(t,e,o){if(ve.includes(o.activity))throw new u(400,"usage",`delivery activity ${o.activity} is available to a dry run only`);const r=f(e).node;o.activity==="boot"&&o.inherited!==!0&&await F(t,r.rowid);const i=await M(t,r.rowid),c={db:t,reader:e,subject:await j(t,e),ledger:i,channel:"transcript"},{result:n,delivered:a}=await C(c,o);return await pe(t,e,a),await P(t,i),n}d(Ve,"deliver");const he={boot:"boot","workspace-open":"workspace-open","file-read":"file-read","document-read":"document-read",command:"command","pre-command":"pre-command","slash-command":"slash-command"};async function Xe(t,e){const o=await K(t);if(o===null)throw new u(404,"not_found",`no node ${t}`);return{cwd:e.cwd??o.cwd,profile:e.profile!==void 0?e.profile:o.profile_id,grantee:e.grantee??o.grantee,kind:e.kind??o.kind,mode:e.mode??o.mode,lifecycle:e.lifecycle??o.lifecycle,hasManager:e.hasManager??(o.parent??null)!==null,depth:e.depth??await ee(t)}}d(Xe,"hypotheticalFrom");function be(t,e){if(t===null)return null;if(t===void 0||t==="")return z(e);const o=X(t);if(o.kind!=="resolved"){const r=`no profile ${t}`;throw new u(404,"not_found",r,{error:"not_found",message:r,next:"List profile ids and names with `crtr profile list`."})}return o.entry.profileId}d(be,"resolveProfileId");async function ze(t,e){const o=await B(t,e.grantee??"app:terminal"),r=be(e.profile,e.cwd),i=await U(e.cwd,r,async p=>await y(t,p),W(t)),{repos:c}=i,n=e.mode??"base",s={class:"node",node:{rowid:R,id:"hypothetical",type:"node",kind:e.kind??"general",owner:o.rowid,privacy:"private",name:"hypothetical",preview:"",created_at:new Date(0).toISOString(),deleted_at:null},app:o,scopes:[...J],cwd:e.cwd,...i,profile:r===null?null:await Y(t,r,o)},l={kind:e.kind??"general",mode:n,lifecycle:e.lifecycle??(n==="orchestrator"?"resident":"terminal"),hasManager:e.hasManager??!0,cwd:e.cwd,scope:q(e.cwd),orchestration:{depth:e.depth??0},profile:Z(r),scopes:Q(null),repo:[...c,...i.projectRepos].map(p=>p.name)};return{reader:s,subject:l}}d(ze,"hypotheticalReader");async function Qe(t,e,o,r,i){const n={node:f(e).node.rowid,preferenceSnapshot:null,objects:new Map,listed:new Map},a={...i??await j(t,e),...r},s={db:t,reader:e,subject:a,ledger:n,channel:"transcript"},{result:l}=await C(s,o),p=he[o.activity];let m=null;if(p!==void 0){const A=o.activity==="file-read"?{absoluteFile:o.subject}:o.activity==="command"||o.activity==="pre-command"?{command:o.subject}:o.activity==="document-read"&&o.subject!==void 0?{doc:await g(t,e,await D(t,e,o.subject))}:{},h=o.activity==="file-read"&&o.subject!==void 0?await E(t,f(e),o.subject):e;m=await se(t,a,h,await w(t,h,[p]),p,A)}return{result:l,plan:m}}d(Qe,"inspect");async function Ze(t,e,o){const r=await t.prepare(`SELECT o.*, MAX(r.number) AS to_seq, GROUP_CONCAT(DISTINCT a.id) AS authors
|
|
3
3
|
FROM watches w JOIN objects o ON o.rowid = w.object AND o.type = 'document' AND o.deleted_at IS NULL
|
|
4
4
|
JOIN revisions r ON r.document = o.rowid LEFT JOIN objects a ON a.rowid = r.author
|
|
5
5
|
WHERE w.watcher = ? AND r.created_at > ? AND (r.author IS NULL OR r.author != ?)
|
|
6
|
-
GROUP BY o.rowid ORDER BY o.rowid`).all(e.rowid,o,e.rowid)
|
|
6
|
+
GROUP BY o.rowid ORDER BY o.rowid`).all(e.rowid,o,e.rowid);return await le(r,async({to_seq:i,authors:c,...n})=>{const a=await t.prepare("SELECT MAX(number) AS seq FROM revisions WHERE document = ? AND created_at <= ?").get(n.rowid,o);return{doc:n,from:a.seq,to:i,authors:c===null?[]:c.split(",")}})}d(Ze,"changedWhileDone");export{ve as DRY_RUN_ONLY,Ze as changedWhileDone,Ve as deliver,Xe as hypotheticalFrom,ze as hypotheticalReader,Qe as inspect,pe as recordContentDelivery};
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
/** The row-backed delivery planner: for one activity it decides, per corpus
|
|
2
|
-
* document, which rule matched and at what level it delivers. It renders
|
|
3
|
-
* nothing and writes nothing; the ledger and renderers are downstream.
|
|
4
|
-
*
|
|
5
|
-
* - The profile's delivery limit caps `boot` and `workspace-open` only, and
|
|
6
|
-
* never the node's own documents.
|
|
7
|
-
* - At `boot` a node's own document with no boot rule is raised to `name`.
|
|
8
|
-
* - `boot` and `workspace-open` keep bare-name shadowing: the first document
|
|
9
|
-
* in view order with a bare name wins it (per boot block), as `[[name]]`
|
|
10
|
-
* resolves. Every other activity delivers every matching document. */
|
|
11
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
12
1
|
import type { RuleRow } from '../../graph/rules.js';
|
|
13
2
|
import type { Reader, RuleOn } from '../../graph/types.js';
|
|
14
3
|
import { type Rung } from '../schema.js';
|
|
15
4
|
import type { NodeConfigSubject } from '../subject-fields.js';
|
|
16
5
|
import { type GateOutcome } from './match.js';
|
|
17
6
|
import type { DeliveryDoc } from './types.js';
|
|
7
|
+
import type { CanvasDb } from '../../canvas/db.js';
|
|
18
8
|
export type { GateOutcome } from './match.js';
|
|
19
9
|
/** What the activity exposes. An activity invoked without its field matches nothing. */
|
|
20
10
|
export interface DeliveryPayload {
|
|
@@ -64,4 +54,4 @@ export interface DeliveryPlan {
|
|
|
64
54
|
/** Which boot block a record belongs to: the node's own documents ride in the knowledge block whatever their kind. */
|
|
65
55
|
export declare function bootPartitionOf(record: Pick<DeliveryRecord, 'doc'>): 'knowledge' | 'preference';
|
|
66
56
|
/** Plan one activity over an already-loaded corpus (view order, from `loadCorpus`). */
|
|
67
|
-
export declare function planDelivery(db:
|
|
57
|
+
export declare function planDelivery(db: CanvasDb, subject: NodeConfigSubject | null, reader: Reader, corpus: readonly DeliveryDoc[], on: RuleOn, payload?: DeliveryPayload): Promise<DeliveryPlan>;
|