@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,11 +1,11 @@
|
|
|
1
|
-
var
|
|
1
|
+
var D=Object.defineProperty;var h=(n,a)=>D(n,"name",{value:a,configurable:!0});import{createHash as A,timingSafeEqual as U}from"node:crypto";import{createServer as W}from"node:http";import{readFileSync as z}from"node:fs";import{join as E,extname as B}from"node:path";import{fileURLToPath as G}from"node:url";import{withCanvasWrite as b}from"../../core/canvas/db.js";import{ApiError as I}from"../../api/errors.js";import{bodyOf as C}from"../../core/graph/bodies.js";import{canChange as H,isShipped as F}from"../../core/graph/access.js";import{documentRecord as x,editDocument as J,heads as O,withCurrentNames as k}from"../../core/graph/documents.js";import{getById as N}from"../../core/graph/objects.js";import{subscribeDocumentEvents as M}from"../../core/graph/events.js";import{emitEvent as V}from"../../core/events/emit.js";import{checkoutsForCwd as X}from"../../core/graph/repo-sync/repos.js";import{canonicalName as Z,repoChange as K,syncChanged as Q}from"./handlers/docs.js";import{escapeHtml as S}from"./vendor-signin.js";import{readerFor as $,resolveRef as Y}from"./reader.js";import{mergeDocumentLines as q}from"./document-merge.js";import{crtrVersion as ee}from"../../shared/crtr-version.js";const te="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'",T={class:"person"},y=encodeURIComponent(ee()),j=G(new URL("../../../dist/",import.meta.url));function m(n,a,t,i){n.writeHead(a,{"Content-Type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:t,message:i}}))}h(m,"error");function P(n,a){const t=h(i=>A("sha256").update(i).digest(),"digest");return U(t(n),t(a))}h(P,"sameSecret");function ne(n,a){for(const t of(n??"").split(";")){const i=t.indexOf("=");if(i!==-1&&t.slice(0,i).trim()===a)return t.slice(i+1).trim()}}h(ne,"cookieValue");function R(n,a,t){n.writeHead(a,{"Content-Type":"application/json; charset=utf-8"}),n.end(JSON.stringify(t))}h(R,"json");async function L(n){return await b(async a=>{const t=await N(a,n.id);if(!t||t.deleted_at||t.type!=="document")return null;const i=await $(a,{principal:T}),l=await x(a,t),o=await O(a,t),e=await Z(a,t),u=o.length===1&&await H(a,i,t);return{id:t.id,name:e,revision:l.revision,heads_key:l.heads_key,body:o.length===1?await k(a,t,C(o[0].body_hash,l.source_path)):"",editable:u,...u?{}:{readonly_reason:o.length!==1?`has ${o.length} heads and needs a merge`:await F(a,t)?"shipped by a plugin":"you cannot change this document"}}})}h(L,"snapshot");async function p(n){return await b(async a=>{const t=await $(a,{principal:T});try{const i=await Y(a,t,n);return"deleted"in i||"remote"in i||i.type!=="document"?null:i}catch(i){if(i instanceof I&&i.code==="not_found")return null;throw i}})}h(p,"resolveDocument");async function oe(n){const a=[];let t=0;for await(const i of n){if(t+=i.length,t>2e6)throw new Error("request body exceeds 2 MB");a.push(i)}return JSON.parse(Buffer.concat(a).toString("utf8"))}h(oe,"requestBody");async function ae(n){const a=await b(async t=>{const i=await $(t,{principal:T}),l=await N(t,n.id);if(!l||l.type!=="document"||l.deleted_at)return{status:404,value:{error:{code:"not_found",message:"document not found"}}};const o=await x(t,l),e=await O(t,l);if(e.length!==1||!await H(t,i,l))return{status:403,value:{error:{code:"forbidden",message:"document is read-only"}}};const u=await k(t,l,C(e[0].body_hash,o.source_path)),c=await t.prepareUncached("SELECT body_hash FROM revisions WHERE document = ? AND rev_id = ?").get(l.rowid,n.base_heads_key);if(!c||await k(t,l,C(c.body_hash,o.source_path))!==n.base_body)return{status:409,value:{saved:!1,conflict:{revision:o.revision,heads_key:o.heads_key,current_body:u,your_body:n.body}}};const r=n.base_heads_key!==o.heads_key,s=r?q(n.base_body,n.body,u):n.body;if(s===null)return{status:409,value:{saved:!1,conflict:{revision:o.revision,heads_key:o.heads_key,current_body:u,your_body:n.body}}};const d=await J(t,i,l,{body:s},n.rationale?.trim()||"edited by the person in the browser",o.heads_key,{},async w=>await X(t,w));return"stale"in d?{status:409,value:{saved:!1,conflict:{revision:d.stale.revision,heads_key:d.stale.heads_key,current_body:u,your_body:n.body}}}:{status:200,value:{saved:!0,revision:d.revision,heads_key:d.heads_key,body:s,merged:r},change:await K(t,i,[l])}});return a.change&&await Q(a.change),a}h(ae,"save");let v="the document listener has not started";function $e(){return v}h($e,"documentListenerUnavailable");function Te(n,a){const t=`crtr_doc_${n}`,i=W((o,e)=>{(async()=>{e.setHeader("Content-Security-Policy",te),e.setHeader("X-Content-Type-Options","nosniff");const u=[`127.0.0.1:${n}`,`localhost:${n}`];if(typeof o.headers.host!="string"||!u.includes(o.headers.host))return m(e,403,"forbidden","invalid Host");if(o.method==="POST"){if(!u.some(r=>o.headers.origin===`http://${r}`))return m(e,403,"forbidden","invalid Origin");if(o.headers["content-type"]!=="application/json")return m(e,415,"unsupported_media_type","Content-Type must be application/json")}const c=new URL(o.url??"/",`http://127.0.0.1:${n}`);if(!c.pathname.startsWith("/assets/")){const r=o.method==="GET"&&c.pathname.startsWith("/r/")?c.searchParams.get("t"):null;if(r!==null&&P(r,a))return c.searchParams.delete("t"),e.writeHead(303,{Location:`${c.pathname}${c.search}`,"Set-Cookie":`${t}=${a}; HttpOnly; SameSite=Strict; Path=/`,"Cache-Control":"no-store"}),e.end();const s=ne(o.headers.cookie,t);if(r!==null||s===void 0||!P(s,a))return c.pathname.startsWith("/r/")?(e.writeHead(401,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),e.end('<!doctype html><html><head><meta charset="utf-8"><title>Not authorized</title><link rel="icon" href="data:,"></head><body style="font-family:system-ui,sans-serif;max-width:40rem;margin:4rem auto;padding:0 1rem"><h1>Not authorized</h1><p>Open this document from its link in the attach viewer.</p></body></html>')):m(e,401,"unauthorized","open the document link from the attach viewer")}if(o.method==="GET"&&c.pathname.startsWith("/r/")){let r;try{r=decodeURIComponent(c.pathname.slice(3))}catch{return m(e,400,"invalid_request","ref is not valid percent-encoding")}const s=await p(r);return s?(e.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),e.end(`<!doctype html><html><head><meta charset="utf-8"><title>${S(s.name)}</title><link rel="icon" href="data:,"><link rel="stylesheet" href="/assets/${y}/editor.css"></head><body><div id="app" data-ref="${S(r)}"></div><script type="module" src="/assets/${y}/editor.js"><\/script></body></html>`)):(e.writeHead(404,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),e.end(`<!doctype html><html><head><meta charset="utf-8"><title>Document not found</title><link rel="icon" href="data:,"></head><body style="font-family:system-ui,sans-serif;max-width:40rem;margin:4rem auto;padding:0 1rem"><h1>Document not found</h1><p>No document you can read is named <code>${S(r)}</code>.</p></body></html>`))}if(o.method==="GET"&&c.pathname==="/api/doc"){const r=c.searchParams.get("ref"),s=r?await p(r):null,d=s&&await L(s);return d?R(e,200,{...d,ref:r}):m(e,404,"not_found","document not found")}if(o.method==="POST"&&c.pathname==="/api/save"){const r=await oe(o);if(!r||typeof r!="object"||Array.isArray(r))return m(e,400,"invalid_request","invalid save body");const s=r;if(typeof s.id!="string"||typeof s.base_heads_key!="string"||typeof s.base_body!="string"||typeof s.body!="string"||s.rationale!==void 0&&typeof s.rationale!="string")return m(e,400,"invalid_request","invalid save body");const d=await ae(s);return R(e,d.status,d.value)}if(o.method==="GET"&&c.pathname==="/api/events"){const r=c.searchParams.get("id");if(!r||!await p(r))return m(e,404,"not_found","document not found");e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-store",Connection:"keep-alive"}),e.write(`: connected
|
|
2
2
|
|
|
3
|
-
`);const
|
|
3
|
+
`);const s=h(async _=>{if(_==="deleted"){e.write(`event: deleted
|
|
4
4
|
data: {}
|
|
5
5
|
|
|
6
|
-
`),e.end();return}const
|
|
7
|
-
data: ${JSON.stringify({revision:
|
|
6
|
+
`),e.end();return}const f=await p(r),g=f&&await L(f);g&&e.write(`event: edited
|
|
7
|
+
data: ${JSON.stringify({revision:g.revision,heads_key:g.heads_key})}
|
|
8
8
|
|
|
9
|
-
`)}),
|
|
9
|
+
`)},"notify"),d=await M(r,_=>{s(_).catch(f=>{V({level:"error",event:"daemon.document_events.notify_failed",error:f}),e.end()})}),w=setInterval(()=>e.write(`: keepalive
|
|
10
10
|
|
|
11
|
-
`),3e4);e.on("close",()=>{clearInterval(
|
|
11
|
+
`),3e4);e.on("close",()=>{clearInterval(w),d()});return}if(o.method==="GET"&&c.pathname.startsWith(`/assets/${y}/`)){const r=c.pathname.slice(`/assets/${y}/`.length);if(!/^[a-zA-Z0-9_.-]+$/.test(r))return m(e,404,"not_found","asset not found");const s=r==="mermaid.js"?E(j,"clients/attach/assets/mermaid.min.js"):E(j,"doc-editor",r);try{const d=z(s);return e.writeHead(200,{"Content-Type":B(r)===".css"?"text/css; charset=utf-8":"text/javascript; charset=utf-8","Cache-Control":"public, max-age=31536000, immutable"}),e.end(d)}catch(d){if(d.code==="ENOENT")return m(e,404,"not_found","asset not found");throw d}}return m(e,404,"not_found","route not found")})().catch(u=>{e.headersSent?e.destroy():m(e,500,"server_failure",u instanceof Error?u.message:String(u))})});return{ready:new Promise((o,e)=>{i.once("error",u=>{v=`the document listener could not bind 127.0.0.1:${n}: ${u.message}`,e(u)}),i.listen(n,"127.0.0.1",()=>{i.removeAllListeners("error"),v=void 0,o()})}),close:h(()=>new Promise(o=>{v="the document listener is closed",i.closeAllConnections(),i.close(()=>o())}),"close")}}h(Te,"createDocumentListener");export{Te as createDocumentListener,$e as documentListenerUnavailable};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var o=(e,a)=>u(e,"name",{value:a,configurable:!0});import{listNodes as _}from"../../../core/canvas/canvas.js";import{openDb as l}from"../../../core/canvas/db.js";import{listMemoryReads as h,memoryReadsStartedAt as g}from"../../../core/canvas/memory-reads.js";import{usage as n}from"../../../core/errors.js";import{computeAnalytics as b,WINDOW_MS as R}from"../../analytics/compute.js";import{scanResponses as O}from"../../analytics/scan.js";import{canReadNode as S}from"../router.js";import{filterAsync as E}from"../../../core/async-array.js";const A=new Set(["as_of","window","project"]);async function M(e){for(const[t]of e.query)if(!A.has(t))throw n(`unknown analytics query parameter: ${t}`);const a=e.query.get("as_of")??"",s=Date.parse(a);if(!Number.isFinite(s))throw n(`as_of must be an ISO 8601 time, got "${a}"`);const r=e.query.get("window")??"";if(!Object.hasOwn(R,r))throw n(`window must be 24h or 7d, got "${r}"`);const d=e.query.get("project");if(d==="")throw n("project must be a non-empty directory path when given");const i=new Map,m=await(await l()).prepare("SELECT node_id, transcript_path FROM sessions WHERE transcript_path IS NOT NULL").all();for(const t of m)i.set(t.node_id,(i.get(t.node_id)??new Set).add(t.transcript_path));const w=new Map((await(await l()).prepare("SELECT node_id, title FROM node_rows WHERE title IS NOT NULL").all()).map(t=>[t.node_id,t.title])),c=e.principal,f=(await E(await _(),async t=>t.kind!=="human"&&(c.class==="person"||await S(c,t.grantee??"app:terminal",t.node_id)))).map(t=>({node_id:t.node_id,name:t.name,title:w.get(t.node_id)??null,kind:t.kind,parent:t.parent??null,cwd:t.cwd,created:t.created,finalized_at:t.finalized_at??null,final_report:t.final_report??null,lifecycle:t.lifecycle,transcripts:[...i.get(t.node_id)??[]]})),p=new AbortController;return e.res.once("close",()=>p.abort()),{status:200,body:await b({asOfMs:s,window:r,project:d??null,agents:f,scan:o(t=>O(t,p.signal),"scan"),memory:o(async(t,y)=>({rows:await h(t,y),startedAt:await g()}),"memory")})}}o(M,"handleAnalytics");const D=[{method:"GET",pattern:"/v1/canvas/analytics",handler:M}];export{D as analyticsRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var i=(t,e)=>c(t,"name",{value:e,configurable:!0});import{getNode as m}from"../../../core/canvas/canvas.js";import{decideAttachRevive as k}from"../../../core/runtime/revive.js";import{viewSocketPath as l}from"../../../core/canvas/paths.js";import{waitForBrokerViewSocket as v}from"../../../core/runtime/placement-tmux.js";import{notFound as
|
|
1
|
+
var c=Object.defineProperty;var i=(t,e)=>c(t,"name",{value:e,configurable:!0});import{getNode as m}from"../../../core/canvas/canvas.js";import{decideAttachRevive as k}from"../../../core/runtime/revive.js";import{viewSocketPath as l}from"../../../core/canvas/paths.js";import{waitForBrokerViewSocket as v}from"../../../core/runtime/placement-tmux.js";import{notFound as w,usage as n}from"../../../core/errors.js";import{ownerOnly as p}from"../router.js";function h(t){if(t==null)return{resume:!0,revive:!0,wakeParked:!0};if(typeof t!="object")throw n("attach body must be a JSON object { resume?, revive?, wakeParked? }");const e=t.resume,r=t.revive,o=t.wakeParked;if(e!==void 0&&typeof e!="boolean")throw n("resume must be a boolean");if(r!==void 0&&typeof r!="boolean")throw n("revive must be a boolean");if(o!==void 0&&typeof o!="boolean")throw n("wakeParked must be a boolean");return{resume:e??!0,revive:r??!0,wakeParked:o??!0}}i(h,"parseAttachBody");async function b(t){const e=t.params.id;if(await m(e)===null)throw w(`unknown node: ${e}`,{received:e});const{resume:r,revive:o,wakeParked:f}=h(t.body);let u=!1,d=!1,s=!1;if(o){const a=await k(e,{resume:r,capacity:"refuse"},f);s=a.parked,a.parked||(u=a.result.launch!==void 0,d=a.result.resumed,await v(e))}return{status:200,body:{node_id:e,socket_path:l(e),revived:u,resumed:d,parked:s}}}i(b,"handleAttach");const F=p([{method:"POST",pattern:"/v1/nodes/:id/attach",handler:b}]);export{F as attachRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var B=Object.defineProperty;var h=(
|
|
1
|
+
var B=Object.defineProperty;var h=(t,o)=>B(t,"name",{value:o,configurable:!0});import{killBashJobObject as E,recordBashJobObject as J}from"../../../core/spaces/stop.js";import{readerFor as P}from"../reader.js";import{join as $}from"node:path";import{createFileBeneath as w,existsBeneath as m,unlinkBeneath as A}from"../../../core/spaces/open-beneath.js";import{launchAppProcess as q,appProcessSandboxed as O}from"../../../core/spaces/process.js";import{BASH_JOB_SUPERVISOR_SCRIPT as N}from"../../../core/bash-job-supervisor.js";import{resolveAdmittedHostCommand as L}from"../../../core/runtime/spawn-env.js";import{requireCurrentExecution as _}from"./broker-recovery.js";import{isSafeNodeId as T}from"../../../core/canvas/paths.js";import{contextDir as v}from"../../../core/canvas/node-agent-paths.js";import{getNode as j}from"../../../core/canvas/canvas.js";import{isBrokerLive as D}from"../../../core/runtime/model-swap.js";import{assertNotFinalized as R}from"../../../core/runtime/reopen.js";import{reviveNode as C}from"../../../core/runtime/revive.js";import{activeBackgroundBashJobs as z,bashJobPaths as k,isBashJobProcessGroupAlive as F,readJobPgid as M,readJobPgidIdentity as G,isSafeBashJobId as I,readBashNiceness as H,stopBackgroundBashJob as Z}from"../../../core/bash-jobs.js";import{ApiError as i}from"../../../api/index.js";import{notFound as U}from"../../../core/errors.js";import{freshChildNodeExecPath as V}from"../../../core/runtime/branded-host.js";async function f(t){const o=t.params.id;if(o===void 0||!T(o))throw new i(400,"invalid_node_id",`invalid node id: ${JSON.stringify(o)}`);if(await j(o)===null)throw U(`unknown node: ${o}`,{received:o});const d=t.params.jobId;if(d!==void 0){if(!I(d))throw new i(400,"invalid_job_id",`invalid background job id: ${JSON.stringify(d)}`);return{nodeId:o,jobId:d,dir:await v(o)}}return{nodeId:o,dir:await v(o)}}h(f,"requireTarget");async function X(t){const{nodeId:o,dir:e}=await f(t);if(t.principal.class!=="broker"||t.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may start a job");const d=t.body;if(!d||typeof d!="object"||Array.isArray(d))throw new i(400,"invalid_request","job.start requires a JSON body");const a=d;await _(o,a.expected_execution_id);const r=a.job_id,s=a.cwd,p=a.env;if(typeof r!="string"||!I(r)||typeof s!="string"||!p||typeof p!="object"||Array.isArray(p)||Object.entries(p).some(([c,b])=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(c)||typeof b!="string"))throw new i(400,"invalid_request","invalid job id, cwd or environment");if(!O())throw new i(400,"invalid_request","job.start is only used with the root launcher");const n=k(e,r);if(!(m(n.root,n.jobRun)||m(n.root,n.jobBg))||![n.cmdSh,n.jobLog].every(c=>m(n.root,c)))throw new i(404,"job_not_found","job was not prepared by this node");const g=$(n.dir,"job.starting");try{w(n.root,g,"")}catch(c){throw c.code==="EEXIST"?new i(409,"job_already_started","job was already started"):c}let l;try{const c=p,b=L("bash",c,s),y=await j(o),S=await V();return l=await q({nodeId:o,app:y.grantee??"app:terminal",isolated:y.isolated,cwd:s,env:c,capture:!1,command:[b,"-c",N,"--",n.cmdSh,n.jobLog,n.jobExit,n.jobRun,n.jobDone,b,String(H(e)),S]}),w(n.root,n.jobPgid,String(l.pid),384),w(n.root,n.jobPgidIdentity,`launcher:${l.pid}`,384),{status:201,body:{pid:l.pid}}}catch(c){if(l!==void 0)try{await l.stop()}catch(b){throw new AggregateError([c,b],`job ${r} launched but could not be recorded or stopped`)}try{A(n.root,g)}catch(b){if(b.code!=="ENOENT")throw b}throw c}}h(X,"handleStart");async function x(t){const{nodeId:o,dir:e}=await f(t),d=Date.now();return{status:200,body:z(e).map(r=>{const s=M(e,r.jobId)??null;return{job_id:r.jobId,command:r.command,purpose:r.purpose,started_at:new Date(r.startedAtMs).toISOString(),elapsed_ms:Math.max(0,d-r.startedAtMs),pgid:s,pgid_alive:s!==null&&F(s,G(e,r.jobId))}})}}h(x,"handleList");async function K(t){const{nodeId:o,jobId:e,dir:d}=await f(t);if(e===void 0)throw new i(400,"invalid_request","a job id is required");const a=t.query.get("foreground")==="1";if(a){if(t.principal.class!=="broker"||t.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may abort its foreground job");await _(o,t.body?.expected_execution_id)}const r=await Z(d,e,a,o);if(r.kind==="missing")throw new i(404,"job_not_found",`no background job ${e} for ${o}`);if(r.kind==="retired")throw new i(404,"job_not_found",`background job ${e} for ${o} is no longer running`,{log_path:r.logPath});if(r.kind==="not-stoppable")throw new i(409,"job_not_stoppable",`job ${e} recorded no trusted process identity`,{log_path:r.logPath});if(a)return{status:200,body:{node_id:o,job_id:e,signaled:r.signaled}};await R(o),await E(e,async n=>{const u=await P(n,t);return u.class==="person"?u.person:u.class==="app"?u.app:u.node});const s=await j(o);if(s!==null&&!D(s))try{await C(o,{resume:!0,capacity:"freeze"})}catch{}return{status:200,body:{node_id:o,job_id:e,signaled:r.signaled}}}h(K,"handleStop");async function Q(t){const{nodeId:o,jobId:e,dir:d}=await f(t);if(e===void 0)throw new i(400,"invalid_request","a job id is required");if(t.principal.class!=="broker"||t.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may record its job");const a=t.body,r=k(d,e);if(typeof a?.command!="string"||a.job_dir!==r.dir||a.log_path!==r.jobLog)throw new i(400,"invalid_request",`job.background requires command, job_dir ${r.dir} and log_path ${r.jobLog}`);if(!m(r.root,r.jobBg))throw new i(404,"job_not_found",`job ${e} of ${o} is not backgrounded`);const s=a.command;return{status:201,body:{id:(await J(o,e,{command:s,jobDir:r.dir,logPath:r.jobLog})).id}}}h(Q,"handleBackground");const jo=[{method:"POST",pattern:"/v1/nodes/:id/jobs/:jobId/background",handler:Q},{method:"POST",pattern:"/v1/nodes/:id/jobs/start",handler:X},{method:"GET",pattern:"/v1/nodes/:id/jobs",handler:x},{method:"DELETE",pattern:"/v1/nodes/:id/jobs/:jobId",handler:K}];export{jo as bashJobRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var p=(o,t)=>c(o,"name",{value:t,configurable:!0});import{statSync as u}from"node:fs";import{isAbsolute as f}from"node:path";import{ApiError as d}from"../../../api/index.js";import{buildOperationalEnvBase as l}from"../../../core/runtime/spawn-env.js";import{runAppCommand as w}from"../../../core/runtime/run-command.js";import{getNode as _}from"../../../core/canvas/canvas.js";import{readProfileEnvVars as b}from"../../../core/profiles/env-store.js";import{readAppEnvVars as y}from"../../../core/profiles/app-env-store.js";import{usage as i}from"../../../core/errors.js";import{appOf as h}from"../router.js";const T=60,m=600,E=256*1024;function A(o){if(typeof o!="object"||o===null||Array.isArray(o))throw i("bash requires an object body");const t=o;if(typeof t.command!="string"||t.command==="")throw i("bash requires a non-empty `command`");if(typeof t.cwd!="string"||!f(t.cwd))throw new d(404,"cwd_not_found","cwd must name an absolute directory");try{if(!u(t.cwd).isDirectory())throw new Error("not a directory")}catch{throw new d(404,"cwd_not_found",`cwd not found: ${t.cwd}`)}const r=t.timeout_s??T;if(typeof r!="number"||!Number.isFinite(r)||r<=0||r>m)throw new d(422,"invalid_timeout",`timeout_s must be greater than 0 and at most ${m}`);if(t.profile!==void 0&&typeof t.profile!="string")throw i("profile must be a string");let n;if(t.env!==void 0){if(typeof t.env!="object"||t.env===null||Array.isArray(t.env))throw i("env must be an object of string values");n={};for(const[s
|
|
1
|
+
var c=Object.defineProperty;var p=(o,t)=>c(o,"name",{value:t,configurable:!0});import{statSync as u}from"node:fs";import{isAbsolute as f}from"node:path";import{ApiError as d}from"../../../api/index.js";import{buildOperationalEnvBase as l}from"../../../core/runtime/spawn-env.js";import{runAppCommand as w}from"../../../core/runtime/run-command.js";import{getNode as _}from"../../../core/canvas/canvas.js";import{readProfileEnvVars as b}from"../../../core/profiles/env-store.js";import{readAppEnvVars as y}from"../../../core/profiles/app-env-store.js";import{usage as i}from"../../../core/errors.js";import{appOf as h}from"../router.js";const T=60,m=600,E=256*1024;function A(o){if(typeof o!="object"||o===null||Array.isArray(o))throw i("bash requires an object body");const t=o;if(typeof t.command!="string"||t.command==="")throw i("bash requires a non-empty `command`");if(typeof t.cwd!="string"||!f(t.cwd))throw new d(404,"cwd_not_found","cwd must name an absolute directory");try{if(!u(t.cwd).isDirectory())throw new Error("not a directory")}catch{throw new d(404,"cwd_not_found",`cwd not found: ${t.cwd}`)}const r=t.timeout_s??T;if(typeof r!="number"||!Number.isFinite(r)||r<=0||r>m)throw new d(422,"invalid_timeout",`timeout_s must be greater than 0 and at most ${m}`);if(t.profile!==void 0&&typeof t.profile!="string")throw i("profile must be a string");let n;if(t.env!==void 0){if(typeof t.env!="object"||t.env===null||Array.isArray(t.env))throw i("env must be an object of string values");n={};for(const[a,s]of Object.entries(t.env)){if(typeof s!="string")throw i("env must be an object of string values");n[a]=s}}return{command:t.command,cwd:t.cwd,timeout_s:r,env:n,profile:t.profile}}p(A,"parseRequest");async function g(o){const t=A(o.body),r=h(o.principal)??"app:terminal";if(r!=="app:terminal"&&t.profile!==void 0)throw new d(403,"permission_error","app bash cannot select an owner profile");const n=r==="app:terminal"?t.profile??null:null,a=l({targetCwd:t.cwd,targetProfileId:n,skipSpawnAllow:r!=="app:terminal"}),s={...a,...y(r),...r==="app:terminal"?b(n):{},...t.env,...n===null?{}:{CRTR_PROFILE_ID:n},CRTR_ADMITTED_HOST_PATH:a.CRTR_ADMITTED_HOST_PATH},e=await(await w({app:r,...o.principal.class==="broker"?{nodeId:o.principal.node,isolated:(await _(o.principal.node))?.isolated===!0}:{},command:t.command,cwd:t.cwd,env:s,timeoutMs:t.timeout_s*1e3,headBytes:E})).completion;if(e.processError!==null)throw e.processError;return{status:200,body:{exit_code:e.timedOut?null:e.exitCode,signal:e.signal,stdout:e.stdout,stdout_truncated:e.stdoutTruncated,stderr:e.stderr,stderr_truncated:e.stderrTruncated,timed_out:e.timedOut,duration_ms:e.durationMs}}}p(g,"handleBash");const q=[{method:"POST",pattern:"/v1/bash",scope:"crtr:act",handler:g}];export{q as bashRoutes};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BrokerExtensionNodeDTO } from '../../../api/dto/broker-ops.js';
|
|
2
2
|
import { getNode } from '../../../core/canvas/canvas.js';
|
|
3
3
|
import { type RouteTable } from '../router.js';
|
|
4
|
-
export declare function extensionNode(node: NonNullable<ReturnType<typeof getNode
|
|
4
|
+
export declare function extensionNode(node: NonNullable<Awaited<ReturnType<typeof getNode>>>): Promise<BrokerExtensionNodeDTO>;
|
|
5
5
|
export declare const brokerOperationRoutes: RouteTable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var A=Object.defineProperty;var i=(e,t)=>A(e,"name",{value:t,configurable:!0});import{canonicalSessionFile as F,findNodeBySessionFile as O,getNode as y,isWarmSpare as R,listNodeIdentities as T,recordRespawnAttempt as I,recordSettledTurn as $,setPresence as b,subscriptionsOf as j,updateNode as g,updateNodeTelemetry as C}from"../../../core/canvas/canvas.js";import{recordExecutionPid as q}from"../../../core/canvas/executions.js";import{bindSession as E,readLiveSession as M,transferSession as L}from"../../../core/canvas/sessions.js";import{isSafeNodeId as D}from"../../../core/canvas/paths.js";import{appForNode as G}from"../../../core/canvas/node-agent-paths.js";import{isPidAlive as J}from"../../../core/canvas/pid.js";import{editorLabel as P}from"../../../core/canvas/labels.js";import{assembleNodeSubject as W}from"../../../core/substrate/subject.js";import{withCanvasWrite as l}from"../../../core/canvas/db.js";import{notFound as v,usage as a}from"../../../core/errors.js";import{hasUnseenWakeMail as N}from"../../../core/canvas/deliveries.js";import{clearYieldMessage as U}from"../../../core/runtime/kickoff.js";import{readRoadmap as V}from"../../../core/runtime/roadmap.js";import{forkSourceNode as Y}from"../../../core/runtime/nodes.js";import{transition as _}from"../../../core/runtime/lifecycle.js";import{focusOf as k,tearDownNode as x}from"../../../core/runtime/placement.js";import{hasAttachedBrokerViewers as z}from"../viewer-presence.js";import{evaluateStop as H}from"../../../core/runtime/stop-guard.js";import{clearFault as h,recordFault as K}from"../../../core/canvas/recovery.js";import{updateModelRecipe as Q}from"../../../core/runtime/model-swap.js";import{completeCompanionRequestedSubmit as X}from"../../review/finish.js";import{emitEvent as Z}from"../../../core/events/emit.js";import{consumePendingPark as ee,recordPendingParkActivity as te}from"../../park-pending.js";import{shouldParkAfterSummary as ne}from"../../park-activity.js";import{ownerOnly as oe}from"../router.js";import{requireCurrentExecution as m}from"./broker-recovery.js";import{ensureRunObserver as re}from"../../runs/observer.js";import{parseNodeTelemetryRecord as ie,writeNodeTelemetryRecord as se}from"./telemetry-record.js";function p(e,t){if(typeof e!="object"||e===null||Array.isArray(e))throw a(`${t} requires a JSON body`);return e}i(p,"objectBody");function ae(e){const t=p(e,"broker session-bound");if(typeof t.executionId!="string"||t.executionId==="")throw a("executionId must be a non-empty string");if(typeof t.piSessionId!="string"||t.piSessionId==="")throw a("piSessionId must be a non-empty string");if(t.sessionFile!==null&&typeof t.sessionFile!="string")throw a("sessionFile must be a string or null");if(!Number.isSafeInteger(t.pid)||t.pid<=0)throw a("pid must be a positive safe integer");if(t.reason!==null&&typeof t.reason!="string")throw a("reason must be a string or null");if(!Array.isArray(t.reviewBoundaryIds)||!t.reviewBoundaryIds.every(n=>typeof n=="string"))throw a("reviewBoundaryIds must be an array of strings");return t}i(ae,"parseSessionBoundBody");function de(e){const t=p(e,"broker settle");if(typeof t.stopReason!="string")throw a("stopReason must be a string");for(const n of["backgroundJobsRunning","pushedFinal"])if(typeof t[n]!="boolean")throw a(`${n} must be a boolean`);return t}i(de,"parseSettleBody");function ue(e){const t=p(e,"broker park-complete");if(t.outcome!=="completed"&&t.outcome!=="failed")throw a("outcome must be completed or failed");return t}i(ue,"parseParkCompleteBody");function ce(e){const t=p(e,"broker telemetry");if(typeof t.expected_execution_id!="string"||t.expected_execution_id==="")throw a("expected_execution_id must be a non-empty string");const n=ie(t);return{...n,expected_execution_id:t.expected_execution_id,updated_at:new Date(n.updated_at).toISOString()}}i(ce,"parseTelemetryBody");function le(e){const t=p(e,"broker model");if(typeof t.spec!="string"||t.spec.trim()==="")throw a("spec must be a non-empty string");const n=t.intent;if(n!==void 0){const r=n!==null&&typeof n=="object"?n:void 0;if(r===void 0||typeof r.family!="string"||r.family===""||!["ultra","strong","medium","light"].includes(r.strength))throw a("intent must be { family, strength } with strength ultra|strong|medium|light when present")}if(typeof t.userSelected!="boolean")throw a("userSelected must be a boolean");return t}i(le,"parseModelCommitBody");function f(e){const t=y(e);if(t===null)throw v(`unknown node: ${e}`,{received:e});return t}i(f,"requireNode");function w(e){return{node_id:e.node_id,grantee:G(e.node_id),name:e.name,...e.description===void 0?{}:{description:e.description},...e.title===void 0?{}:{title:e.title},...e.icon===void 0?{}:{icon:e.icon},kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,parent:e.parent??null,fork_from:e.fork_from??null,profile_id:e.profile_id??null,...e.managed_worktree===void 0?{}:{managed_worktree:e.managed_worktree===null?null:{state:e.managed_worktree.state,...e.managed_worktree.cleanup===void 0?{}:{cleanup:e.managed_worktree.cleanup},path:e.managed_worktree.path,branch:e.managed_worktree.branch,base_ref:e.managed_worktree.base_ref,base_sha:e.managed_worktree.base_sha}},...e.review_binding===void 0?{}:{review_binding:e.review_binding??null},intent:e.intent??null,...e.persona_ack===void 0?{}:{persona_ack:e.persona_ack},created:e.created}}i(w,"extensionNode");function pe(e){const t=f(e),n=[],r=new Set([e]);let o=t.parent??null;for(;o!==null&&o!==""&&!r.has(o);){r.add(o);const c=y(o);if(c===null)break;n.unshift(w(c)),o=c.parent??null}const s=j(e).map(c=>y(c.node_id)).filter(c=>c!==null&&c.kind!=="human").sort((c,S)=>c.status===S.status?0:c.status==="active"?-1:S.status==="active"?1:0).map(w),u=typeof t.fork_source_file=="string"?Y(t.fork_source_file):null,d=W(e);if(d===null)throw v(`unknown node: ${e}`,{received:e});return{node:w(t),warm_spare:R(e),ancestors:n,children:s,fork_source:u===null?null:w(u),subject:d,report_nodes:T(),roadmap:V(e)}}i(pe,"extensionState");function B(e,t){return e?.kind===t.kind&&e?.mode===t.mode&&e?.lifecycle===t.lifecycle}i(B,"samePersona");function me(e){const t=p(e,"broker generated-name");if(t.kind!=="initial"&&t.kind!=="recap")throw a("kind must be initial or recap");if(typeof t.description!="string"||typeof t.title!="string"||typeof t.icon!="string")throw a("description, title, and icon must be strings");if(t.kind==="initial")return t;const n=t.expected;if(typeof n!="object"||n===null||Array.isArray(n)||["name","description","title","icon","kind"].some(r=>typeof n[r]!="string"))throw a("recap expected must contain name, description, title, icon, and kind strings");return t}i(me,"parseGeneratedNameBody");function fe(e){const t=p(e,"broker persona-ack"),n=i(r=>{const o=t[r];if(typeof o!="object"||o===null||Array.isArray(o)||typeof o.kind!="string"||o.mode!=="base"&&o.mode!=="orchestrator"||o.lifecycle!=="terminal"&&o.lifecycle!=="resident")throw a(`${r} must be a persona state`);return o},"parse");return{expected_execution_id:t.expected_execution_id,from:n("from"),to:n("to")}}i(fe,"parsePersonaAckBody");function he(e){const t=e.params.id,n=ae(e.body),r=n.sessionFile===null?null:F(n.sessionFile);return{status:200,body:l(()=>{const s=f(t);if(q(n.executionId,t,n.pid)==="shutdown")return{action:"shutdown"};const u=s.review_binding?.review_id;if(u!==void 0&&!n.reviewBoundaryIds.includes(u))return{action:"shutdown"};if(n.reason==="new"&&s.parent==null)return{action:"relaunch_root"};if(n.reason!=="new"&&s.fork_from!=null&&s.pi_session_id==null&&r===null)return{action:"shutdown"};const d=r===null?null:O(r);if(d!==null&&d.node_id!==t){if(J(d.pi_pid))return K(t,{link:"daemon\u2192node",op:"session-file-ownership",kind:"protocol",retry:{disposition:"fatal"},message:`refusing to bind ${r}: it is owned by live node ${d.node_id}`}),{action:"shutdown"};const c=M(d.node_id);if(c===null||L({fromNodeId:d.node_id,fromBindingId:c.bindingId,toNodeId:t,executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:r})!=="transferred")return{action:"shutdown"}}else if(E(t,{executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:r})==="shutdown")return{action:"shutdown"};return n.reason!=="new"&&(U(t),s.intent==="refresh"&&_(t,"revive")),{action:"none"}})}}i(he,"handleSessionBound");function ye(e,t){const n=y(e);if(n===null){if(t.pushedFinal)return{action:"shutdown"};throw v(`unknown node: ${e}`,{received:e})}if($(e,new Date().toISOString()),(t.stopReason==="stop"||t.stopReason==="length")&&I(e,{failures:0,notBefore:null}),t.stopReason==="quit")return(n.status==="active"||n.status==="idle")&&n.intent===null&&(_(e,"finish"),h(e),k(e)!==null&&x(e),b(e,{pane:null,tmux_session:null,window:null})),{action:"shutdown"};if(t.stopReason!=="stop"&&t.stopReason!=="length")return h(e,{link:"daemon\u2192node"}),n.intent==="refresh"?{action:"shutdown"}:{action:"stay_dormant"};const r={pushedFinal:t.pushedFinal};if(r.pushedFinal||n.status==="done")return h(e),k(e)!==null&&x(e),b(e,{pane:null,tmux_session:null,window:null}),{action:"shutdown"};if(n.intent==="refresh")return h(e),{action:"shutdown"};const o=H(e,r,t.backgroundJobsRunning);return h(e),o.action==="reprompt"?{action:"reprompt",prompt:o.message}:o.reason==="finished"?N(e)?{action:"stay_dormant"}:{action:"shutdown"}:o.reason!=="awaiting"&&o.reason!=="scheduled"?{action:"stay_dormant"}:k(e)!==null||z(e)||N(e)?{action:"stay_dormant"}:(_(e,"release"),{action:"shutdown"})}i(ye,"settleBroker");function _e(e){const t=e.params.id,n=de(e.body);m(t,n.expected_execution_id);const r=l(()=>ye(t,n));return r.action!=="reprompt"&&X(t),{status:200,body:r}}i(_e,"handleSettle");function ke(e){const t=e.params.id,n=ue(e.body);return m(t,n.expected_execution_id),{status:200,body:l(()=>{const o=ee(t);if(o===void 0)return{action:"stay_dormant"};const s=f(t);return ne(t,s,o)?(h(t),_(t,"park"),k(t)!==null&&x(t),b(t,{pane:null,tmux_session:null,window:null}),Z({level:n.outcome==="completed"?"info":"warn",event:"broker.park.complete",...D(t)?{node_id:t}:{},outcome:n.outcome==="completed"?"succeeded":"failed"}),{action:"shutdown"}):{action:"stay_dormant"}})}}i(ke,"handleParkComplete");function we(e){const t=e.params.id;return m(t,p(e.body,"broker park-activity").expected_execution_id),{status:200,body:l(()=>({activity:te(t)?"recorded":"none"}))}}i(we,"handleParkActivity");function be(e){const t=e.params.id,n=ce(e.body);return m(t,n.expected_execution_id),l(()=>{C(t,{tokensIn:n.tokens_in,contextTokens:n.context_tokens,lastActivity:n.last_activity,updatedAt:n.updated_at}),se(t,n)}),{status:204}}i(be,"handleTelemetry");function ge(e){const t=e.params.id,n=le(e.body);return m(t,n.expected_execution_id),{status:200,body:{modelOverride:l(()=>Q(f(t),n.spec,n.intent,n.userSelected)).model_override}}}i(ge,"handleModelCommit");function ve(e){const t=e.params.id,n=f(t);return n.run_id&&re(t,n.run_id),{status:200,body:pe(t)}}i(ve,"handleExtensionState");function xe(e){const t=e.params.id,n=me(e.body);return m(t,n.expected_execution_id),{status:200,body:l(()=>{const o=f(t);if(n.kind==="initial"){if((o.description??"").trim()!=="")return{applied:!1};const d=g(t,{description:n.description,...n.title.trim()===""?{}:{title:n.title},...n.icon.trim()===""?{}:{icon:n.icon}});return{applied:!0,editorLabel:P(d),description:d.description??"",title:d.title??"",icon:d.icon??""}}const s=n.expected;if(o.name!==s.name||(o.description??"")!==s.description||(o.title??"")!==s.title||(o.icon??"")!==s.icon||o.kind!==s.kind)return{applied:!1};const u=g(t,{description:n.description,title:n.title.trim()===""?void 0:n.title,icon:n.icon.trim()===""?void 0:n.icon});return{applied:!0,editorLabel:P(u),description:u.description??"",title:u.title??"",icon:u.icon??""}})}}i(xe,"handleGeneratedName");function Se(e){const t=e.params.id,n=fe(e.body);return m(t,n.expected_execution_id),{status:200,body:l(()=>{const o=f(t),s={kind:o.kind,mode:o.mode,lifecycle:o.lifecycle},u=o.persona_ack,d=u===void 0?s:{kind:u.kind??o.kind,mode:u.mode,lifecycle:u.lifecycle};return!B(s,n.to)||!B(d,n.from)?{applied:!1}:(g(t,{persona_ack:n.to}),{applied:!0})})}}i(Se,"handlePersonaAck");const et=oe([{method:"POST",pattern:"/v1/nodes/:id/broker/session-bound",handler:he},{method:"POST",pattern:"/v1/nodes/:id/broker/settle",handler:_e},{method:"POST",pattern:"/v1/nodes/:id/broker/park-complete",handler:ke},{method:"POST",pattern:"/v1/nodes/:id/broker/park-activity",handler:we},{method:"POST",pattern:"/v1/nodes/:id/broker/telemetry",handler:be},{method:"POST",pattern:"/v1/nodes/:id/broker/model",handler:ge},{method:"GET",pattern:"/v1/nodes/:id/broker/extension-state",handler:ve},{method:"POST",pattern:"/v1/nodes/:id/broker/generated-name",handler:xe},{method:"POST",pattern:"/v1/nodes/:id/broker/persona-ack",handler:Se}]);export{et as brokerOperationRoutes,w as extensionNode};
|
|
1
|
+
var F=Object.defineProperty;var r=(e,t)=>F(e,"name",{value:t,configurable:!0});import{canonicalSessionFile as O,findNodeBySessionFile as R,getNode as y,isWarmSpare as T,listNodeIdentities as I,recordRespawnAttempt as $,recordSettledTurn as j,setPresence as b,subscriptionsOf as C,updateNode as g,updateNodeTelemetry as q}from"../../../core/canvas/canvas.js";import{recordExecutionPid as E}from"../../../core/canvas/executions.js";import{bindSession as M,readLiveSession as L,transferSession as D}from"../../../core/canvas/sessions.js";import{isSafeNodeId as G}from"../../../core/canvas/paths.js";import{appForNode as J}from"../../../core/canvas/node-agent-paths.js";import{isPidAlive as W}from"../../../core/canvas/pid.js";import{editorLabel as P}from"../../../core/canvas/labels.js";import{assembleNodeSubject as U}from"../../../core/substrate/subject.js";import{withCanvasWrite as l}from"../../../core/canvas/db.js";import{notFound as v,usage as s}from"../../../core/errors.js";import{hasUnseenWakeMail as N}from"../../../core/canvas/deliveries.js";import{clearYieldMessage as V}from"../../../core/runtime/kickoff.js";import{readRoadmap as Y}from"../../../core/runtime/roadmap.js";import{forkSourceNode as z}from"../../../core/runtime/nodes.js";import{transition as h}from"../../../core/runtime/lifecycle.js";import{focusOf as _,tearDownNode as x}from"../../../core/runtime/placement.js";import{hasAttachedBrokerViewers as H}from"../viewer-presence.js";import{evaluateStop as K}from"../../../core/runtime/stop-guard.js";import{clearFault as w,recordFault as Q}from"../../../core/canvas/recovery.js";import{updateModelRecipe as X}from"../../../core/runtime/model-swap.js";import{completeCompanionRequestedSubmit as Z}from"../../review/finish.js";import{emitEvent as ee}from"../../../core/events/emit.js";import{consumePendingPark as te,recordPendingParkActivity as ne}from"../../park-pending.js";import{shouldParkAfterSummary as ie}from"../../park-activity.js";import{ownerOnly as oe}from"../router.js";import{requireCurrentExecution as m}from"./broker-recovery.js";import{ensureRunObserver as re}from"../../runs/observer.js";import{parseNodeTelemetryRecord as ae,writeNodeTelemetryRecord as se}from"./telemetry-record.js";import{mapAsync as A}from"../../../core/async-array.js";function p(e,t){if(typeof e!="object"||e===null||Array.isArray(e))throw s(`${t} requires a JSON body`);return e}r(p,"objectBody");function de(e){const t=p(e,"broker session-bound");if(typeof t.executionId!="string"||t.executionId==="")throw s("executionId must be a non-empty string");if(typeof t.piSessionId!="string"||t.piSessionId==="")throw s("piSessionId must be a non-empty string");if(t.sessionFile!==null&&typeof t.sessionFile!="string")throw s("sessionFile must be a string or null");if(!Number.isSafeInteger(t.pid)||t.pid<=0)throw s("pid must be a positive safe integer");if(t.reason!==null&&typeof t.reason!="string")throw s("reason must be a string or null");if(!Array.isArray(t.reviewBoundaryIds)||!t.reviewBoundaryIds.every(n=>typeof n=="string"))throw s("reviewBoundaryIds must be an array of strings");return t}r(de,"parseSessionBoundBody");function ce(e){const t=p(e,"broker settle");if(typeof t.stopReason!="string")throw s("stopReason must be a string");for(const n of["backgroundJobsRunning","pushedFinal"])if(typeof t[n]!="boolean")throw s(`${n} must be a boolean`);return t}r(ce,"parseSettleBody");function ue(e){const t=p(e,"broker park-complete");if(t.outcome!=="completed"&&t.outcome!=="failed")throw s("outcome must be completed or failed");return t}r(ue,"parseParkCompleteBody");function le(e){const t=p(e,"broker telemetry");if(typeof t.expected_execution_id!="string"||t.expected_execution_id==="")throw s("expected_execution_id must be a non-empty string");const n=ae(t);return{...n,expected_execution_id:t.expected_execution_id,updated_at:new Date(n.updated_at).toISOString()}}r(le,"parseTelemetryBody");function pe(e){const t=p(e,"broker model");if(typeof t.spec!="string"||t.spec.trim()==="")throw s("spec must be a non-empty string");const n=t.intent;if(n!==void 0){const o=n!==null&&typeof n=="object"?n:void 0;if(o===void 0||typeof o.family!="string"||o.family===""||!["ultra","strong","medium","light"].includes(o.strength))throw s("intent must be { family, strength } with strength ultra|strong|medium|light when present")}if(typeof t.userSelected!="boolean")throw s("userSelected must be a boolean");return t}r(pe,"parseModelCommitBody");async function f(e){const t=await y(e);if(t===null)throw v(`unknown node: ${e}`,{received:e});return t}r(f,"requireNode");async function k(e){return{node_id:e.node_id,grantee:await J(e.node_id),name:e.name,...e.description===void 0?{}:{description:e.description},...e.title===void 0?{}:{title:e.title},...e.icon===void 0?{}:{icon:e.icon},kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,parent:e.parent??null,fork_from:e.fork_from??null,profile_id:e.profile_id??null,...e.managed_worktree===void 0?{}:{managed_worktree:e.managed_worktree===null?null:{state:e.managed_worktree.state,...e.managed_worktree.cleanup===void 0?{}:{cleanup:e.managed_worktree.cleanup},path:e.managed_worktree.path,branch:e.managed_worktree.branch,base_ref:e.managed_worktree.base_ref,base_sha:e.managed_worktree.base_sha}},...e.review_binding===void 0?{}:{review_binding:e.review_binding??null},intent:e.intent??null,...e.persona_ack===void 0?{}:{persona_ack:e.persona_ack},created:e.created}}r(k,"extensionNode");async function me(e){const t=await f(e),n=[],o=new Set([e]);let i=t.parent??null;for(;i!==null&&i!==""&&!o.has(i);){o.add(i);const u=await y(i);if(u===null)break;n.unshift(await k(u)),i=u.parent??null}const a=await A((await A(await C(e),async u=>await y(u.node_id))).filter(u=>u!==null&&u.kind!=="human").sort((u,S)=>u.status===S.status?0:u.status==="active"?-1:S.status==="active"?1:0),k),c=typeof t.fork_source_file=="string"?await z(t.fork_source_file):null,d=await U(e);if(d===null)throw v(`unknown node: ${e}`,{received:e});return{node:await k(t),warm_spare:await T(e),ancestors:n,children:a,fork_source:c===null?null:await k(c),subject:d,report_nodes:await I(),roadmap:await Y(e)}}r(me,"extensionState");function B(e,t){return e?.kind===t.kind&&e?.mode===t.mode&&e?.lifecycle===t.lifecycle}r(B,"samePersona");function fe(e){const t=p(e,"broker generated-name");if(t.kind!=="initial"&&t.kind!=="recap")throw s("kind must be initial or recap");if(typeof t.description!="string"||typeof t.title!="string"||typeof t.icon!="string")throw s("description, title, and icon must be strings");if(t.kind==="initial")return t;const n=t.expected;if(typeof n!="object"||n===null||Array.isArray(n)||["name","description","title","icon","kind"].some(o=>typeof n[o]!="string"))throw s("recap expected must contain name, description, title, icon, and kind strings");return t}r(fe,"parseGeneratedNameBody");function we(e){const t=p(e,"broker persona-ack"),n=r(o=>{const i=t[o];if(typeof i!="object"||i===null||Array.isArray(i)||typeof i.kind!="string"||i.mode!=="base"&&i.mode!=="orchestrator"||i.lifecycle!=="terminal"&&i.lifecycle!=="resident")throw s(`${o} must be a persona state`);return i},"parse");return{expected_execution_id:t.expected_execution_id,from:n("from"),to:n("to")}}r(we,"parsePersonaAckBody");async function ye(e){const t=e.params.id,n=de(e.body),o=n.sessionFile===null?null:O(n.sessionFile);return{status:200,body:await l(async()=>{const a=await f(t);if(await E(n.executionId,t,n.pid)==="shutdown")return{action:"shutdown"};const c=a.review_binding?.review_id;if(c!==void 0&&!n.reviewBoundaryIds.includes(c))return{action:"shutdown"};if(n.reason==="new"&&a.parent==null)return{action:"relaunch_root"};if(n.reason!=="new"&&a.fork_from!=null&&a.pi_session_id==null&&o===null)return{action:"shutdown"};const d=o===null?null:await R(o);if(d!==null&&d.node_id!==t){if(W(d.pi_pid))return await Q(t,{link:"daemon\u2192node",op:"session-file-ownership",kind:"protocol",retry:{disposition:"fatal"},message:`refusing to bind ${o}: it is owned by live node ${d.node_id}`}),{action:"shutdown"};const u=await L(d.node_id);if(u===null||await D({fromNodeId:d.node_id,fromBindingId:u.bindingId,toNodeId:t,executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:o})!=="transferred")return{action:"shutdown"}}else if(await M(t,{executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:o})==="shutdown")return{action:"shutdown"};return n.reason!=="new"&&(await V(t),a.intent==="refresh"&&await h(t,"revive")),{action:"none"}})}}r(ye,"handleSessionBound");async function he(e,t){const n=await y(e);if(n===null){if(t.pushedFinal)return{action:"shutdown"};throw v(`unknown node: ${e}`,{received:e})}if(await j(e,new Date().toISOString()),(t.stopReason==="stop"||t.stopReason==="length")&&await $(e,{failures:0,notBefore:null}),t.stopReason==="quit")return(n.status==="active"||n.status==="idle")&&n.intent===null&&(await h(e,"finish"),await w(e),await _(e)!==null&&await x(e),await b(e,{pane:null,tmux_session:null,window:null})),{action:"shutdown"};if(t.stopReason!=="stop"&&t.stopReason!=="length")return await w(e,{link:"daemon\u2192node"}),n.intent==="refresh"?{action:"shutdown"}:{action:"stay_dormant"};const o={pushedFinal:t.pushedFinal};if(o.pushedFinal||n.status==="done")return await w(e),await _(e)!==null&&await x(e),await b(e,{pane:null,tmux_session:null,window:null}),{action:"shutdown"};if(n.intent==="refresh")return await w(e),{action:"shutdown"};const i=await K(e,o,t.backgroundJobsRunning);return await w(e),i.action==="reprompt"?{action:"reprompt",prompt:i.message}:i.reason==="finished"?await N(e)?{action:"stay_dormant"}:{action:"shutdown"}:i.reason!=="awaiting"&&i.reason!=="scheduled"?{action:"stay_dormant"}:await _(e)!==null||H(e)||await N(e)?{action:"stay_dormant"}:(await h(e,"release"),{action:"shutdown"})}r(he,"settleBroker");async function _e(e){const t=e.params.id,n=ce(e.body);await m(t,n.expected_execution_id);const o=await l(async()=>await he(t,n));return o.action!=="reprompt"&&Z(t),{status:200,body:o}}r(_e,"handleSettle");async function ke(e){const t=e.params.id,n=ue(e.body);return await m(t,n.expected_execution_id),{status:200,body:await l(async()=>{const i=te(t);if(i===void 0)return{action:"stay_dormant"};const a=await f(t);return await ie(t,a,i)?(await w(t),await h(t,"park"),await _(t)!==null&&await x(t),await b(t,{pane:null,tmux_session:null,window:null}),ee({level:n.outcome==="completed"?"info":"warn",event:"broker.park.complete",...G(t)?{node_id:t}:{},outcome:n.outcome==="completed"?"succeeded":"failed"}),{action:"shutdown"}):{action:"stay_dormant"}})}}r(ke,"handleParkComplete");async function be(e){const t=e.params.id;return await m(t,p(e.body,"broker park-activity").expected_execution_id),{status:200,body:await l(async()=>({activity:ne(t)?"recorded":"none"}))}}r(be,"handleParkActivity");async function ge(e){const t=e.params.id,n=le(e.body);return await m(t,n.expected_execution_id),await l(async()=>{await q(t,{tokensIn:n.tokens_in,contextTokens:n.context_tokens,lastActivity:n.last_activity,updatedAt:n.updated_at}),se(t,n)}),{status:204}}r(ge,"handleTelemetry");async function ve(e){const t=e.params.id,n=pe(e.body);return await m(t,n.expected_execution_id),{status:200,body:{modelOverride:(await l(async()=>await X(await f(t),n.spec,n.intent,n.userSelected))).model_override}}}r(ve,"handleModelCommit");async function xe(e){const t=e.params.id,n=await f(t);return n.run_id&&await re(t,n.run_id),{status:200,body:await me(t)}}r(xe,"handleExtensionState");async function Se(e){const t=e.params.id,n=fe(e.body);return await m(t,n.expected_execution_id),{status:200,body:await l(async()=>{const i=await f(t);if(n.kind==="initial"){if((i.description??"").trim()!=="")return{applied:!1};const d=await g(t,{description:n.description,...n.title.trim()===""?{}:{title:n.title},...n.icon.trim()===""?{}:{icon:n.icon}});return{applied:!0,editorLabel:P(d),description:d.description??"",title:d.title??"",icon:d.icon??""}}const a=n.expected;if(i.name!==a.name||(i.description??"")!==a.description||(i.title??"")!==a.title||(i.icon??"")!==a.icon||i.kind!==a.kind)return{applied:!1};const c=await g(t,{description:n.description,title:n.title.trim()===""?void 0:n.title,icon:n.icon.trim()===""?void 0:n.icon});return{applied:!0,editorLabel:P(c),description:c.description??"",title:c.title??"",icon:c.icon??""}})}}r(Se,"handleGeneratedName");async function Pe(e){const t=e.params.id,n=we(e.body);return await m(t,n.expected_execution_id),{status:200,body:await l(async()=>{const i=await f(t),a={kind:i.kind,mode:i.mode,lifecycle:i.lifecycle},c=i.persona_ack,d=c===void 0?a:{kind:c.kind??i.kind,mode:c.mode,lifecycle:c.lifecycle};return!B(a,n.to)||!B(d,n.from)?{applied:!1}:(await g(t,{persona_ack:n.to}),{applied:!0})})}}r(Pe,"handlePersonaAck");const nt=oe([{method:"POST",pattern:"/v1/nodes/:id/broker/session-bound",handler:ye},{method:"POST",pattern:"/v1/nodes/:id/broker/settle",handler:_e},{method:"POST",pattern:"/v1/nodes/:id/broker/park-complete",handler:ke},{method:"POST",pattern:"/v1/nodes/:id/broker/park-activity",handler:be},{method:"POST",pattern:"/v1/nodes/:id/broker/telemetry",handler:ge},{method:"POST",pattern:"/v1/nodes/:id/broker/model",handler:ve},{method:"GET",pattern:"/v1/nodes/:id/broker/extension-state",handler:xe},{method:"POST",pattern:"/v1/nodes/:id/broker/generated-name",handler:Se},{method:"POST",pattern:"/v1/nodes/:id/broker/persona-ack",handler:Pe}]);export{nt as brokerOperationRoutes,k as extensionNode};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type RouteTable } from '../router.js';
|
|
2
|
-
export declare function requireCurrentExecution(nodeId: string, expectedExecutionId: unknown): void
|
|
2
|
+
export declare function requireCurrentExecution(nodeId: string, expectedExecutionId: unknown): Promise<void>;
|
|
3
3
|
export declare const brokerRecoveryRoutes: RouteTable;
|
|
4
4
|
export declare const nodeFaultRoutes: RouteTable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var k=Object.defineProperty;var o=(r,e)=>k(r,"name",{value:e,configurable:!0});import{ApiError as E}from"../../../api/errors.js";import{getNode as I}from"../../../core/canvas/canvas.js";import{liveExecutionForNode as S}from"../../../core/canvas/executions.js";import{admitEpisode as T,clearEpisode as q,clearFault as m,closeTurn as P,invalidateEpisode as R,openTurn as h,parseProviderError as F,readEpisode as A,readFault as l,recordFault as v,recordPendingEpisode as N,recordTransportPoisonVerdict as O,recordTurnProgress as j,reopenEpisode as L}from"../../../core/canvas/recovery.js";import{notFound as D,usage as n}from"../../../core/errors.js";import{hasPresentedViewer as B}from"../viewer-presence.js";import{ownerOnly as b}from"../router.js";const f=new Set(["pi\u2192provider","viewer\u2194broker","relay\u2194broker","viewer\u2194crtrd","daemon\u2192node","crtr\u2192pi"]),$=new Set(["rate-limit","overloaded","connection","auth","protocol","context-overflow","other","wedged","model-not-found"]),C=new Set(["auto","manual","fatal"]),K=new Set(["sdk","daemon","client"]);function d(r,e){if(typeof r!="object"||r===null||Array.isArray(r))throw n(`${e} requires a JSON object`);return r}o(d,"objectBody");async function a(r){if(await I(r)===null)throw D(`unknown node: ${r}`,{received:r})}o(a,"requireNode");async function c(r,e){if(typeof e!="string"||e==="")throw n("expected_execution_id must be a non-empty string");const t=await S(r);if(t===null||t.executionId!==e)throw new E(409,"stale_execution","broker execution is no longer current")}o(c,"requireCurrentExecution");function g(r){if(typeof r!="object"||r===null||Array.isArray(r))throw n("retry must be an object");const e=r;if(!C.has(e.disposition))throw n("retry.disposition must be auto, manual, or fatal");if(e.by!==void 0&&!K.has(e.by))throw n("retry.by must be sdk, daemon, or client");for(const t of["attempt","max"])if(e[t]!==void 0&&(!Number.isSafeInteger(e[t])||e[t]<0))throw n(`retry.${t} must be a non-negative safe integer`);if(e.nextAt!==void 0&&typeof e.nextAt!="string")throw n("retry.nextAt must be a string");return e}o(g,"parseRetry");function _(r){const e=d(r,"fault input");if(!f.has(e.link))throw n("fault link is invalid");if(typeof e.op!="string"||e.op==="")throw n("fault op must be a non-empty string");if(!$.has(e.kind))throw n("fault kind is invalid");if(typeof e.message!="string")throw n("fault message must be a string");if(e.operation_id!==void 0&&(typeof e.operation_id!="string"||e.operation_id===""))throw n("operation_id must be a non-empty string");if(e.since!==void 0&&typeof e.since!="string")throw n("since must be a string");if(e.anchor_entry_id!==void 0&&(typeof e.anchor_entry_id!="string"||e.anchor_entry_id===""))throw n("anchor_entry_id must be a non-empty string");const t=e.provider_error===void 0?void 0:F(e.provider_error);if(e.provider_error!==void 0&&t===void 0)throw n("provider_error is invalid");return{...e,...t===void 0?{}:{provider_error:t},retry:g(e.retry)}}o(_,"parseFaultInput");function y(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,...r.operation_id===void 0?{}:{operation_id:r.operation_id},...r.since===void 0?{}:{since:r.since},...r.anchor_entry_id===void 0?{}:{anchorEntryId:r.anchor_entry_id},...r.provider_error===void 0?{}:{providerError:r.provider_error}}}o(y,"faultInput");function u(r){return{fault_id:r.faultId,link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,since:r.since,operation_id:r.operation_id,...r.anchorEntryId===void 0?{}:{anchor_entry_id:r.anchorEntryId},...r.providerError===void 0?{}:{provider_error:r.providerError}}}o(u,"faultDto");async function x(r){const e=await l(r),t=await A(r);return{fault:e===null?null:u(e),episode:t===null?null:{state:t.state,session_id:t.sessionId,fault:u(t.fault)}}}o(x,"recoveryState");function U(r){const e=d(r,"broker turn"),t=e.event;if(t!=="started"&&t!=="progress"&&t!=="closed"&&t!=="interrupted"&&t!=="exit-diagnostic")throw n("event is invalid");if(typeof e.expected_execution_id!="string"||e.expected_execution_id==="")throw n("expected_execution_id must be a non-empty string");if(t==="closed"){if(e.end_reason!=="settled"&&e.end_reason!=="teardown-aborted")throw n("closed turn requires end_reason settled or teardown-aborted")}else if(e.end_reason!==void 0)throw n("end_reason is valid only for closed turns");if(t==="exit-diagnostic"){const i=d(e.exit_diagnostic,"exit_diagnostic"),s=d(i.transport_poison,"exit_diagnostic.transport_poison");if(i.schema!=="crtr.execution-exit-diagnostic/v1"||!Number.isSafeInteger(s.consecutive_passes)||s.consecutive_passes<1||!Array.isArray(s.routes)||s.routes.length===0||!s.routes.every(p=>typeof p=="string"&&p!==""))throw n("exit_diagnostic is invalid")}else if(e.exit_diagnostic!==void 0)throw n("exit_diagnostic is valid only for exit-diagnostic turns");return e}o(U,"parseTurn");async function V(r){const e=r.params.id;await a(e);const t=U(r.body);await c(e,t.expected_execution_id);let i;switch(t.event){case"started":i=await h(t.expected_execution_id,{reason:"agent-start"});break;case"interrupted":i=await h(t.expected_execution_id,{reason:"prompt-unsettled"});break;case"progress":i=await j(t.expected_execution_id);break;case"closed":i=await P(t.expected_execution_id,{endReason:t.end_reason,viewerPresent:B(e)});break;case"exit-diagnostic":{const w=t.exit_diagnostic.transport_poison;i=await O(t.expected_execution_id,{consecutivePasses:w.consecutive_passes,routes:w.routes});break}}const s=(await l(e))?.link;return{status:200,body:{applied:i,fault_link:s==="daemon\u2192node"||s==="pi\u2192provider"?s:null}}}o(V,"handleTurn");function Y(r){const e=d(r,"provider retry");if(typeof e.expected_execution_id!="string"||e.expected_execution_id==="")throw n("expected_execution_id must be a non-empty string");if(!["record-pending","admit","reopen","invalidate","clear"].includes(e.op))throw n("provider retry op is invalid");if(typeof e.session_id!="string"||e.session_id==="")throw n("session_id must be a non-empty string");if(e.op==="record-pending"&&(e.input=_(e.input)),e.op==="admit"){if(typeof e.fault_id!="string"||e.fault_id==="")throw n("admit requires fault_id");e.retry=g(e.retry)}return e}o(Y,"parseProviderRetry");async function G(r){const e=r.params.id;await a(e);const t=Y(r.body);await c(e,t.expected_execution_id);let i;switch(t.op){case"record-pending":i=await N(e,{sessionId:t.session_id,input:y(t.input)})!==null;break;case"admit":i=await T(e,{sessionId:t.session_id,faultId:t.fault_id,retry:t.retry});break;case"reopen":i=await L(e,{sessionId:t.session_id});break;case"invalidate":i=await R(e,{sessionId:t.session_id});break;case"clear":i=await q(e,{sessionId:t.session_id});break}return{status:200,body:{applied:i,episode:(await x(e)).episode}}}o(G,"handleProviderRetry");function J(r){const e=d(r,"broker fault");if(typeof e.expected_execution_id!="string"||e.expected_execution_id==="")throw n("expected_execution_id must be a non-empty string");if(e.op!=="record"&&e.op!=="clear")throw n("fault op must be record or clear");if(e.op==="record"&&(e.input=_(e.input)),e.op==="clear"&&e.link!==void 0&&!f.has(e.link))throw n("fault link is invalid");if(e.preserve_episode!==void 0&&typeof e.preserve_episode!="boolean")throw n("preserve_episode must be boolean");return e}o(J,"parseBrokerFault");async function W(r){const e=r.params.id;await a(e);const t=J(r.body);await c(e,t.expected_execution_id);const i=t.op==="record"?await v(e,y(t.input)):(await m(e,{...t.link===void 0?{}:{link:t.link},...t.preserve_episode===void 0?{}:{preserveEpisode:t.preserve_episode}}),await l(e));return{status:200,body:{fault:i===null?null:u(i)}}}o(W,"handleBrokerFault");async function z(r){const e=r.params.id;return await a(e),await c(e,r.query.get("expected_execution_id")),{status:200,body:await x(e)}}o(z,"handleRecovery");async function H(r){const e=r.params.id;await a(e);const t=await v(e,y(_(r.body)));return{status:200,body:{fault:t===null?null:u(t)}}}o(H,"handleNodeFaultRecord");async function M(r){const e=r.params.id;await a(e);const t=r.query.get("link");if(t!==null&&!f.has(t))throw n("fault link is invalid");const i=r.query.get("preserve_episode");if(i!==null&&i!=="true"&&i!=="false")throw n("preserve_episode must be true or false");return{status:200,body:{cleared:await m(e,{...t===null?{}:{link:t},...i===null?{}:{preserveEpisode:i==="true"}})}}}o(M,"handleNodeFaultClear");const oe=b([{method:"POST",pattern:"/v1/broker/:id/turn",handler:V},{method:"POST",pattern:"/v1/broker/:id/provider-retry",handler:G},{method:"POST",pattern:"/v1/broker/:id/fault",handler:W},{method:"GET",pattern:"/v1/broker/:id/recovery",handler:z}]),se=b([{method:"POST",pattern:"/v1/nodes/:id/fault",handler:H},{method:"DELETE",pattern:"/v1/nodes/:id/fault",handler:M}]);export{oe as brokerRecoveryRoutes,se as nodeFaultRoutes,c as requireCurrentExecution};
|
|
@@ -9,10 +9,10 @@ export declare class BrokerSignalStreams {
|
|
|
9
9
|
pingMs: number;
|
|
10
10
|
blockedMs: number;
|
|
11
11
|
});
|
|
12
|
-
open(nodeId: string, res: ServerResponse, hello: BrokerSignalLineDTO, req: RequestContext['req']): void
|
|
12
|
+
open(nodeId: string, res: ServerResponse, hello: BrokerSignalLineDTO, req: RequestContext['req']): Promise<void>;
|
|
13
13
|
/** Hint the node's broker to re-run its retry scheduling. False when no
|
|
14
14
|
* broker stream is open (it resyncs on reconnect instead). */
|
|
15
|
-
nudgeFaultRetry(nodeId: string): boolean
|
|
15
|
+
nudgeFaultRetry(nodeId: string): Promise<boolean>;
|
|
16
16
|
close(): void;
|
|
17
17
|
}
|
|
18
18
|
export declare const brokerSignalStreams: BrokerSignalStreams;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var D=Object.defineProperty;var r=(
|
|
2
|
-
`)||(
|
|
1
|
+
var D=Object.defineProperty;var r=(c,e)=>D(c,"name",{value:e,configurable:!0});import{ApiError as M}from"../../../api/errors.js";import{getNode as y}from"../../../core/canvas/canvas.js";import{brokerSignalBus as E}from"../../broker-signals/bus.js";import{boundDaemonControl as T}from"../../control.js";import{requireCurrentExecution as v}from"./broker-recovery.js";import{extensionNode as _}from"./broker-ops.js";const R=15e3,C=3e4;class N{static{r(this,"BrokerSignalStreams")}timing;streams=new Map;constructor(e={pingMs:R,blockedMs:C}){this.timing=e}async open(e,t,u,d){this.streams.get(e)?.close();let n=!1,i=!1,h=!1,w=!1,g=!1,s,m,b;const a=r((o=!1)=>{n||(n=!0,m!==void 0&&clearInterval(m),s!==void 0&&clearTimeout(s),t.off("drain",k),t.off("close",l),t.off("error",l),d.off("aborted",l),b?.(),this.streams.get(e)===S&&this.streams.delete(e),o?t.destroy():t.writableEnded||t.end())},"close"),f=r(o=>{n||i||t.write(`${JSON.stringify(o)}
|
|
2
|
+
`)||(i=!0,s=setTimeout(()=>a(!0),this.timing.blockedMs),s.unref())},"send"),p=r(async()=>{if(!(n||i)&&(h&&(h=!1,f({type:"mail",channel:"wake",at:Date.now()})),g&&!i&&(g=!1,f({type:"fault-retry",at:Date.now()})),w&&!i)){w=!1;const o=await y(e);o!==null&&f({type:"node",node:await _(o),at:Date.now()})}},"flush"),k=r(()=>{i=!1,s!==void 0&&clearTimeout(s),s=void 0,p().catch(()=>a())},"drain"),l=r(()=>a(),"onClosed"),S={close:a,nudgeFaultRetry:r(async()=>{if(!n){g=!0;try{await p()}catch{a()}}},"nudgeFaultRetry")};this.streams.set(e,S),t.on("drain",k),t.once("close",l),t.once("error",l),b=await E.subscribe((o,x)=>{o!==e||n||(x==="mail"?h=!0:w=!0,p().catch(()=>a()))}),m=setInterval(()=>{if(!(i||n))try{f({type:"ping",at:Date.now()})}catch{a()}},this.timing.pingMs),m.unref(),d.once("aborted",l);try{f(u),await p()}catch{a()}}async nudgeFaultRetry(e){const t=this.streams.get(e);return t===void 0?!1:(await t.nudgeFaultRetry(),!0)}close(){for(const e of[...this.streams.values()])e.close()}}const B=new N;async function F(c){const e=c.params.id??"",t=await y(e);if(t===null)throw new M(404,"node_not_found",`no node ${e}`);const u=c.query.get("execution_id");await v(e,u);const{req:d,res:n}=c;n.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});try{await B.open(e,n,{type:"hello",epoch:T()?.epoch??"",execution_id:u,node:await _(await y(e)??t),at:Date.now()},d)}catch{n.writableEnded||n.end()}return{status:200}}r(F,"handleSignals");const J=[{method:"GET",pattern:"/v1/nodes/:id/broker/signals",handler:F}];export{N as BrokerSignalStreams,J as brokerSignalRoutes,B as brokerSignalStreams};
|
|
@@ -3,5 +3,5 @@ import { type HandlerResult, type RequestContext, type RouteTable } from '../rou
|
|
|
3
3
|
* application/gzip, not HTTP content-encoding: the local socket fetch returns a
|
|
4
4
|
* byte stream without automatic decompression. Build from selected columns so
|
|
5
5
|
* the daemon does not materialize or serialize outcome/activity/placement. */
|
|
6
|
-
export declare function handleBrowse(ctx: RequestContext): HandlerResult
|
|
6
|
+
export declare function handleBrowse(ctx: RequestContext): Promise<HandlerResult>;
|
|
7
7
|
export declare const canvasRoutes: RouteTable;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);if(e.length>0){const c=
|
|
3
|
-
`).forEach((u,g)=>{
|
|
1
|
+
var X=Object.defineProperty;var l=(t,e)=>X(t,"name",{value:e,configurable:!0});import{gzipSync as Z}from"node:zlib";import{browseNodes as F,graphNodes as ee,listNodes as G,pruneNodes as te,pruneToLimit as ne,rosterEdges as S,rosterNodes as se}from"../../../core/canvas/canvas.js";import{liveObjectWaitsNamed as oe,readControllerWait as re}from"../../../core/canvas/waits.js";import{activeBackgroundBashJobs as ae}from"../../../core/bash-jobs.js";import{contextDir as ie}from"../../../core/canvas/node-agent-paths.js";import{nowIso as I}from"../../../core/fs-utils.js";import{isPidPresent as de}from"../../../core/canvas/pid.js";import{dashboardRowsAllFromSource as le,enrichRowsFromSource as ce}from"../../../core/canvas/render-source.js";import{localCanvasSource as D}from"../../../core/canvas/source.js";import{ticketCountsForNodes as q,ticketsAcrossCanvas as ue}from"../../../core/canvas/attention.js";import{buildCorpus as fe,groupCorpus as pe,resolveRef as me}from"../../../core/canvas/history.js";import{listFocuses as H,reapEmptyNodes as _e}from"../../../core/runtime/placement.js";import{boundFleet as ye}from"../../../core/runtime/fleet.js";import{retentionHold as he}from"../../reconcilers/live-obligation.js";import{notFound as be,usage as _}from"../../../core/errors.js";import{openDb as ge}from"../../../core/canvas/db.js";import{view as ve}from"../../../core/canvas/tree.js";import{isLiveStatus as we}from"../../../core/canvas/node-order.js";import{readNodeRecap as ke}from"../../../core/canvas/node-recap.js";import{readGoal as Se}from"../../../core/runtime/kickoff.js";import{faultSummary as Ne}from"../../../core/canvas/status-glyph.js";import{listPendingAsks as Re}from"../../../core/human/requests.js";import{toGraphNodeDTO as Ce}from"../map.js";import{actsAsPerson as je,canReadNode as A,canReadRun as Ie}from"../router.js";import{ApiError as T}from"../../../api/errors.js";import{filterAsync as $,mapAsync as x}from"../../../core/async-array.js";async function N(t){return t.principal.class==="person"?null:new Set((await $(await G(),async e=>await A(t.principal,e.grantee??"app:terminal",e.node_id))).map(e=>e.node_id))}l(N,"visibleNodes");async function z(t){return t.principal.class==="person"?null:new Set((await $(await G(),async e=>e.run_id?await Ie(t.principal,e.grantee??"app:terminal",e.node_id):await A(t.principal,e.grantee??"app:terminal",e.node_id))).map(e=>e.node_id))}l(z,"visibleHistoryNodes");async function Me(t){const e=await N(t);return{status:200,body:{items:(await ue()).filter(n=>e===null||e.has(n.node_id)).map(n=>({node_id:n.node_id,name:n.name,cwd:n.cwd,count:n.count,subjects:n.subjects}))}}}l(Me,"handleAttention");async function Le(t){const e=t.body;if(e===null||typeof e!="object"||!Array.isArray(e.node_ids))throw _("attention count request requires node_ids: string[]");const r=e.node_ids;if(!r.every(o=>typeof o=="string"))throw _("attention count request node_ids must contain only strings");const n=await N(t);return{status:200,body:{counts:await q(r.filter(o=>n===null||n.has(o)))}}}l(Le,"handleAttentionCounts");function J(t){return Buffer.from(String(t),"utf8").toString("base64")}l(J,"encodeCursor");function K(t){const e=Number(Buffer.from(t,"base64").toString("utf8"));if(!Number.isInteger(e)||e<0)throw _(`invalid cursor: ${t}`);return e}l(K,"decodeCursor");function Oe(t,e,r){const i=t.loadBody().split(`
|
|
2
|
+
`);if(e.length>0){const c=i.findIndex(p=>{const f=p.toLowerCase();return e.some(y=>f.includes(y))});if(c!==-1)return i.slice(c,c+r).map(p=>p.trim()).filter(p=>p!=="").join(" \u23CE ")}const o=i.map(c=>c.trim()).filter(c=>c!=="").slice(0,r).join(" \u23CE ");return o!==""?o:t.title}l(Oe,"snippet");function Ee(t,e,r){const n=[...t];return e==="relevance"&&r!==void 0?n.sort((i,o)=>(r.get(o.ref)??0)-(r.get(i.ref)??0)||o.tsMs-i.tsMs||i.ref.localeCompare(o.ref)):e==="oldest"?n.sort((i,o)=>i.tsMs-o.tsMs||i.ref.localeCompare(o.ref)):n.sort((i,o)=>o.tsMs-i.tsMs||i.ref.localeCompare(o.ref)),n}l(Ee,"sortArtifacts");function Ae(t){if(t==null)return{};if(typeof t!="object")throw _("history search body must be a JSON object");return t}l(Ae,"parseSearchBody");function Te(t){if(t===null||typeof t!="object")throw _("history grep body must be a JSON object");const e=t;if(typeof e.pattern!="string"||e.pattern==="")throw _("history grep body requires a non-empty pattern");return e}l(Te,"parseGrepBody");async function B(t,e){const r={cwd:t.cwd,allCwds:t.all_cwds===!0,under:t.under,nodes:t.nodes},n={types:t.types,kinds:t.kinds,statuses:t.statuses,sinceMs:t.since_ms,untilMs:t.until_ms,origins:t.origins,roles:t.roles,from:t.from},i=await z(e);return(await fe(r,n)).filter(o=>i===null||i.has(o.nodeId))}l(B,"buildCorpusFromQuery");function $e(t){if(t==null)return{};if(typeof t!="object")throw _("history stats body must be a JSON object");return t}l($e,"parseStatsBody");const W=["origin","node","kind","day","type","role"];async function Be(t){const e=$e(t.body),r=e.group_by??"type";if(!W.includes(r))throw _(`--group-by must be one of: ${W.join(", ")}; received: ${String(e.group_by)}`);const n=await B(e,t),i=pe(n,r);return{status:200,body:{group_by:r,groups:i,total:i.reduce((c,p)=>c+p.count,0),scanned:n.length}}}l(Be,"handleHistoryStats");async function Pe(t){const e=Te(t.body),r=Math.min(100,Math.max(1,e.limit??20)),n=await B(e,t),i=e.cursor!==void 0?K(e.cursor):0;let o;try{o=new RegExp(e.pattern,"i")}catch{throw _(`invalid regex pattern: ${e.pattern}`)}const c=[];for(const a of n)a.loadBody().split(`
|
|
3
|
+
`).forEach((u,g)=>{o.test(u)&&c.push({ref:a.ref,node:`${a.nodeName} (${a.nodeId})`,ts:a.ts,line:g+1,text:u.trim()})});c.sort((a,s)=>a.ref.localeCompare(s.ref)||a.line-s.line);const p=c.slice(i,i+r),f=i+r<c.length?J(i+r):null;return{status:200,body:{hits:p,next_cursor:f,total:c.length}}}l(Pe,"handleHistoryGrep");async function Fe(t){const e=Ae(t.body),r=(e.query??"").trim(),n=e.weigh_body===!0,i=e.full===!0,o=Math.max(1,e.snippet_lines??1),c=Math.min(100,Math.max(1,e.limit??20)),p=e.per_node===!0;if(p&&(e.nodes===void 0||e.nodes.length===0))throw new T(400,"invalid_request","`per_node` requires a non-empty `nodes` list",{param:"nodes"});const f=await B(e,t),y=e.cursor!==void 0?K(e.cursor):0,a=r.toLowerCase().split(/\s+/).filter(d=>d.length>0);let s=f,u;const g=e.sort??(a.length>0?"relevance":"recency");if(a.length>0&&g==="relevance"){u=new Map;const d=[];for(const m of f){const E=m.title.toLowerCase(),Y=m.nodeName.toLowerCase(),V=m.nodeDesc.toLowerCase(),P=n?m.loadBody().toLowerCase():null;let k=0;for(const j of a)E.includes(j)&&(k+=10),Y.includes(j)&&(k+=5),V.includes(j)&&(k+=3),P!==null&&P.includes(j)&&(k+=1);k>0&&(u.set(m.ref,k),d.push(m))}s=d}else a.length>0&&(s=f.filter(d=>{const m=`${d.title}
|
|
4
4
|
${d.nodeName}
|
|
5
5
|
${d.nodeDesc}${n?`
|
|
6
|
-
`+d.loadBody():""}`.toLowerCase();return
|
|
6
|
+
`+d.loadBody():""}`.toLowerCase();return a.some(E=>m.includes(E))}));let b=Ee(s,g,u);if(p){const d=new Set;b=b.filter(m=>!d.has(m.nodeId)&&d.add(m.nodeId))}const v=p?b:b.slice(y,y+c),h=!p&&y+c<b.length?J(y+c):null;return{status:200,body:{hits:v.map(d=>{const m={ref:d.ref,node:`${d.nodeName} (${d.nodeId})`,kind:d.nodeKind,source:d.source,ts:d.ts,...p?{node_id:d.nodeId}:{}};return g==="relevance"&&u!==void 0&&(m.score=u.get(d.ref)??0),i?m.body=d.loadBody():m.snippet=Oe(d,a,o),m}),next_cursor:h,total:b.length}}}l(Fe,"handleHistorySearch");async function Ge(t){const e=(t.query.get("ref")??"").trim();if(!e.includes(":"))throw _(`ref must be <node-id>:inbox/<n>, <node-id>:session, or <node-id>:session/<n>; received: ${e}`,{received:e,next:"Get a valid ref from `crtr canvas history search`. Reports and documents are `crtr canvas read <name>`."});const r=await me(e);if(r===null)throw be(`no inbox entry or message for ref: ${e}`,{ref:e,next:"Re-run `crtr canvas history search` for a current ref. Reports and documents are `crtr canvas read <name>`."});if((await z(t))?.has(r.nodeId)===!1)throw new T(404,"not_found","artifact not found");const n=r.source,o=t.query.get("format")==="raw"&&r.raw!==null?r.raw:r.body;return{status:200,body:{ref:e,node:`${r.nodeName} (${r.nodeId})`,source:n,ts:r.ts,content:o}}}l(Ge,"handleHistoryRead");function De(t){for(const[n]of t.query)if(n!=="live")throw _(`unknown snapshot query parameter: ${n}`);const e=t.query.getAll("live");if(e.length>1)throw _("live must appear at most once");const r=e[0];if(r===void 0||r==="false"||r==="0")return!1;if(r==="true"||r==="1")return!0;throw _("live must be true or false")}l(De,"snapshotLiveOnly");async function qe(t){const e=new Set((await H()).map(a=>a.node_id)),r=await N(t),n=(await le(D,e,De(t))).filter(a=>r===null||r.has(a.node_id)),i=await q(n.map(a=>a.node_id));await ce(D,n,i);const o=await x(n,async a=>{const s=a.srcRow,u=s?.host_kind??"tmux";return{node_id:a.node_id,name:a.name,title:a.handle??a.name,description:a.description??null,kind:a.kind,mode:a.mode,lifecycle:a.lifecycle??s?.lifecycle,status:a.status,cwd:a.cwd,profile_id:a.profile_id??null,parent:s?.parent??null,created:a.created,host_kind:u,enterable:u==="broker",attention_count:a.asks,...s?.cycles!=null?{cycles:s.cycles}:{},...a.mtimeMs!==void 0?{last_activity:new Date(a.mtimeMs).toISOString()}:{},ctx_tokens:a.ctx_tokens,streaming:a.streaming??!1,jobs_active:s!==void 0&&de(s.pi_pid)?ae(await ie(a.node_id)).length:0,waiting_for:(await re(a.node_id))?.controllerId??null,hanging:a.hanging??null,viewed:a.viewed??!1,final_report:s?.final_report??null,finalized_at:s?.finalized_at??null}}),c=new Map;for(const a of await S()){const s=c.get(a.from_id);s===void 0?c.set(a.from_id,[a.to_id]):s.push(a.to_id)}const p=new Set(n.map(a=>a.node_id)),f=Object.fromEntries(n.map(a=>[a.node_id,(c.get(a.node_id)??[]).filter(s=>p.has(s))]));return{status:200,body:{generated_at:I(),nodes:o,subscriptions:f}}}l(qe,"handleSnapshot");async function U(){const t=(await se()).map(n=>{const i=n.host_kind??"tmux";return{node_id:n.node_id,name:n.name,kind:n.kind,mode:n.mode,lifecycle:n.lifecycle,status:n.status,cwd:n.cwd,host_kind:i,enterable:i==="broker",parent:n.parent,created:n.created}}),e=(await S()).map(n=>({from_id:n.from_id,to_id:n.to_id,active:n.active,created:n.created})),r=(await oe()).map(n=>({node_id:n.nodeId,object_id:n.objectId,object_type:n.objectType,object_name:n.objectName,created:new Date(n.createdAt).toISOString()}));return{generated_at:I(),nodes:t,edges:e,object_waits:r}}l(U,"buildRoster");let R=null,M=null;function He(){return R===null?(R=Promise.resolve().then(async()=>await U()).finally(()=>{R=null}),R):(M===null&&(M=R.then(async()=>await U()).finally(()=>{M=null})),M)}l(He,"rosterCoalesced");async function xe(t){const e=await He(),r=await N(t);return r===null?{status:200,body:e}:{status:200,body:{...e,nodes:e.nodes.filter(n=>r.has(n.node_id)),edges:e.edges.filter(n=>r.has(n.from_id)&&r.has(n.to_id)),object_waits:(e.object_waits??[]).filter(n=>r.has(n.node_id))}}}l(xe,"handleRoster");function Q(t){if(t.name!==""&&t.name!==t.kind)return t.name;const e=(t.description??"").trim();return e!==""?e:t.name}l(Q,"liveRootName");const ze=1440*6e4;async function Je(){const t=await F(),e=new Map(t.map(s=>[s.node_id,s])),r=new Map((await(await ge()).prepare("SELECT node_id, reply_at, read_at, intent FROM nodes WHERE parent IS NULL").all()).map(s=>[s.node_id,s])),n=await Re(),i=new Map;for(const s of n)i.set(s.requester_node_id,(i.get(s.requester_node_id)??0)+1);const o=new Date(Date.now()-ze).toISOString(),c=l(s=>{const u=r.get(s.node_id);return u?.reply_at!=null&&(u.read_at==null||u.reply_at>u.read_at)||(i.get(s.node_id)??0)>0?!0:s.status!=="done"||u?.intent!=="parked"?!1:[s.created,s.telemetry_updated_at,u.reply_at].reduce((v,h)=>h!=null&&h>v?h:v,"")>=o},"keepFinished"),p=t.filter(s=>s.parent===null&&s.kind!=="human"&&(we(s.status)||c(s))),f=new Map;for(const s of await S())f.set(s.from_id,[...f.get(s.from_id)??[],s.to_id]);const y=l(s=>{const u=e.get(s)?.fault;return u&&u.link!=="broker\u2194crtrd"?Ne(u):null},"faultOf"),a=await x(p,async s=>{const u=[s.node_id,...await ve(s.node_id)].filter(d=>e.get(d)?.kind!=="human"&&e.has(d)),g=new Set(u),b=n.filter(d=>g.has(d.requester_node_id)),v=r.get(s.node_id),h=v?.reply_at??null,O=v?.read_at??null;let w=s.created;for(const d of u){const m=e.get(d).telemetry_updated_at;m!=null&&m>w&&(w=m)}return h!==null&&h>w&&(w=h),{node_id:s.node_id,name:Q(s),cwd:s.cwd,profile_id:s.profile_id,status:s.status,state_line:(()=>{const d=ke(s.node_id)?.state.trim();return d||null})(),goal:(await Se(s.node_id))?.trim()||null,asks:b.length,first_ask_ticket_id:b[0]?.inbox_ticket_id??null,fault:u.map(y).find(d=>d!==null)??null,running_count:u.filter(d=>e.get(d).streaming===!0).length,unread:h!==null&&(O===null||h>O),last_activity:w,children:(f.get(s.node_id)??[]).filter(d=>e.has(d)&&e.get(d).kind!=="human").map(d=>{const m=e.get(d);return{node_id:d,name:Q(m),status:m.status,streaming:m.streaming===!0,asks:i.get(d)??0,fault:y(d)}})}});return{generated_at:I(),rows:a}}l(Je,"buildLiveRoots");let C=null,L=null;function Ke(){const t=l(()=>Promise.resolve().then(Je),"run");return C===null?(C=t().finally(()=>{C=null}),C):(L===null&&(L=C.then(t).finally(()=>{L=null})),L)}l(Ke,"liveRootsCoalesced");async function We(t){if(!je(t.principal))throw new T(403,"permission_error","only the person reads the dashboard");const e=await Ke(),r=t.query.get("profile");return{status:200,body:r===null?e:{...e,rows:e.rows.filter(n=>n.profile_id===r)}}}l(We,"handleLiveRoots");async function Ue(t){const e=(await $(await F(),async o=>t.principal.class==="person"||await A(t.principal,o.grantee??"app:terminal",o.node_id))).map(o=>({node_id:o.node_id,name:o.name,description:o.description,kind:o.kind,mode:o.mode,lifecycle:o.lifecycle,status:o.status,cwd:o.cwd,profile_id:o.profile_id,grantee:o.grantee??"app:terminal",parent:o.parent,created:o.created,frozen_at:o.frozen_at??null,terminal_reason:o.terminal_reason??null,final_report:o.final_report??null,telemetry_tokens_in:o.telemetry_tokens_in??null,telemetry_updated_at:o.telemetry_updated_at??null,fault:o.fault&&o.fault.link!=="broker\u2194crtrd"?{...o.fault,link:o.fault.link}:null,streaming:o.streaming??!1})),r=new Set(e.map(o=>o.node_id)),n=(await S()).filter(o=>r.has(o.from_id)&&r.has(o.to_id));return{status:200,rawBody:Z(JSON.stringify({nodes:e,edges:n}),{level:1}),headers:{"content-type":"application/gzip"}}}l(Ue,"handleBrowse");async function Qe(t){const e=await N(t);return{status:200,body:{generated_at:I(),nodes:(await ee()).filter(n=>e===null||e.has(n.node_id)).map(Ce),edges:(await S()).filter(n=>e===null||e.has(n.from_id)&&e.has(n.to_id)).map(n=>({from_id:n.from_id,to_id:n.to_id,active:n.active,created:n.created})),focused_node_ids:(await H()).map(n=>n.node_id).filter(n=>e===null||e.has(n))}}}l(Qe,"handleGraph");function Ye(t){if(t==null)return{};if(typeof t!="object")throw _("prune body must be a JSON object");const e=t,r=l(a=>{const s=e[a];if(s!==void 0){if(typeof s!="number"||!Number.isFinite(s))throw _(`${a} must be a number`);return s}},"num"),n=l(a=>{const s=e[a];if(s!==void 0){if(typeof s!="boolean")throw _(`${a} must be a boolean`);return s}},"bool"),i={},o=r("limit");o!==void 0&&(i.limit=o);const c=r("ttl_days");c!==void 0&&(i.ttl_days=c);const p=n("include_stale");p!==void 0&&(i.include_stale=p);const f=n("empty");f!==void 0&&(i.empty=f);const y=n("dry_run");return y!==void 0&&(i.dry_run=y),i}l(Ye,"parsePruneBody");async function Ve(t){const e=Ye(t.body),r=e.ttl_days??14,n=e.dry_run??!1,i=await he(ye());let o;return e.limit!==void 0?o=(await ne({maxNodes:e.limit,held:i,dryRun:n})).pruned.map(f=>({node_id:f.node_id,status:f.status,created:f.created})):e.empty===!0?o=(await _e({dryRun:n})).map(f=>({node_id:f,status:"empty",created:""})):o=(await te({ttlDays:r,held:i,dryRun:n,includeStale:e.include_stale??!1})).pruned.map(f=>({node_id:f.node_id,status:f.status,created:f.created})),{status:200,body:{pruned:o,dry_run:n,ttl_days:r}}}l(Ve,"handlePrune");const Rt=[{method:"GET",pattern:"/v1/canvas/attention",handler:Me},{method:"POST",pattern:"/v1/canvas/attention/counts",handler:Le},{method:"POST",pattern:"/v1/canvas/history/search",handler:Fe},{method:"POST",pattern:"/v1/canvas/history/grep",handler:Pe},{method:"GET",pattern:"/v1/canvas/history/read",handler:Ge},{method:"POST",pattern:"/v1/canvas/history/stats",handler:Be},{method:"GET",pattern:"/v1/canvas/snapshot",handler:qe},{method:"GET",pattern:"/v1/canvas/roster",handler:xe},{method:"GET",pattern:"/v1/canvas/live-roots",handler:We},{method:"GET",pattern:"/v1/canvas/browse",handler:Ue},{method:"GET",pattern:"/v1/canvas/graph",handler:Qe},{method:"POST",pattern:"/v1/canvas/prune",ownerOnly:!0,handler:Ve}];export{Rt as canvasRoutes,Ue as handleBrowse};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var n=Object.defineProperty;var e=(t,o)=>n(t,"name",{value:o,configurable:!0});import{getNode as r}from"../../../core/canvas/canvas.js";import{isSafeNodeId as d}from"../../../core/canvas/paths.js";import{notFound as i,usage as a}from"../../../core/errors.js";import{readChatInventory as m}from"../../../core/runtime/broker-inventory.js";async function s(t){const o=t.params.id;if(!d(o))throw a(`invalid node id: ${o}`,{received:o});if(r(o)===null)throw i(`unknown node: ${o}`,{received:o});return{status:200,body:await m(o)}}e(s,"handleGet");const v=[{method:"GET",pattern:"/v1/nodes/:id/chat-inventory",handler:s}];export{v as chatInventoryRoutes};
|
|
1
|
+
var n=Object.defineProperty;var e=(t,o)=>n(t,"name",{value:o,configurable:!0});import{getNode as r}from"../../../core/canvas/canvas.js";import{isSafeNodeId as d}from"../../../core/canvas/paths.js";import{notFound as i,usage as a}from"../../../core/errors.js";import{readChatInventory as m}from"../../../core/runtime/broker-inventory.js";async function s(t){const o=t.params.id;if(!d(o))throw a(`invalid node id: ${o}`,{received:o});if(await r(o)===null)throw i(`unknown node: ${o}`,{received:o});return{status:200,body:await m(o)}}e(s,"handleGet");const v=[{method:"GET",pattern:"/v1/nodes/:id/chat-inventory",handler:s}];export{v as chatInventoryRoutes};
|