@north-light/cli 0.3.530 → 0.3.531
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 +3 -3
- 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 +1 -1
- 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 +7 -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 +6 -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,11 +1,11 @@
|
|
|
1
|
-
var
|
|
2
|
-
VALUES (?, ?, 'controller', ?, ?, ?, NULL)`).run(
|
|
1
|
+
var w=Object.defineProperty;var n=(t,e)=>w(t,"name",{value:e,configurable:!0});import{randomBytes as c}from"node:crypto";import{withCanvasWrite as E,openDb as d}from"./db.js";function s(t){if(t.kind!=="controller")throw new Error(`wait ${t.wait_id} is not a controller wait`);return{waitId:t.wait_id,nodeId:t.node_id,controllerId:t.target_id,generation:t.generation,createdAt:t.created_at,satisfiedAt:t.satisfied_at}}n(s,"waitFrom");function _(){let t;do t=c(16).toString("hex");while(t==="00000000000000000000000000000000");return t}n(_,"newWaitId");async function f(t,e,i=Date.now()){return await E(async a=>{await a.prepare("UPDATE waits SET satisfied_at = ? WHERE node_id = ? AND kind = 'controller' AND satisfied_at IS NULL").run(i,t);const r=Number((await a.prepare("SELECT COALESCE(MAX(generation), 0) AS generation FROM waits WHERE node_id = ? AND kind = 'controller'").get(t)).generation)+1,o={wait_id:_(),node_id:t,kind:"controller",target_id:e,generation:r,created_at:i,satisfied_at:null};return await a.prepare(`INSERT INTO waits (wait_id, node_id, kind, target_id, generation, created_at, satisfied_at)
|
|
2
|
+
VALUES (?, ?, 'controller', ?, ?, ?, NULL)`).run(o.wait_id,o.node_id,o.target_id,o.generation,o.created_at),s(o)})}n(f,"armControllerWait");async function p(t){const e=await(await d()).prepare("SELECT * FROM waits WHERE node_id = ? AND kind = 'controller' AND satisfied_at IS NULL").get(t);return e===void 0?null:s(e)}n(p,"readControllerWait");async function L(t,e,i,a){if(a??=await d(),e===null)return!1;const r=await a.prepare("SELECT wait_id, generation FROM waits WHERE node_id = ? AND kind = 'controller' AND target_id = ? AND satisfied_at IS NULL").get(t,e);return r===void 0?!1:Number((await a.prepare("UPDATE waits SET satisfied_at = ? WHERE wait_id = ? AND generation = ? AND satisfied_at IS NULL").run(i,r.wait_id,r.generation)).changes)===1}n(L,"settleMatchingControllerWait");async function g(t,e,i,a){a??=await d();const r=await a.prepare(`SELECT w.wait_id, w.generation, target.status AS controller_status
|
|
3
3
|
FROM waits w LEFT JOIN nodes target ON target.node_id = w.target_id
|
|
4
|
-
WHERE w.node_id = ? AND w.kind = 'controller' AND w.target_id = ? AND w.satisfied_at IS NULL`).get(t,e);return
|
|
4
|
+
WHERE w.node_id = ? AND w.kind = 'controller' AND w.target_id = ? AND w.satisfied_at IS NULL`).get(t,e);return r===void 0||r.controller_status==="active"||r.controller_status==="idle"?!1:Number((await a.prepare("UPDATE waits SET satisfied_at = ? WHERE wait_id = ? AND generation = ? AND satisfied_at IS NULL").run(i,r.wait_id,r.generation)).changes)===1}n(g,"settleDeadControllerWait");async function A(){return(await(await d()).prepare("SELECT * FROM waits WHERE kind = 'controller' AND satisfied_at IS NULL").all()).map(s)}n(A,"liveControllerWaits");async function D(t,e,i,a=Date.now()){await t.prepare(`INSERT INTO waits (wait_id, node_id, kind, target_id, generation, created_at, satisfied_at)
|
|
5
5
|
SELECT ?, ?, 'object', ?, 1, ?, NULL
|
|
6
|
-
WHERE NOT EXISTS (SELECT 1 FROM waits WHERE node_id = ? AND kind = 'object' AND target_id = ? AND satisfied_at IS NULL)`).run(
|
|
6
|
+
WHERE NOT EXISTS (SELECT 1 FROM waits WHERE node_id = ? AND kind = 'object' AND target_id = ? AND satisfied_at IS NULL)`).run(_(),e,i,a,e,i)}n(D,"armObjectWait");async function S(t,e,i=null,a=Date.now()){return Number(i===null?(await t.prepare("UPDATE waits SET satisfied_at = ? WHERE kind = 'object' AND target_id = ? AND satisfied_at IS NULL").run(a,e)).changes:(await t.prepare("UPDATE waits SET satisfied_at = ? WHERE kind = 'object' AND target_id = ? AND node_id = ? AND satisfied_at IS NULL").run(a,e,i)).changes)}n(S,"settleObjectWaits");async function T(t,e,i=Date.now()){return Number((await t.prepare("UPDATE waits SET satisfied_at = ? WHERE kind = 'object' AND node_id = ? AND satisfied_at IS NULL").run(i,e)).changes)}n(T,"settleNodeObjectWaits");async function R(t){return t??=await d(),(await t.prepare(`SELECT w.wait_id, w.node_id, w.target_id, w.created_at, o.type AS object_type, o.name AS object_name
|
|
7
7
|
FROM waits w JOIN objects o ON o.id = w.target_id
|
|
8
8
|
WHERE w.kind = 'object' AND w.satisfied_at IS NULL AND o.deleted_at IS NULL
|
|
9
|
-
ORDER BY w.node_id, w.created_at, w.rowid`).all().map(e=>({waitId:e.wait_id,nodeId:e.node_id,objectId:e.target_id,createdAt:e.created_at,objectType:e.object_type,objectName:e.object_name}))}
|
|
9
|
+
ORDER BY w.node_id, w.created_at, w.rowid`).all()).map(e=>({waitId:e.wait_id,nodeId:e.node_id,objectId:e.target_id,createdAt:e.created_at,objectType:e.object_type,objectName:e.object_name}))}n(R,"liveObjectWaitsNamed");async function W(t){return await(await d()).prepare("SELECT 1 FROM waits WHERE node_id = ? AND kind = 'object' AND satisfied_at IS NULL LIMIT 1").get(t)!==void 0}n(W,"hasLiveObjectWait");async function I(t){return await(await d()).prepare(`SELECT 1 FROM waits w JOIN nodes target ON target.node_id = w.target_id
|
|
10
10
|
WHERE w.node_id = ? AND w.kind = 'controller' AND w.satisfied_at IS NULL
|
|
11
|
-
AND target.status IN ('active', 'idle') LIMIT 1`).get(t)!==void 0}
|
|
11
|
+
AND target.status IN ('active', 'idle') LIMIT 1`).get(t)!==void 0}n(I,"hasLiveControllerWait");export{f as armControllerWait,D as armObjectWait,I as hasLiveControllerWait,W as hasLiveObjectWait,A as liveControllerWaits,R as liveObjectWaitsNamed,p as readControllerWait,g as settleDeadControllerWait,L as settleMatchingControllerWait,T as settleNodeObjectWaits,S as settleObjectWaits};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type CanvasDb } from './db.js';
|
|
2
2
|
import type { ManagedWorktree, ManagedWorktreeObservation } from './types.js';
|
|
3
3
|
export declare function worktreeFromRow(row: Record<string, unknown> | undefined): ManagedWorktree | null;
|
|
4
|
-
export declare function readWorktree(nodeId: string): ManagedWorktree | null
|
|
5
|
-
export declare function openWorktree(nodeId: string, worktree: ManagedWorktree, db?:
|
|
4
|
+
export declare function readWorktree(nodeId: string): Promise<ManagedWorktree | null>;
|
|
5
|
+
export declare function openWorktree(nodeId: string, worktree: ManagedWorktree, db?: CanvasDb): Promise<void>;
|
|
6
6
|
export declare function closeWorktree(nodeId: string, input: {
|
|
7
7
|
cleanup: 'pending' | 'complete';
|
|
8
8
|
closedAt: string;
|
|
9
|
-
}): void
|
|
9
|
+
}): Promise<void>;
|
|
10
10
|
/** Complete a worktree close and repoint the node in the same SQL transaction.
|
|
11
11
|
* A close invalidates the active transcript because Pi remains in the old
|
|
12
12
|
* checkout; the next launch starts from the durable base checkout. */
|
|
@@ -15,14 +15,14 @@ export declare function closeWorktreeAndRepoint(nodeId: string, input: {
|
|
|
15
15
|
cleanup: 'pending' | 'complete';
|
|
16
16
|
closedAt: string;
|
|
17
17
|
unbindSession: boolean;
|
|
18
|
-
}): void
|
|
19
|
-
export declare function abandonWorktree(nodeId: string, abandoned: NonNullable<ManagedWorktree['abandoned']>): void
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
export declare function abandonWorktree(nodeId: string, abandoned: NonNullable<ManagedWorktree['abandoned']>): Promise<void>;
|
|
20
20
|
export declare function abandonWorktreeAndRepoint(nodeId: string, input: {
|
|
21
21
|
cwd: string;
|
|
22
22
|
abandoned: NonNullable<ManagedWorktree['abandoned']>;
|
|
23
|
-
}): void
|
|
24
|
-
export declare function recordLandIntent(nodeId: string, intent: NonNullable<ManagedWorktree['land_intent']>): void
|
|
25
|
-
export declare function recordDisposalGrant(nodeId: string, disposal: NonNullable<ManagedWorktree['disposal']>): void
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
export declare function recordLandIntent(nodeId: string, intent: NonNullable<ManagedWorktree['land_intent']>): Promise<void>;
|
|
25
|
+
export declare function recordDisposalGrant(nodeId: string, disposal: NonNullable<ManagedWorktree['disposal']>): Promise<void>;
|
|
26
26
|
export declare function recordSweepAttempt(nodeId: string, input: {
|
|
27
27
|
reason: string;
|
|
28
28
|
detail?: string;
|
|
@@ -31,11 +31,11 @@ export declare function recordSweepAttempt(nodeId: string, input: {
|
|
|
31
31
|
lastAttemptAt: string;
|
|
32
32
|
nextAttemptAt: string;
|
|
33
33
|
quarantined: boolean;
|
|
34
|
-
}): void
|
|
35
|
-
export declare function completeCleanup(nodeId: string): void
|
|
36
|
-
export declare function hasUnreconciledWorktree(nodeId: string): boolean
|
|
37
|
-
export declare function sweepCandidates(now: string): string[]
|
|
38
|
-
export declare function quarantinedWorktrees(): Array<{
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
export declare function completeCleanup(nodeId: string): Promise<void>;
|
|
36
|
+
export declare function hasUnreconciledWorktree(nodeId: string): Promise<boolean>;
|
|
37
|
+
export declare function sweepCandidates(now: string): Promise<string[]>;
|
|
38
|
+
export declare function quarantinedWorktrees(): Promise<Array<{
|
|
39
39
|
nodeId: string;
|
|
40
40
|
worktree: ManagedWorktree;
|
|
41
|
-
}
|
|
41
|
+
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=Object.defineProperty;var a=(e,t)=>p(e,"name",{value:t,configurable:!0});import{openDb as s,withCanvasWrite as _}from"./db.js";import{flatMapAsync as i}from"../async-array.js";function d(e){const t=JSON.stringify(e);if(t===void 0)throw new TypeError("worktree value must be JSON-serializable");return t}a(d,"json");function o(e){if(typeof e=="string")return JSON.parse(e)}a(o,"parse");function l(e){if(e===void 0)return null;const t=o(e.sweep_observed_json),n=e.attempts,r=t===void 0?void 0:{reason:e.sweep_reason,...e.sweep_detail===null?{}:{detail:e.sweep_detail},observed:t,attempts:n,last_attempt:e.sweep_last_at,next_attempt:e.next_attempt_at,...e.quarantined===1?{quarantined:!0}:{}};return{state:e.state,...e.cleanup_state===null?{}:{cleanup:e.cleanup_state},path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created_at,...e.closed_at===null?{}:{closed:e.closed_at},...o(e.abandoned_json)===void 0?{}:{abandoned:o(e.abandoned_json)},...o(e.land_intent_json)===void 0?{}:{land_intent:o(e.land_intent_json)},...r===void 0?{}:{sweep:r},...o(e.disposal_json)===void 0?{}:{disposal:o(e.disposal_json)}}}a(l,"worktreeFromRow");async function c(e){return l(await(await s()).prepare("SELECT * FROM worktrees WHERE node_id = ?").get(e))}a(c,"readWorktree");async function w(e,t,n){n??=await s(),await n.prepare("INSERT INTO worktrees (node_id, state, cleanup_state, path, branch, repo_root, base_ref, base_sha, created_at, closed_at, next_attempt_at, attempts, quarantined, sweep_reason, sweep_detail, sweep_last_at, sweep_observed_json, abandoned_json, land_intent_json, disposal_json) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)").run(e,t.state,t.cleanup??null,t.path,t.branch,t.repo_root,t.base_ref,t.base_sha,t.created,t.closed??null)}a(w,"openWorktree");async function N(e,t){await(await s()).prepare("UPDATE worktrees SET state = 'closed', cleanup_state = ?, closed_at = ?, land_intent_json = NULL, sweep_reason = NULL, sweep_detail = NULL, sweep_last_at = NULL, sweep_observed_json = NULL, next_attempt_at = NULL, attempts = 0, quarantined = 0 WHERE node_id = ?").run(t.cleanup,t.closedAt,e)}a(N,"closeWorktree");async function U(e,t){await _(async n=>{await n.prepare("UPDATE nodes SET cwd = ? WHERE node_id = ?").run(t.cwd,e),t.unbindSession&&await n.prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(t.closedAt,e),await n.prepare("UPDATE worktrees SET state = 'closed', cleanup_state = ?, closed_at = ?, land_intent_json = NULL, sweep_reason = NULL, sweep_detail = NULL, sweep_last_at = NULL, sweep_observed_json = NULL, next_attempt_at = NULL, attempts = 0, quarantined = 0 WHERE node_id = ?").run(t.cleanup,t.closedAt,e)})}a(U,"closeWorktreeAndRepoint");async function f(e,t){await(await s()).prepare("UPDATE worktrees SET state = 'abandoned', abandoned_json = ? WHERE node_id = ? AND abandoned_json IS NULL").run(d(t),e)}a(f,"abandonWorktree");async function b(e,t){await _(async n=>{await n.prepare("UPDATE nodes SET cwd = ? WHERE node_id = ?").run(t.cwd,e),await n.prepare("UPDATE worktrees SET state = 'abandoned', abandoned_json = ? WHERE node_id = ? AND abandoned_json IS NULL").run(d(t.abandoned),e)})}a(b,"abandonWorktreeAndRepoint");async function A(e,t){await(await s()).prepare("UPDATE worktrees SET land_intent_json = ? WHERE node_id = ? AND land_intent_json IS NULL").run(d(t),e)}a(A,"recordLandIntent");async function m(e,t){await(await s()).prepare("UPDATE worktrees SET disposal_json = ? WHERE node_id = ? AND disposal_json IS NULL").run(d(t),e)}a(m,"recordDisposalGrant");async function R(e,t){await(await s()).prepare("UPDATE worktrees SET sweep_reason = ?, sweep_detail = ?, sweep_observed_json = ?, attempts = ?, sweep_last_at = ?, next_attempt_at = ?, quarantined = ? WHERE node_id = ?").run(t.reason,t.detail??null,d(t.observed),t.attempts,t.lastAttemptAt,t.nextAttemptAt,t.quarantined?1:0,e)}a(R,"recordSweepAttempt");async function S(e){await(await s()).prepare("UPDATE worktrees SET state = 'closed', cleanup_state = 'complete', sweep_reason = NULL, sweep_detail = NULL, sweep_last_at = NULL, sweep_observed_json = NULL, next_attempt_at = NULL, attempts = 0, quarantined = 0 WHERE node_id = ?").run(e)}a(S,"completeCleanup");async function T(e){return await(await s()).prepare("SELECT 1 FROM worktrees WHERE node_id = ? AND state != 'abandoned' AND (state = 'open' OR cleanup_state IS NULL OR cleanup_state != 'complete')").get(e)!==void 0}a(T,"hasUnreconciledWorktree");async function D(e){return(await(await s()).prepare("SELECT w.node_id FROM worktrees w JOIN nodes n ON n.node_id = w.node_id WHERE n.status IN ('done', 'dead', 'canceled') AND n.frozen_at IS NULL AND w.state IN ('open', 'closed') AND (w.state = 'open' OR w.cleanup_state IS NULL OR w.cleanup_state != 'complete') AND (w.state = 'closed' OR (n.status = 'done' AND n.final_report IS NOT NULL)) AND (w.next_attempt_at IS NULL OR w.next_attempt_at <= ?) ORDER BY w.next_attempt_at, w.node_id").all(e)).map(({node_id:t})=>t)}a(D,"sweepCandidates");async function j(){return await i(await(await s()).prepare("SELECT node_id FROM worktrees WHERE quarantined = 1 ORDER BY sweep_last_at").all(),async({node_id:e})=>{const t=await c(e);return t===null?[]:[{nodeId:e,worktree:t}]})}a(j,"quarantinedWorktrees");export{f as abandonWorktree,b as abandonWorktreeAndRepoint,N as closeWorktree,U as closeWorktreeAndRepoint,S as completeCleanup,T as hasUnreconciledWorktree,w as openWorktree,j as quarantinedWorktrees,c as readWorktree,m as recordDisposalGrant,A as recordLandIntent,R as recordSweepAttempt,D as sweepCandidates,l as worktreeFromRow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var M=Object.defineProperty;var c=(e,t)=>M(e,"name",{value:t,configurable:!0});import{randomBytes as k}from"node:crypto";import{spawn as _}from"node:child_process";import{PROCESS_GROUP_KILL_GRACE_MS as S,posixProcessGroupSpawnOptions as R,terminateProcessGroup as V}from"../../../hook-process.js";import{isRecord as L}from"../../../shared/predicates.js";import{diag as x}from"../../io.js";import{LIFECYCLE_CATALOG as O}from"../lifecycle-catalog.js";import{getNode as A}from"../../canvas/canvas.js";import{buildAppProcessEnv as C}from"../../runtime/spawn-env.js";import{appProcessSandboxed as D,launchAppProcess as G}from"../../spaces/process.js";const P=10*1024*1024;async function H(e,t,n){try{const r=await B(e,t,n);r.ok||x(`crtr: ${g(e)} failed: ${r.error.code}: ${r.error.message}`)}catch(r){x(`crtr: ${g(e)} failed: ${w(r)}`)}}c(H,"invokeLifecycleHook");async function te(e,t){if(e.length===0)return;const{hookTimeoutMs:n,eventBudgetMs:r}=O[e[0].event],s=Date.now()+r;for(const o of e){const a=s-Date.now(),u=Math.min(n,a-S);if(u<=0){x(`crtr: lifecycle hook event ${o.event} exceeded its ${r}ms aggregate budget; skipped ${g(o)}`);return}await H(o,t,u)}}c(te,"invokeLifecycleHooks");async function re(e,t){if(e.length===0)return null;const{hookTimeoutMs:n,eventBudgetMs:r}=O["node:create"],s=Date.now()+r;for(const o of e){const a=s-Date.now(),u=Math.min(n,a-S);if(u<=0)return T(o,`lifecycle hook event node:create exceeded its ${r}ms aggregate budget`);try{const i=await B(o,t,u);if(!i.ok)return{hook:o,message:i.error.message,next:i.error.next??E(o)}}catch(i){return T(o,w(i))}}return null}c(re,"invokeBlockingLifecycleHooks");function T(e,t){return{hook:e,message:`${g(e)} failed: ${t}`,next:E(e)}}c(T,"refusal");function ne(e){return E(e)}c(ne,"lifecycleHookAttribution");async function B(e,t,n){const r=e.event==="node:create"?N(e,t):I(e,t),s=D()?await J(e,t,JSON.stringify(r),n):await q(e,JSON.stringify(r),n);if(s.signal!==null)throw new Error(`executable was killed by signal ${s.signal}`);const o=K(s.stdout);return o.ok&&s.status!==0&&x(`crtr: ${g(e)} returned ok:true but exited ${s.status} (honoring the envelope)`),o}c(B,"executeLifecycleHook");function I(e,t){return{protocolVersion:1,op:e.op,event:e.event,phase:e.phase,operationId:k(16).toString("hex"),node:t.node,runtime:t.runtime,context:{cwd:t.node.cwd}}}c(I,"nodeRequest");function N(e,t){return{protocolVersion:1,op:e.op,event:"node:create",phase:"before",operationId:k(16).toString("hex"),create:t.create,runtime:t.runtime,context:{cwd:t.create.cwd}}}c(N,"createRequest");async function J(e,t,n,r){const s=e.event==="node:create",o=s?t.create.cwd:t.node.cwd,a=s?void 0:t.node.id,u=s?t.app:A(a)?.grantee;if(!u)throw new Error(`missing app for lifecycle hook ${e.event}`);const i=C(o,t.runtime.profile,u),m=await G({...s?{app:u}:{nodeId:a},command:[e.executable,"--crtr-hook-protocol","1"],cwd:e.plugin.root,pluginRoot:e.plugin.root,env:i,stdin:n,stdoutBytes:P,stderrBytes:64*1024});let l;try{const p=await Promise.race([m.completion,new Promise((b,f)=>{l=setTimeout(()=>{m.stop().then(()=>f(new Error(`executable timed out after ${r}ms`)),f)},r)})]);if(p.stdoutTruncated)throw new Error("stdout exceeded the 10 MiB cap");return{stdout:p.stdout,status:p.exitCode,signal:p.signal}}finally{l&&clearTimeout(l)}}c(J,"runSandboxedLifecycleProcess");async function q(e,t,n){let r;try{r=_(e.executable,["--crtr-hook-protocol","1"],{cwd:e.plugin.root,env:process.env,stdio:["pipe","pipe","inherit"],...R()})}catch(s){throw new Error(`executable could not be run (${w(s)})`)}return new Promise((s,o)=>{let a=0;const u=[];let i,m=!1,l=!1,p=null,b=null,f;const y=c(()=>{if(!(!m||i!==void 0&&!l)){if(f!==void 0&&clearTimeout(f),i?.kind==="timeout")return o(new Error(`executable timed out after ${n}ms`));if(i?.kind==="output_limit")return o(new Error("stdout exceeded the 10 MiB cap"));if(i?.kind==="spawn")return o(new Error(`executable could not be run (${w(i.error)})`));if(i?.kind==="cleanup")return o(new Error(`executable cleanup failed (${w(i.error)})`));s({stdout:Buffer.concat(u).toString("utf8"),status:p,signal:b})}},"finish"),$=c(d=>{i===void 0&&(i=d,f!==void 0&&clearTimeout(f),V(r).then(()=>{l=!0,y()},h=>{i={kind:"cleanup",error:h},l=!0,y()}))},"terminate");r.stdout.on("data",d=>{if(a+=d.byteLength,a>P)return $({kind:"output_limit"});u.push(d)}),r.once("error",d=>{if(r.pid===void 0){i={kind:"spawn",error:d},m=!0,l=!0,y();return}$({kind:"spawn",error:d})}),r.once("close",(d,h)=>{p=d,b=h,m=!0,y()}),f=setTimeout(()=>$({kind:"timeout"}),n),r.stdin.end(t)})}c(q,"runLifecycleProcess");function K(e){let t;try{t=JSON.parse(e.trim())}catch{throw new Error("stdout was not a single JSON envelope")}if(!L(t)||t.protocolVersion!==1)throw new Error("stdout was not a protocolVersion: 1 envelope");if(t.ok===!0&&v(t,["protocolVersion","ok"]))return{protocolVersion:1,ok:!0};if(t.ok!==!1||!v(t,["protocolVersion","ok","error"]))throw new Error("response envelope had missing or extra fields");const n=t.error;if(!L(n)||!v(n,["code","message"],["next"])||typeof n.code!="string"||n.code===""||typeof n.message!="string"||n.message===""||n.next!==void 0&&typeof n.next!="string")throw new Error("failure envelope had invalid error fields");return{protocolVersion:1,ok:!1,error:{code:n.code,message:n.message,...n.next===void 0?{}:{next:n.next}}}}c(K,"parseEnvelope");function v(e,t,n=[]){return t.every(r=>Object.hasOwn(e,r))&&Object.keys(e).every(r=>t.includes(r)||n.includes(r))}c(v,"exactKeys");function g(e){return`plugin "${e.plugin.name}" lifecycle hook "${e.op}" for ${e.event}`}c(g,"label");function E(e){return`Refused by plugin ${e.plugin.name}, op ${e.op}.`}c(E,"attribution");function w(e){return e instanceof Error?e.message:String(e)}c(w,"describeError");export{re as invokeBlockingLifecycleHooks,H as invokeLifecycleHook,te as invokeLifecycleHooks,ne as lifecycleHookAttribution};
|
|
1
|
+
var M=Object.defineProperty;var c=(e,t)=>M(e,"name",{value:t,configurable:!0});import{randomBytes as k}from"node:crypto";import{spawn as _}from"node:child_process";import{PROCESS_GROUP_KILL_GRACE_MS as S,posixProcessGroupSpawnOptions as R,terminateProcessGroup as V}from"../../../hook-process.js";import{isRecord as L}from"../../../shared/predicates.js";import{diag as x}from"../../io.js";import{LIFECYCLE_CATALOG as O}from"../lifecycle-catalog.js";import{getNode as A}from"../../canvas/canvas.js";import{buildAppProcessEnv as C}from"../../runtime/spawn-env.js";import{appProcessSandboxed as D,launchAppProcess as G}from"../../spaces/process.js";const P=10*1024*1024;async function H(e,t,n){try{const r=await B(e,t,n);r.ok||x(`crtr: ${g(e)} failed: ${r.error.code}: ${r.error.message}`)}catch(r){x(`crtr: ${g(e)} failed: ${w(r)}`)}}c(H,"invokeLifecycleHook");async function te(e,t){if(e.length===0)return;const{hookTimeoutMs:n,eventBudgetMs:r}=O[e[0].event],s=Date.now()+r;for(const o of e){const a=s-Date.now(),u=Math.min(n,a-S);if(u<=0){x(`crtr: lifecycle hook event ${o.event} exceeded its ${r}ms aggregate budget; skipped ${g(o)}`);return}await H(o,t,u)}}c(te,"invokeLifecycleHooks");async function re(e,t){if(e.length===0)return null;const{hookTimeoutMs:n,eventBudgetMs:r}=O["node:create"],s=Date.now()+r;for(const o of e){const a=s-Date.now(),u=Math.min(n,a-S);if(u<=0)return T(o,`lifecycle hook event node:create exceeded its ${r}ms aggregate budget`);try{const i=await B(o,t,u);if(!i.ok)return{hook:o,message:i.error.message,next:i.error.next??E(o)}}catch(i){return T(o,w(i))}}return null}c(re,"invokeBlockingLifecycleHooks");function T(e,t){return{hook:e,message:`${g(e)} failed: ${t}`,next:E(e)}}c(T,"refusal");function ne(e){return E(e)}c(ne,"lifecycleHookAttribution");async function B(e,t,n){const r=e.event==="node:create"?N(e,t):I(e,t),s=D()?await J(e,t,JSON.stringify(r),n):await q(e,JSON.stringify(r),n);if(s.signal!==null)throw new Error(`executable was killed by signal ${s.signal}`);const o=K(s.stdout);return o.ok&&s.status!==0&&x(`crtr: ${g(e)} returned ok:true but exited ${s.status} (honoring the envelope)`),o}c(B,"executeLifecycleHook");function I(e,t){return{protocolVersion:1,op:e.op,event:e.event,phase:e.phase,operationId:k(16).toString("hex"),node:t.node,runtime:t.runtime,context:{cwd:t.node.cwd}}}c(I,"nodeRequest");function N(e,t){return{protocolVersion:1,op:e.op,event:"node:create",phase:"before",operationId:k(16).toString("hex"),create:t.create,runtime:t.runtime,context:{cwd:t.create.cwd}}}c(N,"createRequest");async function J(e,t,n,r){const s=e.event==="node:create",o=s?t.create.cwd:t.node.cwd,a=s?void 0:t.node.id,u=s?t.app:(await A(a))?.grantee;if(!u)throw new Error(`missing app for lifecycle hook ${e.event}`);const i=C(o,t.runtime.profile,u),m=await G({...s?{app:u}:{nodeId:a},command:[e.executable,"--crtr-hook-protocol","1"],cwd:e.plugin.root,pluginRoot:e.plugin.root,env:i,stdin:n,stdoutBytes:P,stderrBytes:64*1024});let l;try{const p=await Promise.race([m.completion,new Promise((b,f)=>{l=setTimeout(()=>{m.stop().then(()=>f(new Error(`executable timed out after ${r}ms`)),f)},r)})]);if(p.stdoutTruncated)throw new Error("stdout exceeded the 10 MiB cap");return{stdout:p.stdout,status:p.exitCode,signal:p.signal}}finally{l&&clearTimeout(l)}}c(J,"runSandboxedLifecycleProcess");async function q(e,t,n){let r;try{r=_(e.executable,["--crtr-hook-protocol","1"],{cwd:e.plugin.root,env:process.env,stdio:["pipe","pipe","inherit"],...R()})}catch(s){throw new Error(`executable could not be run (${w(s)})`)}return new Promise((s,o)=>{let a=0;const u=[];let i,m=!1,l=!1,p=null,b=null,f;const y=c(()=>{if(!(!m||i!==void 0&&!l)){if(f!==void 0&&clearTimeout(f),i?.kind==="timeout")return o(new Error(`executable timed out after ${n}ms`));if(i?.kind==="output_limit")return o(new Error("stdout exceeded the 10 MiB cap"));if(i?.kind==="spawn")return o(new Error(`executable could not be run (${w(i.error)})`));if(i?.kind==="cleanup")return o(new Error(`executable cleanup failed (${w(i.error)})`));s({stdout:Buffer.concat(u).toString("utf8"),status:p,signal:b})}},"finish"),$=c(d=>{i===void 0&&(i=d,f!==void 0&&clearTimeout(f),V(r).then(()=>{l=!0,y()},h=>{i={kind:"cleanup",error:h},l=!0,y()}))},"terminate");r.stdout.on("data",d=>{if(a+=d.byteLength,a>P)return $({kind:"output_limit"});u.push(d)}),r.once("error",d=>{if(r.pid===void 0){i={kind:"spawn",error:d},m=!0,l=!0,y();return}$({kind:"spawn",error:d})}),r.once("close",(d,h)=>{p=d,b=h,m=!0,y()}),f=setTimeout(()=>$({kind:"timeout"}),n),r.stdin.end(t)})}c(q,"runLifecycleProcess");function K(e){let t;try{t=JSON.parse(e.trim())}catch{throw new Error("stdout was not a single JSON envelope")}if(!L(t)||t.protocolVersion!==1)throw new Error("stdout was not a protocolVersion: 1 envelope");if(t.ok===!0&&v(t,["protocolVersion","ok"]))return{protocolVersion:1,ok:!0};if(t.ok!==!1||!v(t,["protocolVersion","ok","error"]))throw new Error("response envelope had missing or extra fields");const n=t.error;if(!L(n)||!v(n,["code","message"],["next"])||typeof n.code!="string"||n.code===""||typeof n.message!="string"||n.message===""||n.next!==void 0&&typeof n.next!="string")throw new Error("failure envelope had invalid error fields");return{protocolVersion:1,ok:!1,error:{code:n.code,message:n.message,...n.next===void 0?{}:{next:n.next}}}}c(K,"parseEnvelope");function v(e,t,n=[]){return t.every(r=>Object.hasOwn(e,r))&&Object.keys(e).every(r=>t.includes(r)||n.includes(r))}c(v,"exactKeys");function g(e){return`plugin "${e.plugin.name}" lifecycle hook "${e.op}" for ${e.event}`}c(g,"label");function E(e){return`Refused by plugin ${e.plugin.name}, op ${e.op}.`}c(E,"attribution");function w(e){return e instanceof Error?e.message:String(e)}c(w,"describeError");export{re as invokeBlockingLifecycleHooks,H as invokeLifecycleHook,te as invokeLifecycleHooks,ne as lifecycleHookAttribution};
|
|
@@ -15,16 +15,16 @@ export type ConversationWrite = {
|
|
|
15
15
|
kind: 'replace';
|
|
16
16
|
};
|
|
17
17
|
/** One coherent write: the canvas step, `write()` (returns the new file size), then commit. */
|
|
18
|
-
export type AppendSection = (conversationId: string, change: ConversationWrite, write: () => number) => void
|
|
18
|
+
export type AppendSection = (conversationId: string, change: ConversationWrite, write: () => number) => Promise<void>;
|
|
19
19
|
/** The canvas side of the store: the write section, and each conversation's current owner. */
|
|
20
20
|
export interface ConversationCanvas {
|
|
21
21
|
appendSection: AppendSection;
|
|
22
|
-
owners(): Map<string, string
|
|
23
|
-
createPath?(nodeId: string, header: SessionHeader): string
|
|
24
|
-
pathFor?(id: string): string | undefined
|
|
25
|
-
repair?(id: string, path: string): void
|
|
26
|
-
abortCreate?(id: string): void
|
|
27
|
-
delete?(id: string): void
|
|
22
|
+
owners(): Promise<Map<string, string>>;
|
|
23
|
+
createPath?(nodeId: string, header: SessionHeader): Promise<string>;
|
|
24
|
+
pathFor?(id: string): Promise<string | undefined>;
|
|
25
|
+
repair?(id: string, path: string): Promise<void>;
|
|
26
|
+
abortCreate?(id: string): Promise<void>;
|
|
27
|
+
delete?(id: string): Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
export declare function sessionDirectory(root: string, cwd: string): string;
|
|
30
30
|
export declare function createFileStore(root: string, canvas: ConversationCanvas): ConversationStore & {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var G=Object.defineProperty;var u=(l,
|
|
2
|
-
`))if(
|
|
3
|
-
`);for(;
|
|
4
|
-
`)}}}finally{v(
|
|
5
|
-
`).join("")}u(C,"lines");function W(l,
|
|
6
|
-
`)},"slice"),s=
|
|
7
|
-
`));return g[0]?.type==="session"&&g.shift(),{header:r,entries:g,tail:E(
|
|
8
|
-
`)),path:n}}finally{v(i)}}u(H,"readWindow");function D(e,t,r,n,
|
|
9
|
-
`).join("")),k(i),S(n).size}finally{v(i)}})}catch(i){throw
|
|
1
|
+
var G=Object.defineProperty;var u=(l,o)=>G(l,"name",{value:o,configurable:!0});import{randomUUID as J}from"node:crypto";import{closeSync as v,createReadStream as K,existsSync as $,fsyncSync as k,mkdirSync as L,openSync as z,readFileSync as P,readSync as M,renameSync as Q,statSync as S,unlinkSync as O,writeFileSync as j}from"node:fs";import{createInterface as T}from"node:readline";import{dirname as V,join as F,relative as X,resolve as b}from"node:path";import{SessionManager as Y}from"@earendil-works/pi-coding-agent";import{ConversationNotFoundError as Z}from"./index.js";function E(l){const o=[];for(const w of l.split(`
|
|
2
|
+
`))if(w.trim())try{o.push(JSON.parse(w))}catch{}return o}u(E,"parseLines");function I(l){const o=z(l,"r");try{const w=Buffer.allocUnsafe(4096);let f="";for(;;){const h=M(o,w,0,w.length,null);f+=w.toString("utf8",0,h);let y=f.indexOf(`
|
|
3
|
+
`);for(;y!==-1||h===0;){const m=y===-1?f:f.slice(0,y),[d]=E(m);if(d!==void 0)return d;if(y===-1)return;f=f.slice(y+1),y=f.indexOf(`
|
|
4
|
+
`)}}}finally{v(o)}}u(I,"firstLine");function ee(l,o){const w=z(l,"r");try{const f=Buffer.alloc(1);return M(w,f,0,1,o-1),f[0]}finally{v(w)}}u(ee,"lastByte");function C(l,o){return[l,...o].map(w=>`${JSON.stringify(w)}
|
|
5
|
+
`).join("")}u(C,"lines");function W(l,o){const w=`--${b(o).replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`;return F(l,w)}u(W,"sessionDirectory");function A(l){return`${l.timestamp.replace(/[:.]/g,"-")}_${l.id}.jsonl`}u(A,"fileName");function ce(l,o){const{appendSection:w}=o,f=new Map,h=new Map;L(l,{recursive:!0,mode:448});const y=new Set;async function m(e){if(y.has(e))return;const t=await d(e);if(await o.repair?.(e,t),!$(t)){f.delete(e),h.delete(e);return}y.add(e)}u(m,"repair");async function d(e){const t=f.get(e)??await o.pathFor?.(e);if(!t)throw new Z(e);return f.set(e,t),t}u(d,"pathFor");async function x(e){await m(e);const t=await d(e),r=E(P(t,"utf8")),n=r.shift();if(n?.type!=="session"||n.id!==e)throw new Error(`invalid conversation: ${e}`);return{header:n,entries:r,path:t}}u(x,"read");function B(e,t){const r=I(t);return r?.type==="session"&&r.id===e?r:void 0}u(B,"validHeader");async function N(e){const t=await d(e),r=B(e,t);if(!r)throw new Error(`invalid conversation: ${e}`);return{header:r,path:t}}u(N,"headerOf");async function H(e,t){await m(e);const{header:r,path:n}=await N(e),c=S(n).size;if(c<=t.head+t.tail)return await x(e);const i=z(n,"r");try{const a=u((R,_)=>{if(_<=0)return[];const U=Buffer.allocUnsafe(_),q=M(i,U,0,_,R);return U.subarray(0,q).toString("utf8").split(`
|
|
6
|
+
`)},"slice"),s=a(0,t.head),p=a(c-t.tail,t.tail);s.pop(),p.shift();const g=E(s.join(`
|
|
7
|
+
`));return g[0]?.type==="session"&&g.shift(),{header:r,entries:g,tail:E(p.join(`
|
|
8
|
+
`)),path:n}}finally{v(i)}}u(H,"readWindow");async function D(e,t,r,n,c){if(f.has(t.id))throw new Error(`conversation already exists: ${t.id}`);const i=X(l,n);if(i.startsWith("..")||i===""||b(n)===b(l))throw new Error("conversation path outside store root");if(L(V(n),{recursive:!0,mode:448}),$(n))throw new Error(`conversation file already exists: ${n}`);let a=!1;try{const s=u(()=>{const p=z(n,"wx",384);a=!0;try{return j(p,C(t,r)),k(p),a=!1,S(n).size}finally{v(p)}},"write");return e===void 0?s():await w(t.id,{kind:"create",nodeId:e,path:n,entries:r,...c?{sourceId:c}:{}},s),f.set(t.id,n),t.id}catch(s){throw a||!$(n)?($(n)&&O(n),await o.abortCreate?.(t.id)):f.set(t.id,n),s}}return u(D,"createAt"),{recover(e){for(const t of e){if(!t.transcript_path)continue;const r=f.get(t.session_id);if(r&&r!==t.transcript_path)throw new Error(`conflicting conversation paths: ${t.session_id}`);f.set(t.session_id,t.transcript_path)}},repair:m,async readLines(e){await m(e);const t=await d(e),r=T({input:K(t),crlfDelay:1/0});return{path:t,lines:r}},async create(e,t,r,n){return await D(e,t,r,await o.createPath?.(e,t)??n??F(W(l,t.cwd),A(t)))},async append(e,t,r){if(t.length===0)return;await m(e);const n=await d(e);if(r?.dedupe){const i=new Set((await x(e)).entries.map(a=>a.id));if(t=t.filter(a=>!i.has(a.id)),t.length===0)return}const c=S(n).size;if(c>0&&ee(n,c)!==10)throw new Error(`incomplete conversation tail: ${e}`);try{await w(e,{kind:"append",entries:t},()=>{const i=z(n,"a");try{return j(i,t.map(a=>`${JSON.stringify(a)}
|
|
9
|
+
`).join("")),k(i),S(n).size}finally{v(i)}})}catch(i){throw y.delete(e),i}},async replace(e,t,r){await m(e);const n=await d(e);if(t.id!==e)throw new Error("replacement header id differs from conversation id");const c=P(n),i=u(s=>{const p=`${n}.${J()}.tmp`;try{j(p,s,{flag:"wx",mode:384});const g=z(p,"r");try{k(g)}finally{v(g)}Q(p,n)}finally{$(p)&&O(p)}},"swap");let a=!1;try{await w(e,{kind:"replace"},()=>(i(C(t,r)),a=!0,S(n).size))}catch(s){throw a&&i(c),s}finally{h.delete(e)}},async read(e,t){return t?await H(e,t):await x(e)},async header(e){await m(e);const{header:t,path:r}=await N(e),n=S(r);return{header:t,path:r,mtime:n.mtimeMs,size:n.size}},async fork(e,t,r,n){const c=await x(e);let i=c.entries;if(r!==void 0){const p=Y.inMemory(c.header.cwd,void 0,[c.header,...i]);p.createBranchedSession(r),i=p.getEntries()}const a=new Date().toISOString(),s={...c.header,id:J(),timestamp:a,cwd:n??c.header.cwd,parentSession:c.path};return await D(t,s,i,t&&o.createPath?await o.createPath(t,s):F(W(l,s.cwd),A(s)),e)},async list(e){const t=[],r=await o.owners();for(const n of new Set([...f.keys(),...r.keys()])){const c=r.get(n);if(e!==void 0&&c!==e||(await m(n),!f.has(n)))continue;const i=await d(n),a=S(i);let s=h.get(n);(!s||s.mtime!==a.mtimeMs||s.size!==a.size)&&(s={mtime:a.mtimeMs,size:a.size,header:B(n,i)},h.set(n,s)),s.header&&t.push({conversation_id:n,...c?{node_id:c}:{},header:s.header,mtime:a.mtimeMs,size:a.size,path:i})}return t.sort((n,c)=>c.mtime-n.mtime)},async delete(e){O(await d(e)),await o.delete?.(e),f.delete(e),y.delete(e),h.delete(e)}}}u(ce,"createFileStore");export{ce as createFileStore,W as sessionDirectory};
|
|
@@ -54,41 +54,43 @@ export interface ConversationStoreClient {
|
|
|
54
54
|
}
|
|
55
55
|
/** The daemon's file store (`createFileStore`, installed by `sessions.ts`). */
|
|
56
56
|
export interface ConversationStore {
|
|
57
|
-
create(nodeId: string, header: SessionHeader, entries: SessionEntry[], path?: string): string
|
|
57
|
+
create(nodeId: string, header: SessionHeader, entries: SessionEntry[], path?: string): Promise<string>;
|
|
58
58
|
append(id: string, entries: SessionEntry[], options?: {
|
|
59
59
|
dedupe?: boolean;
|
|
60
|
-
}): void
|
|
61
|
-
replace(id: string, header: SessionHeader, entries: SessionEntry[]): void
|
|
62
|
-
read(id: string, window?: ConversationWindow): {
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
replace(id: string, header: SessionHeader, entries: SessionEntry[]): Promise<void>;
|
|
62
|
+
read(id: string, window?: ConversationWindow): Promise<{
|
|
63
63
|
header: SessionHeader;
|
|
64
64
|
entries: SessionEntry[];
|
|
65
65
|
tail?: SessionEntry[];
|
|
66
66
|
path: string;
|
|
67
|
-
}
|
|
67
|
+
}>;
|
|
68
68
|
/** Stream a complete conversation without blocking the daemon on a full-file read. */
|
|
69
|
-
readLines?(id: string): {
|
|
69
|
+
readLines?(id: string): Promise<{
|
|
70
70
|
path: string;
|
|
71
71
|
lines: AsyncIterable<string>;
|
|
72
|
-
}
|
|
73
|
-
header(id: string): {
|
|
72
|
+
}>;
|
|
73
|
+
header(id: string): Promise<{
|
|
74
74
|
header: SessionHeader;
|
|
75
75
|
mtime: number;
|
|
76
76
|
size: number;
|
|
77
77
|
path: string;
|
|
78
|
-
}
|
|
79
|
-
fork(id: string, nodeId?: string, leafId?: string, cwd?: string): string
|
|
80
|
-
list(nodeId?: string): ConversationInfo[]
|
|
81
|
-
delete(id: string): void
|
|
78
|
+
}>;
|
|
79
|
+
fork(id: string, nodeId?: string, leafId?: string, cwd?: string): Promise<string>;
|
|
80
|
+
list(nodeId?: string): Promise<ConversationInfo[]>;
|
|
81
|
+
delete(id: string): Promise<void>;
|
|
82
82
|
}
|
|
83
83
|
export declare function conversationIdFromPath(path: string): string | null;
|
|
84
84
|
export declare function defaultConversationRoot(): string;
|
|
85
85
|
export declare function storeAddress(): string;
|
|
86
86
|
export declare function installConversationStore(store: ConversationStore | undefined): void;
|
|
87
|
+
/** The installed store, else the client over the store socket with each call awaited. */
|
|
87
88
|
export declare function conversationStore(): ConversationStore;
|
|
88
|
-
/** The synchronous store pi's `SessionManager` statics call:
|
|
89
|
+
/** The synchronous store pi's `SessionManager` statics call: always the client over the store socket (the installed
|
|
90
|
+
* store is async, so it cannot serve a synchronous caller). */
|
|
89
91
|
export declare function conversationClient(): ConversationStoreClient;
|
|
90
92
|
/** Read a conversation without parking the event loop on the store worker. */
|
|
91
|
-
export declare function readConversationAsync(id: string, window?: ConversationWindow): Promise<ReturnType<ConversationStore['read']
|
|
93
|
+
export declare function readConversationAsync(id: string, window?: ConversationWindow): Promise<Awaited<ReturnType<ConversationStore['read']>>>;
|
|
92
94
|
export { createFileStore, sessionDirectory, type AppendSection, type ConversationCanvas, type ConversationWrite } from './file-store.js';
|
|
93
95
|
export { installSessionManagerStorePatch } from './patch.js';
|
|
94
96
|
export { findOrphanedParents, relinkOrphanedParents, repairConversationFile, type FileRepair, type OrphanRelink } from './repair.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});import{appsRoot as i,socketDir as p}from"../layout.js";import{join as d}from"node:path";import{createStoreClient as f}from"./client.js";import{currentNodeToken as u}from"../runtime/broker/node-token.js";class l extends Error{static{o(this,"ConversationNotFoundError")}code="not_found";constructor(r){super(`conversation not found: ${r}`)}}function h(e){return e instanceof l}o(h,"isConversationNotFound");function k(e){return/(?:^|\/)[^/]+_([0-9a-f-]{36})\.jsonl$/i.exec(e)?.[1]??null}o(k,"conversationIdFromPath");function R(){return i()}o(R,"defaultConversationRoot");function m(){return process.env.CRTR_STORE_ADDRESS||d(p(),"store.sock")}o(m,"storeAddress");let t,s;function A(e){t=e}o(A,"installConversationStore");function F(){if(t)return t;const e=a();return{create:o(async(...r)=>e.create(...r),"create"),append:o(async(...r)=>e.append(...r),"append"),replace:o(async(...r)=>e.replace(...r),"replace"),read:o(async(...r)=>e.read(...r),"read"),header:o(async(...r)=>e.header(...r),"header"),fork:o(async(...r)=>e.fork(...r),"fork"),list:o(async(...r)=>e.list(...r),"list"),delete:o(async(...r)=>e.delete(...r),"delete")}}o(F,"conversationStore");function a(){const e=m();return s?.address!==e&&(s={address:e,store:f(e,u())}),s.store}o(a,"conversationClient");async function D(e,r){if(t)return t.read(e,r);const n=a();return n.readAsync?n.readAsync(e,r):n.read(e,r)}o(D,"readConversationAsync");import{createFileStore as _,sessionDirectory as N}from"./file-store.js";import{installSessionManagerStorePatch as T}from"./patch.js";import{findOrphanedParents as $,relinkOrphanedParents as g,repairConversationFile as I}from"./repair.js";export{l as ConversationNotFoundError,a as conversationClient,k as conversationIdFromPath,F as conversationStore,_ as createFileStore,R as defaultConversationRoot,$ as findOrphanedParents,A as installConversationStore,T as installSessionManagerStorePatch,h as isConversationNotFound,D as readConversationAsync,g as relinkOrphanedParents,I as repairConversationFile,N as sessionDirectory,m as storeAddress};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var O=Object.defineProperty;var v=(
|
|
1
|
+
var O=Object.defineProperty;var v=(o,n)=>O(o,"name",{value:n,configurable:!0});import{createServer as _}from"node:http";import{chmodSync as k,existsSync as N,unlinkSync as T}from"node:fs";import{isConversationNotFound as b}from"./index.js";import{resolveNodeToken as j}from"../canvas/node-tokens.js";import{conversationOwner as H}from"../canvas/sessions.js";import{peerUid as J}from"../../native/linux.js";async function x(o){const n=[];for await(const s of o)n.push(Buffer.from(s));return JSON.parse(Buffer.concat(n).toString("utf8"))}v(x,"body");function l(o,n,s){o.writeHead(n,{"content-type":"application/json"}),o.end(JSON.stringify(s))}v(l,"json");async function P(o,n,s){if(!n.readLines){const f=await n.read(s);o.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":f.path}),o.end([f.header,...f.entries].map(d=>JSON.stringify(d)).join(`
|
|
2
2
|
`)+`
|
|
3
|
-
`);return}const{path:
|
|
4
|
-
`;c+=Buffer.byteLength(S),c>=256*1024?(c=0,await new Promise((p,u)=>
|
|
3
|
+
`);return}const{path:a,lines:e}=await n.readLines(s);let r=!1,c=0;for await(const f of e){if(!f.trim())continue;let d;try{d=JSON.parse(f)}catch{continue}if(!r){if(d.type!=="session"||d.id!==s)throw new Error(`invalid conversation: ${s}`);o.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":a}),r=!0}const S=JSON.stringify(d)+`
|
|
4
|
+
`;c+=Buffer.byteLength(S),c>=256*1024?(c=0,await new Promise((p,u)=>o.write(S,w=>w?u(w):p()))):o.write(S)}if(!r)throw new Error(`invalid conversation: ${s}`);o.end()}v(P,"fullRead");async function C(o,n){const s=_(async(a,e)=>{try{const r=a.headers.authorization,c=typeof r=="string"&&r.startsWith("Bearer ")?await j(r.slice(7)):null,f=new URL(a.url??"/","http://store"),d=f.pathname.split("/").filter(Boolean);if(r===void 0&&process.platform!=="linux"&&a.method==="GET"&&d[0]==="conversations"&&(d.length===1||d.length===2||d.length===3&&d[2]==="header")){const t=d[1];if(!t)l(e,200,{conversations:await n.list(f.searchParams.get("node_id")??void 0)});else if(d[2]==="header")l(e,200,await n.header(t));else{const y=f.searchParams.get("head"),h=f.searchParams.get("tail");if(y===null||h===null)await P(e,n,t);else{const g=await n.read(t,{head:Number(y),tail:Number(h)});e.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":g.path,...g.tail?{"x-conversation-tail":String(1+g.entries.length)}:{}}),e.end([g.header,...g.entries,...g.tail??[]].map(E=>JSON.stringify(E)).join(`
|
|
5
5
|
`)+`
|
|
6
|
-
`)}}return}if(!c){l(e,401,{error:"unauthorized"});return}if(process.platform==="linux"){let
|
|
6
|
+
`)}}return}if(!c){l(e,401,{error:"unauthorized"});return}if(process.platform==="linux"){let t;try{t=J(a.socket)}catch{l(e,401,{error:"unauthorized"});return}if(t!==c.uid){l(e,401,{error:"unauthorized"});return}}const p=v(async t=>await H(t)===c.node,"owns"),u=v(()=>l(e,404,{error:"not_found"}),"notFound"),w=new URL(a.url??"/","http://store"),m=w.pathname.split("/").filter(Boolean);if(m[0]!=="conversations"){l(e,404,{error:"not_found"});return}const i=m[1];if(!i&&a.method==="POST"){const t=await x(a);if(t.node_id!==c.node){u();return}l(e,201,{conversation_id:await n.create(t.node_id,t.header,t.entries,t.path)})}else if(!i&&a.method==="GET"){if(w.searchParams.has("node_id")&&w.searchParams.get("node_id")!==c.node){u();return}l(e,200,{conversations:await n.list(c.node)})}else if(i&&m[2]==="entries"&&a.method==="POST"){if(!await p(i)){u();return}const t=await x(a);await n.append(i,t.entries,t.dedupe===!0?{dedupe:!0}:void 0),e.writeHead(204).end()}else if(i&&m[2]==="header"&&a.method==="GET"){if(!await p(i)){u();return}l(e,200,await n.header(i))}else if(i&&m[2]==="fork"&&a.method==="POST"){if(!await p(i)){u();return}const t=await x(a);if(t.node_id!==c.node){u();return}l(e,201,{conversation_id:await n.fork(i,c.node,t.leaf_id,t.cwd)})}else if(i&&m.length===2&&a.method==="GET"){if(!await p(i)){u();return}const t=w.searchParams.get("head"),y=w.searchParams.get("tail");if(t===null||y===null)await P(e,n,i);else{const h=await n.read(i,{head:Number(t),tail:Number(y)});e.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":h.path,...h.tail?{"x-conversation-tail":String(1+h.entries.length)}:{}}),e.end([h.header,...h.entries,...h.tail??[]].map(g=>JSON.stringify(g)).join(`
|
|
7
7
|
`)+`
|
|
8
|
-
`)}}else if(
|
|
8
|
+
`)}}else if(i&&m.length===2&&a.method==="PUT"){if(!await p(i)){u();return}const t=await x(a);await n.replace(i,t.header,t.entries),e.writeHead(204).end()}else if(i&&m.length===2&&a.method==="DELETE"){if(!await p(i)){u();return}await n.delete(i),e.writeHead(204).end()}else l(e,404,{error:"not_found"})}catch(r){const c=r instanceof Error?r.message:String(r);e.headersSent?e.destroy(r instanceof Error?r:new Error(c)):l(e,b(r)?404:500,{error:c})}});if(N(o)&&T(o),await new Promise((a,e)=>{s.once("error",e),s.listen(o,()=>{s.off("error",e),a()})}),typeof s.address()!="string")throw s.close(),new Error(`store listener must bind a unix socket: ${JSON.stringify(s.address())}`);return k(o,process.platform==="linux"&&N("/run/crtr/launcher.sock")?438:384),{close:v(()=>new Promise((a,e)=>s.close(r=>r?e(r):a())),"close")}}v(C,"listenConversationStore");export{C as listenConversationStore};
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ConversationStoreClient } from './index.js';
|
|
2
|
+
/** `store` is the synchronous client pi's `SessionManager` needs: the broker's client over the store socket unless a caller supplies one. */
|
|
3
|
+
export declare function installSessionManagerStorePatch(nodeId: string, store?: ConversationStoreClient): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var P=Object.defineProperty;var
|
|
1
|
+
var P=Object.defineProperty;var c=(a,r)=>P(a,"name",{value:r,configurable:!0});import{dirname as E,resolve as A}from"node:path";import{SessionManager as w}from"@earendil-works/pi-coding-agent";import{conversationClient as R,conversationIdFromPath as O}from"./index.js";import{findOrphanedParents as T}from"./repair.js";import{emitEvent as I}from"../events/emit.js";const f=new WeakMap;function k(a){a>0&&Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,a)}c(k,"sleep");function C(){const a=Number(process.env.CRTR_CONVERSATION_APPEND_RETRY_MS);return Number.isFinite(a)&&a>=0?a:500}c(C,"retryDelayMs");let x=!1;function z(a,r=R()){if(x)return;const l=w.prototype,h=w;for(const e of["_setSessionFile","_rewriteFile","_persist","createBranchedSession","newSession"])if(typeof l[e]!="function")throw new Error(`pi SessionManager.${e} changed; store patch cannot start`);for(const e of["create","open","continueRecent","forkFrom","findById","list","listAll"])if(typeof h[e]!="function")throw new Error(`pi SessionManager.${e} changed; store patch cannot start`);const M=l.createBranchedSession,y=l.newSession;function N(e,s){const t=T(s);t.length!==0&&I({level:"error",event:"conversation.orphaned_parent",fields:{conversation_id:e,orphan_count:t.length,orphans:t.slice(0,20).map(i=>({entry_id:i.entryId,missing_parent_id:i.missingParentId}))}})}c(N,"reportOrphans");function _(e,s){const{header:t,entries:i,path:o}=r.read(e);N(t.id,i);const n=w.inMemory(s??t.cwd);n.sessionFile=o,n.sessionDir=E(o),n._loadEntries([t,...i]),n.persist=!0,n.flushed=!0;const u=n.fileEntries[0];return u?.type==="session"&&u.version!==t.version&&n._rewriteFile(),n}c(_,"fromStore");function m(e){const[s,...t]=e.fileEntries;if(!s||s.type!=="session")throw new Error("conversation has no session header");r.create(a,s,t),e.sessionFile=r.header(s.id).path,e.sessionDir=E(e.sessionFile),e.flushed=!0,f.delete(e)}c(m,"persistNew");function B(e,s){const t=f.get(e)??{entries:[],ambiguous:!1};t.entries.push(s),f.set(e,t);let i;for(let o=0;o<2;o++){o>0&&k(C());try{r.append(e.sessionId,t.entries,t.ambiguous?{dedupe:!0}:void 0),f.delete(e);return}catch(n){i=n,t.ambiguous=!0}}throw I({level:"error",event:"conversation.append_failed",error:i,fields:{conversation_id:e.sessionId,pending_entries:t.entries.length}}),i}c(B,"appendInOrder");function g(e){const s=O(e);if(!s)throw new Error(`invalid conversation path: ${e}`);return s}c(g,"idOf"),l._setSessionFile=function(e){const{header:s,entries:t}=r.read(g(e));this.sessionFile=r.header(s.id).path,this.sessionDir=E(this.sessionFile),N(s.id,t),this._loadEntries([s,...t]),this.flushed=!0,f.delete(this)},l._rewriteFile=function(){if(!this.persist||!this.sessionFile)return;const[e,...s]=this.fileEntries;if(!e||e.type!=="session")throw new Error("conversation has no session header");r.replace(e.id,e,s),f.delete(this)},l._persist=function(e){!this.persist||!this.sessionFile||(this.flushed?B(this,e):m(this))},l.newSession=function(e){if(!this.persist)return y.call(this,e);const s=this.flushed&&this.fileEntries.length===1&&this.sessionFile!==void 0?this.sessionId:void 0;if(s!==void 0&&(e?.id===void 0||e.id===s)){const t=this.sessionFile;y.call(this,{...e,id:s});const i=this.fileEntries[0];if(!i||i.type!=="session")throw new Error("conversation has no session header");return r.replace(s,i,[]),this.sessionFile=t,this.flushed=!0,t}return y.call(this,e),m(this),this.sessionFile},l.createBranchedSession=function(e){if(!this.persist)return M.call(this,e);const s=this.sessionFile;this.persist=!1;try{M.call(this,e)}finally{this.persist=!0}const t=this.fileEntries[0];if(!t||t.type!=="session")throw new Error("branch has no header");return this.fileEntries[0]={...t,parentSession:s},m(this),this.sessionFile},h.create=(e,s,t)=>{const i=w.inMemory(e,t);return i.persist=!0,m(i),i},h.open=(e,s,t)=>_(g(e),t),h.continueRecent=e=>{const s=r.list().find(t=>t.header.cwd===A(e));return s?_(s.conversation_id,e):h.create(e)},h.forkFrom=(e,s)=>_(r.fork(g(e),a,void 0,s)),h.findById=(e,s)=>r.list().find(t=>t.conversation_id===s&&t.header.cwd===A(e))?.path;function b(e){return r.list().filter(s=>e===void 0||s.header.cwd===A(e)).map(s=>{let t,i=0,o="",n;const u=[];for(const p of r.read(s.conversation_id).entries){if(p.type==="session_info"&&(t=p.name?.trim()||void 0),p.type!=="message")continue;i++;const d=p.message;if(d.role!=="user"&&d.role!=="assistant")continue;const D=typeof d.timestamp=="number"?d.timestamp:Date.parse(p.timestamp);Number.isNaN(D)||(n=Math.max(n??0,D));const F=typeof d.content=="string"?d.content:Array.isArray(d.content)?d.content.filter(S=>S.type==="text").map(S=>S.text??"").join(" "):"";F&&(u.push(F),!o&&d.role==="user"&&(o=F))}const v=new Date(s.header.timestamp);return{path:s.path,id:s.conversation_id,cwd:s.header.cwd,...t?{name:t}:{},...s.header.parentSession?{parentSessionPath:s.header.parentSession}:{},created:v,modified:n&&n>0?new Date(n):Number.isNaN(v.getTime())?new Date(s.mtime):v,messageCount:i,firstMessage:o||"(no messages)",allMessagesText:u.join(" ")}})}c(b,"sessionInfos"),h.list=async(e,s,t,i)=>{i?.throwIfAborted();const o=b(e);return t?.(o.length,o.length,o),o},h.listAll=async(...e)=>(e.find(t=>t instanceof AbortSignal)?.throwIfAborted(),b()),x=!0}c(z,"installSessionManagerStorePatch");export{z as installSessionManagerStorePatch};
|
package/dist/core/feed/feed.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var N=Object.defineProperty;var i=(e,t)=>N(e,"name",{value:t,configurable:!0});import{
|
|
2
|
-
`)[0]??"";return r.length>t?`${r.slice(0,t-1)}\u2026`:r}i(
|
|
1
|
+
var N=Object.defineProperty;var i=(e,t)=>N(e,"name",{value:t,configurable:!0});import{cancelCronsOnWake as O,getNode as E}from"../canvas/index.js";import{runStructuredRequestEffects as y,settleStructuredRequestIn as R}from"../canvas/structured-requests.js";import{openDb as q,withCanvasWrite as T}from"../canvas/db.js";import{randomUUID as x}from"node:crypto";import{composeNodeOutcomeDocument as F}from"../runtime/outcome-document.js";import{closeNode as M}from"../runtime/close.js";import{put as W}from"../graph/bodies.js";import{writeDocument as z}from"../graph/documents.js";import{asRuntimeWriter as A}from"../graph/spaces/own-memory.js";import{publish as k}from"../graph/events.js";import{nodeObject as v}from"../graph/objects.js";import{readerForNode as L}from"../graph/reader.js";import{endMessageSubscriptions as C}from"../graph/watches.js";import{operationIdContext as D}from"../events/operation-id.js";class H extends Error{static{i(this,"StructuredRequestFinalizationError")}state;constructor(t){super(t==="expired"?"structured_request_expired":"structured_request_settled"),this.state=t}}class h extends Error{static{i(this,"FinalizationError")}code;report;constructor(t,r){super(t),this.code=t,this.report=r}}function j(e){const t=i((r,n=2)=>String(r).padStart(n,"0"),"pad");return`${e.getUTCFullYear()}${t(e.getUTCMonth()+1)}${t(e.getUTCDate())}T${t(e.getUTCHours())}${t(e.getUTCMinutes())}${t(e.getUTCSeconds())}${t(e.getUTCMilliseconds(),3)}`}i(j,"compactTs");function S(e,t=80){const r=e.split(`
|
|
2
|
+
`)[0]??"";return r.length>t?`${r.slice(0,t-1)}\u2026`:r}i(S,"firstLine");function B(e){return e.kind==="final"?{event:"report.final"}:e.result!==void 0?{event:"report.result"}:e.kind==="urgent"?{event:"report.update",level:7}:{event:"report.update",level:e.deliveryTier==="deferred"?3:e.deliveryTier==="urgent"?7:5}}i(B,"eventFor");async function U(e,t,r){const n=r.from??t,o=`reports/${j(new Date)}-${x().slice(-8)}-${r.kind}`,u=await v(e,t),c=await v(e,n),{object:d}=await z(e,A(await L(e,n,async()=>[])),{owner:u,kind:"report",name:o,preview:S(r.body)||r.kind,privacy:"public"},r.body),s=`${t}/${o}`,{event:p,level:m}=B(r);await k(e,{event:p,object:u,actor:c,...m===void 0?{}:{level:m},attrs:{},pointer:d.id,messageBody:{kind:r.kind,label:S(r.body),bodyRef:s,...r.disposition===void 0?{}:{disposition:r.disposition}}});const l=(await e.prepare(`SELECT d.destination_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
3
3
|
JOIN objects receiver ON receiver.id = d.destination_id
|
|
4
|
-
WHERE m.body_ref = ? AND receiver.type = 'node' ORDER BY d.destination_id`).all(
|
|
4
|
+
WHERE m.body_ref = ? AND receiver.type = 'node' ORDER BY d.destination_id`).all(s)).map(w=>w.destination_id);return r.kind==="final"?await C(e,u,"final"):r.result?.requestMessageId&&await C(e,u,{result:r.result.requestMessageId}),{name:o,ref:s,doc:d,createdAt:d.created_at,deliveredTo:l}}i(U,"writeReport");async function J(e,t){return T(async r=>{const n=await r.prepare("SELECT status, final_report FROM nodes WHERE node_id = ?").get(e);if(n===void 0)throw new h("unknown_node");const o=t.outcome;let u;if(o?.structured!==void 0){const a=await R(r,o.structured.requestId,o.structured.declined===void 0?{intended:"completed",result:o.structured.value}:{intended:"declined",declined:o.structured.declined});if(!a.changed||a.row===null||a.row.state!=="completed"&&a.row.state!=="declined")return{written:void 0,...a.row===null?{}:{structured:a.row},structuredRefused:!0};u=a.row}else{const a=await r.prepareUncached("SELECT request_id FROM structured_requests WHERE node_id = ? AND state = 'pending'").get(e);if(a!==void 0){const f=await R(r,a.request_id,{intended:"failed",failureReason:"finalized"});if(!f.changed||f.row===null||f.row.state!=="failed")return{written:void 0,...f.row===null?{}:{structured:f.row},structuredRefused:!0};u=f.row}}if(n.final_report!==null)throw new h("already_finalized",`${e}/${n.final_report}`);if(n.status!=="active"&&n.status!=="idle"&&n.status!=="done")throw new h("finalization_forbidden");const c=await U(r,e,t),d=await E(e),s=d?.kind!=="human",p=(d?.outcome_revision??0)+1,m=t.outcome?.kind??"result",l=t.outcome?.reason??"finalized",w=t.outcome?.detailJson??null,_=c.createdAt;if(s){const a=d===null?null:await F({node:{...d,status:"done",intent:"done",terminal_reason:l},outcome:{kind:m,reason:l,at:_,revision:p,detailJson:w},finalReport:c.name,...u?.state==="completed"?{structuredResult:u.result}:{}});await r.prepare("UPDATE nodes SET status = 'done', intent = 'done', terminal_reason = ?, final_report = ?, finalized_at = ?, outcome_kind = ?, outcome_reason = ?, outcome_at = ?, outcome_revision = outcome_revision + 1, outcome_detail_json = ? WHERE node_id = ? AND final_report IS NULL").run(l,c.name,_,m,l,_,w,e),a!==null&&await k(r,{event:"outcome",object:await v(r,e),actor:null,attrs:{revision:p},messageBody:a})}else await r.prepare("UPDATE nodes SET status = 'done', intent = 'done', terminal_reason = 'finalized', final_report = ?, finalized_at = ? WHERE node_id = ? AND final_report IS NULL").run(c.name,_,e);return{written:c,...u===void 0?{}:{structured:u}}})}i(J,"commitCanonicalFinal");async function $(e,t){if(!e)throw new Error(`push: empty nodeId (kind=${t.kind}) \u2014 a report must belong to a node`);if(t.kind==="final"&&t.deliveryTier!==void 0)throw new Error("push final does not accept a delivery tier");if(t.kind!=="final"&&t.outcome!==void 0)throw new Error("push outcome is final-only");if(t.kind!=="update"&&t.result!==void 0)throw new Error("a one-off result is an update report");if(W(t.body),t.kind==="final"){const n=await J(e,t);if(n.structuredRefused===!0)throw n.structured!==void 0&&y(n.structured),new H(n.structured?.state??"failed");n.structured!==void 0&&t.outcome?.structured?.skipEffects!==!0&&y(n.structured);const{written:o}=n;if(await O(e),(await E(e))?.run_id===e){const c=await(await q()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(e,e);for(const d of c){const s=await E(d.node_id);s&&s.status!=="done"&&s.status!=="canceled"&&s.status!=="dead"&&await M(d.node_id,{preserveEmpty:!0})}}return{report:o.ref,reportId:o.doc.id,deliveredTo:o.deliveredTo}}const r=await T(async n=>await U(n,e,t));return{report:r.ref,reportId:r.doc.id,deliveredTo:r.deliveredTo}}i($,"pushWithContext");function g(e,t){return D.current()===void 0?D.fresh(()=>$(e,t)):$(e,t)}i(g,"push");async function oe(e,t,r){return g(e,{kind:"update",body:t,...r})}i(oe,"pushUpdate");async function ae(e,t,r){return g(e,{kind:"urgent",body:t,...r})}i(ae,"pushUrgent");async function ue(e,t,r){return g(e,{kind:"final",body:t,...r})}i(ue,"pushFinal");export{h as FinalizationError,H as StructuredRequestFinalizationError,g as push,ue as pushFinal,oe as pushUpdate,ae as pushUrgent};
|
|
@@ -24,11 +24,11 @@ export interface InboxEntry {
|
|
|
24
24
|
export declare function nodeMailEntry(delivery: ClaimedNodeMail): InboxEntry;
|
|
25
25
|
/** The newest head body of the report document a message points at, or null when the entry
|
|
26
26
|
* is not a report or the document is gone. */
|
|
27
|
-
export declare function reportDocumentBody(objectId: string): string | null
|
|
27
|
+
export declare function reportDocumentBody(objectId: string): Promise<string | null>;
|
|
28
28
|
export interface InboxDelivery {
|
|
29
29
|
kind: 'human' | 'card';
|
|
30
30
|
text: string;
|
|
31
31
|
entries: readonly InboxEntry[];
|
|
32
32
|
}
|
|
33
33
|
/** Split delivered entries into verbatim human messages and sender-grouped inbox cards. */
|
|
34
|
-
export declare function coalesce(entries: readonly InboxEntry[]): readonly InboxDelivery[]
|
|
34
|
+
export declare function coalesce(entries: readonly InboxEntry[]): Promise<readonly InboxDelivery[]>;
|
package/dist/core/feed/inbox.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var f=Object.defineProperty;var i=(n,e)=>f(n,"name",{value:e,configurable:!0});import{openDb as u}from"../canvas/db.js";import{heads as m}from"../graph/documents.js";import{getById as p}from"../graph/objects.js";import{bodyOf as l}from"../graph/bodies.js";import{validateOperationId as y}from"../events/operation-id.js";import{formatInboxCard as h,machineOfEntries as b}from"../../shared/generated-context.js";import{inlineBody as w,renderEntryBody as I,reportRefNodeId as g}from"../../shared/inbox-entry-body.js";import{mapAsync as E}from"../async-array.js";const _=/^(?!0{32}$)[0-9a-f]{32}$/;function x(n){if(typeof n!="string"||!_.test(n))throw new TypeError("entry_id must be 32 lowercase non-zero hexadecimal characters");return n}i(x,"validateInboxEntryId");function S(n){const e=n.message;return{entry_id:x(e.messageId),operation_id:y(e.operationId),ts:e.createdAt,from:e.senderNodeId,...e.senderName===null?{}:{from_name:e.senderName},tier:n.urgency,kind:e.kind,...e.bodyRef===null?{}:{ref:e.bodyRef},label:e.label,...e.bodyJson===null?{}:{data:e.bodyJson},...e.disposition===null?{}:{disposition:e.disposition}}}i(S,"nodeMailEntry");async function k(n){const e=await u(),o=await p(e,n);if(o===null||o.type!=="document"||o.deleted_at!==null)return null;const s=(await m(e,o))[0];if(s===void 0)return null;const d=await e.prepare("SELECT source_path FROM documents WHERE object = ?").get(o.rowid);return l(s.body_hash,d?.source_path??null)}i(k,"reportDocumentBody");async function B(n){const e=n.data?.push?.object?.id,o=g(n.ref)!==void 0&&e!==void 0?await k(e):null;return I(n,o)}i(B,"entryBody");async function N(n){return{kind:n.kind,body:await B(n),...n.ref===void 0?{}:{ref:n.ref},...n.disposition===void 0?{}:{disposition:n.disposition}}}i(N,"cardEntry");async function $(n){if(n.length===0)return[];const e=new Map;for(const t of n){const r=t.from??"system";e.has(r)||e.set(r,[]),e.get(r).push(t)}const o=[],s=[];let d=-1;for(const[t,r]of e){if(t==="human"){for(const a of r){const c=w(a);o.push({kind:"human",text:c===""?a.label:c,entries:[a]})}continue}d<0&&(d=o.length,o.push({kind:"card",text:"",entries:[]})),s.push({id:t,...b(r),entries:await E(r,N)})}return d>=0&&(o[d]={kind:"card",text:h(s),entries:n.filter(t=>(t.from??"system")!=="human")}),o}i($,"coalesce");export{$ as coalesce,S as nodeMailEntry,k as reportDocumentBody};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { openDb } from '../canvas/db.js';
|
|
1
|
+
import { type CanvasDb } from '../canvas/db.js';
|
|
3
2
|
import type { OperationId } from '../events/types.js';
|
|
4
3
|
import type { Level, ListenDelivery } from '../graph/types.js';
|
|
5
4
|
import { type InboxDisposition, type InboxKind, type InboxTier } from './inbox.js';
|
|
@@ -20,7 +19,7 @@ export interface NodeMailInput {
|
|
|
20
19
|
/** Optional caller-owned obligation identity, used by cron settlement replay. */
|
|
21
20
|
idempotencyKey?: string;
|
|
22
21
|
/** Runs with the mail insert, before the transaction commits. */
|
|
23
|
-
withinEnqueue?: (db:
|
|
22
|
+
withinEnqueue?: (db: CanvasDb, messageId: string) => Promise<void>;
|
|
24
23
|
}
|
|
25
24
|
export interface EnqueuedNodeMail {
|
|
26
25
|
messageId: string;
|
|
@@ -30,8 +29,8 @@ export interface EnqueuedNodeMail {
|
|
|
30
29
|
}
|
|
31
30
|
export declare function newId(): string;
|
|
32
31
|
/** A terminal-lifecycle destination's normal or deferred mail is raised to urgent. */
|
|
33
|
-
export declare function effectiveTier(nodeId: string, urgency: InboxTier): InboxTier
|
|
34
|
-
export declare function insertMessage(db:
|
|
32
|
+
export declare function effectiveTier(nodeId: string, urgency: InboxTier): Promise<InboxTier>;
|
|
33
|
+
export declare function insertMessage(db: CanvasDb, input: {
|
|
35
34
|
messageId?: string;
|
|
36
35
|
operationId: OperationId;
|
|
37
36
|
createdAt: string;
|
|
@@ -50,7 +49,7 @@ export declare function insertMessage(db: ReturnType<typeof openDb>, input: {
|
|
|
50
49
|
};
|
|
51
50
|
causeMessageId?: string | null;
|
|
52
51
|
depth?: number;
|
|
53
|
-
}): string
|
|
52
|
+
}): Promise<string>;
|
|
54
53
|
/** The message's creation time, operation id and body — an oversized inline body is clipped
|
|
55
54
|
* into `destinationNodeId`'s messages dir and referenced; with no destination it stays inline. */
|
|
56
55
|
export declare function finalizeNodeMail(input: Omit<NodeMailInput, 'wake'>, destinationNodeId: string | null): {
|
|
@@ -60,24 +59,24 @@ export declare function finalizeNodeMail(input: Omit<NodeMailInput, 'wake'>, des
|
|
|
60
59
|
bodyJson: unknown | undefined;
|
|
61
60
|
};
|
|
62
61
|
/** Insert one immutable message and one node-inbox obligation into the caller's write transaction. */
|
|
63
|
-
export declare function enqueueNodeMail(destinationNodeId: string, input: NodeMailInput): EnqueuedNodeMail
|
|
62
|
+
export declare function enqueueNodeMail(destinationNodeId: string, input: NodeMailInput): Promise<EnqueuedNodeMail>;
|
|
64
63
|
/** Contract §1: a listening delivery maps 1:1 onto an inbox tier; only `next-turn` does not wake. */
|
|
65
64
|
export declare function listenDeliveryTier(delivery: ListenDelivery): {
|
|
66
65
|
urgency: InboxTier;
|
|
67
66
|
wake: 0 | 1;
|
|
68
67
|
};
|
|
69
68
|
/** Queue one runtime notice to a node's inbox inside the caller's write transaction (no sender). */
|
|
70
|
-
export declare function queueNodeNotice(db:
|
|
69
|
+
export declare function queueNodeNotice(db: CanvasDb, nodeId: string, notice: {
|
|
71
70
|
body: string;
|
|
72
71
|
label?: string;
|
|
73
72
|
tier: InboxTier;
|
|
74
73
|
wake: 0 | 1;
|
|
75
|
-
}): EnqueuedNodeMail
|
|
74
|
+
}): Promise<EnqueuedNodeMail>;
|
|
76
75
|
/** Retract an obligation without fabricating a terminal receipt. */
|
|
77
|
-
export declare function cancelDelivery(deliveryId: string, now?: number): boolean
|
|
76
|
+
export declare function cancelDelivery(deliveryId: string, now?: number): Promise<boolean>;
|
|
78
77
|
export declare function cancelPendingNodeMail(nodeId: string, select?: {
|
|
79
78
|
senderNodeId?: string | null;
|
|
80
79
|
kind?: InboxKind;
|
|
81
|
-
}): string[]
|
|
80
|
+
}): Promise<string[]>;
|
|
82
81
|
/** Enqueue the one notice only if the same live controller wait is still dead. */
|
|
83
|
-
export declare function enqueueControllerDeathNotice(nodeId: string, controllerId: string): EnqueuedNodeMail | null
|
|
82
|
+
export declare function enqueueControllerDeathNotice(nodeId: string, controllerId: string): Promise<EnqueuedNodeMail | null>;
|