@north-light/cli 0.3.531 → 0.3.533
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +6 -3
- package/dist/api/client.js +1 -1
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/canvas.d.ts +2 -0
- package/dist/api/dto/crons.d.ts +2 -0
- package/dist/builtin-memory/crouter-sdk/release-notes.md +8 -0
- package/dist/builtin-memory/northlight-apps/providers/README.md +2 -0
- package/dist/builtin-memory/northlight-apps/providers/sms.md +2 -0
- package/dist/clients/attach/chrome/inbox-strip.d.ts +6 -1
- package/dist/clients/attach/chrome/inbox-strip.js +1 -1
- package/dist/clients/attach/chrome/roster.js +1 -1
- package/dist/clients/attach/session/chrome-refresh.d.ts +12 -3
- package/dist/clients/attach/session/chrome-refresh.js +1 -1
- package/dist/clients/attach/session/document-links.js +1 -1
- package/dist/clients/attach/viewer.js +586 -587
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/node/inspect.js +6 -6
- package/dist/commands/sys/context/expose.js +2 -2
- package/dist/commands/sys/db.d.ts +1 -0
- package/dist/commands/sys/db.js +1 -0
- package/dist/commands/sys.js +1 -1
- package/dist/core/bash-guard.js +9 -3
- package/dist/core/canvas/canvas.d.ts +12 -2
- package/dist/core/canvas/canvas.js +23 -20
- package/dist/core/canvas/daemon-actions.d.ts +0 -3
- package/dist/core/canvas/daemon-actions.js +7 -24
- package/dist/core/canvas/daemon-owner.d.ts +3 -0
- package/dist/core/canvas/daemon-owner.js +1 -6
- package/dist/core/canvas/db.d.ts +28 -20
- package/dist/core/canvas/db.js +4 -3
- package/dist/core/canvas/deliveries.d.ts +5 -0
- package/dist/core/canvas/deliveries.js +25 -30
- package/dist/core/canvas/export-sqlite.d.ts +14 -0
- package/dist/core/canvas/export-sqlite.js +3 -0
- package/dist/core/canvas/import-sqlite.d.ts +44 -0
- package/dist/core/canvas/import-sqlite.js +7 -0
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/outcome-actions.js +4 -4
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/schema-pg.sql +1022 -0
- package/dist/core/canvas/schema-version.d.ts +4 -0
- package/dist/core/canvas/schema-version.js +1 -0
- package/dist/core/canvas/sessions.js +3 -3
- package/dist/core/canvas/structured-requests.js +2 -2
- package/dist/core/canvas/tree.js +6 -6
- package/dist/core/canvas/waits.js +1 -1
- package/dist/core/feed/inbox.js +1 -1
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/feed/reports.js +2 -2
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/graph/access.js +7 -7
- package/dist/core/graph/custom.js +10 -10
- package/dist/core/graph/deletion.js +6 -6
- package/dist/core/graph/documents.d.ts +1 -1
- package/dist/core/graph/documents.js +9 -9
- package/dist/core/graph/edges.d.ts +3 -3
- package/dist/core/graph/edges.js +3 -1
- package/dist/core/graph/events.js +7 -7
- package/dist/core/graph/exposures.d.ts +8 -8
- package/dist/core/graph/jobs.d.ts +1 -1
- package/dist/core/graph/jobs.js +2 -2
- package/dist/core/graph/kinds/custom.js +1 -1
- package/dist/core/graph/kinds/document.js +4 -4
- 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 +2 -2
- package/dist/core/graph/kinds/kind.js +1 -1
- package/dist/core/graph/kinds/live-read.d.ts +5 -0
- package/dist/core/graph/kinds/live-read.js +1 -0
- package/dist/core/graph/kinds/node.js +5 -5
- package/dist/core/graph/kinds/owner.js +2 -2
- package/dist/core/graph/names.js +3 -3
- package/dist/core/graph/objects.d.ts +5 -5
- package/dist/core/graph/objects.js +10 -10
- package/dist/core/graph/package-docs.js +6 -5
- package/dist/core/graph/reader.d.ts +1 -1
- package/dist/core/graph/reader.js +2 -2
- package/dist/core/graph/receivers.js +4 -5
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/repo-sync/repos.js +3 -3
- package/dist/core/graph/repo-sync/sync.js +1 -1
- package/dist/core/graph/rules.d.ts +3 -4
- 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 +1 -1
- package/dist/core/graph/spaces/index.js +1 -1
- 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/types.d.ts +4 -3
- package/dist/core/graph/watches.d.ts +2 -2
- package/dist/core/graph/watches.js +17 -17
- package/dist/core/human/page-schema.js +5 -4
- package/dist/core/human/requests.d.ts +1 -1
- package/dist/core/human/requests.js +20 -23
- package/dist/core/llm/run.js +2 -2
- package/dist/core/peer/home.d.ts +6 -0
- package/dist/core/peer/home.js +2 -2
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/receiver.js +1 -1
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/providers/receipts.js +3 -2
- package/dist/core/review/comments.js +5 -4
- package/dist/core/runs/activity.js +4 -5
- package/dist/core/runs/confinement.d.ts +1 -1
- package/dist/core/runs/confinement.js +2 -2
- package/dist/core/runs/events.d.ts +1 -1
- package/dist/core/runs/events.js +5 -5
- package/dist/core/runs/operations.js +6 -4
- package/dist/core/runtime/close.d.ts +3 -0
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/host.d.ts +5 -1
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/launch.js +2 -2
- package/dist/core/runtime/ledger.js +3 -3
- package/dist/core/runtime/lifecycle.d.ts +9 -0
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/nodes.d.ts +1 -1
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/spaces/stop.d.ts +1 -0
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/statements.d.ts +17 -0
- package/dist/core/statements.js +2 -0
- package/dist/core/substrate/delivery/corpus.js +3 -3
- package/dist/core/substrate/delivery/deliver.js +5 -5
- package/dist/core/substrate/delivery/listings.js +1 -1
- package/dist/core/substrate/delivery/match.d.ts +2 -2
- package/dist/core/substrate/delivery/match.js +1 -1
- package/dist/core/substrate/delivery/plan.js +3 -3
- package/dist/core/substrate/delivery/render-boot.js +5 -5
- package/dist/core/substrate/delivery/render-event.js +6 -6
- package/dist/core/usage/ledger.js +8 -8
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/document-listener.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/custom-objects.js +3 -3
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/memory.js +7 -7
- package/dist/daemon/api/handlers/messages.js +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/reviews.js +1 -1
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/broker-signals/bus.d.ts +14 -6
- package/dist/daemon/broker-signals/bus.js +1 -10
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.js +12 -11
- package/dist/daemon/due.js +1 -1
- package/dist/daemon/export-sqlite-run.d.ts +1 -0
- package/dist/daemon/export-sqlite-run.js +4 -0
- package/dist/daemon/fleet.d.ts +1 -0
- package/dist/daemon/fleet.js +3 -3
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/manage.d.ts +10 -0
- package/dist/daemon/manage.js +3 -2
- package/dist/daemon/peer/forward.d.ts +7 -0
- package/dist/daemon/peer/forward.js +1 -1
- package/dist/daemon/postgres/binary.d.ts +17 -0
- package/dist/daemon/postgres/binary.js +2 -0
- package/dist/daemon/postgres/cluster.d.ts +37 -0
- package/dist/daemon/postgres/cluster.js +6 -0
- package/dist/daemon/postgres/index.d.ts +2 -0
- package/dist/daemon/postgres/index.js +1 -0
- package/dist/daemon/postgres/pins.d.ts +7 -0
- package/dist/daemon/postgres/pins.js +1 -0
- package/dist/daemon/postgres/supervisor.d.ts +95 -0
- package/dist/daemon/postgres/supervisor.js +2 -0
- package/dist/daemon/reconcilers/bash-deadline.js +2 -2
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +7 -3
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +0 -6
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -8
- package/dist/daemon/runs/observer.js +5 -4
- package/dist/migrations/004-canvas-documents/index.js +1 -1
- package/dist/pi-extensions/canvas-doc-substrate.d.ts +2 -0
- package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
- package/dist/pi-extensions/envelope-merge.d.ts +3 -2
- package/dist/pi-extensions/envelope-merge.js +9 -8
- package/dist/shared/env.d.ts +3 -0
- package/dist/shared/env.js +2 -2
- package/docs/apps/providers/README.md +2 -0
- package/docs/apps/providers/sms.md +2 -0
- package/docs/public-api.md +11 -2
- package/docs/sdk/release-notes.md +8 -0
- package/package.json +6 -6
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -26
- package/scripts/install-runtime.mjs +53 -3
- package/scripts/lib/isolation-env.mjs +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var Ie=Object.defineProperty;var s=(e,t)=>Ie(e,"name",{value:t,configurable:!0});import{envProfileId as Ae}from"../../../shared/env.js";import{pausedCanvasProfiles as $e}from"../../../core/profiles/manifest.js";import{existsSync as N,realpathSync as q,statSync as ee}from"node:fs";import{isAbsolute as F,resolve as T}from"node:path";import{appendSituationalContext as Ce,formatSituationalProse as Ne}from"../../../core/runtime/situational-context.js";import{closeNode as Te}from"../../../core/runtime/close.js";import{reviveNode as Ee}from"../../../core/runtime/revive.js";import{nowIso as B}from"../../../core/fs-utils.js";import{appPaidLaunch as Pe,assertLaunchModelRegistered as K,forkNode as De,resolveForkSource as Le,spawnChildPrepared as Me}from"../../../core/runtime/spawn.js";import{forkSourceNode as je,newNodeId as ne}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as te,childrenOf as Ge,completeCreateRequest as ie,findCreateRequest as Fe,getNode as R,recordCreateRequestNode as Be,reserveCreateRequest as oe,reserveCreateRequestNode as Ke,listNodes as re,recordRespawnAttempt as We,subscribersOf as Ve,subscriptionsOf as ae,updateNode as C}from"../../../core/canvas/canvas.js";import{armControllerWait as xe}from"../../../core/canvas/waits.js";import{subtreeIds as ze}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as W}from"../../../core/canvas/db.js";import{markNodeRead as Je}from"../../../core/canvas/recovery.js";import{nodeObject as Ue}from"../../../core/graph/objects.js";import{recordActedOn as Ye}from"../../../core/graph/edges.js";import{publish as He}from"../../../core/graph/events.js";import{readerFor as Qe}from"../reader.js";import{relocateSessionCwd as Xe,unbindSession as Ze}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as qe}from"../../../core/canvas/attention.js";import{isSafeNodeId as en}from"../../../core/canvas/paths.js";import{contextDir as de,nodeAgentDir as V}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as nn}from"../../cron/authority.js";import{cronBirthPlacement as tn}from"../../cron/armed-context.js";import{existsBeneath as on,isAbsentOrRefused as rn,isBeneathRefusal as an,readdirBeneath as dn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as sn,readNodeSession as ln,readNodeSnapshot as cn,transcriptMarkdown as fn}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as un}from"../../../core/substrate/subject.js";import{reviveAll as pn}from"../../../core/runtime/revive-all.js";import{promoteAsync as mn,requestYieldAsync as wn,reshapeNodeAsync as x}from"../../../core/runtime/promote.js";import{recycleNode as hn}from"../../../core/runtime/recycle.js";import{relaunchRoot as yn}from"../../../core/runtime/reset.js";import{assertReopenGate as _n}from"../../../core/runtime/reopen.js";import{writeYieldMessage as gn,readGoal as bn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as vn,hasRoadmap as kn}from"../../../core/runtime/roadmap.js";import{renameWindow as Sn}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as Rn,explicitModelIntent as On,normalizeModel as In,readMergedLaunchConfigAsync as se}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as An}from"../../../core/model-routes.js";import{persistDormantModel as $n,setModelLive as Cn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as le}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as Nn}from"../../../core/runtime/broker-request.js";import{boundFleet as E}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as Tn}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as En}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as ce}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as Pn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Dn}from"../../../core/human-actions.js";import{parseDurationMs as Ln}from"../../../core/wake.js";import{claimWarmNode as Mn,refillWarmPool as fe,resumeWarmClaim as jn,warmPoolEnabled as Gn}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as z,isLaunchKind as Fn,resolveLaunchTarget as Bn}from"../../../core/runtime/launch-target.js";import{fullName as Kn}from"../../../core/canvas/labels.js";import{reportsForNode as ue}from"./reports.js";import{requireUsableProfile as Wn}from"./profiles.js";import{assertProfileActive as Vn,loadExactProfileManifest as xn}from"../../../core/profiles/manifest.js";import{getCron as pe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as zn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as Jn}from"../../control.js";import{notFound as P,usage as w}from"../../../core/errors.js";import{assertScope as Un,validateScopes as me}from"../../../core/scopes.js";import{scopeAllowed as I}from"../../../shared/env.js";import{toCloseResultDTO as Yn,toNodeDetailDTO as J,toNodeSummaryDTO as Hn,toReviveResultDTO as Qn}from"../map.js";import{ApiError as u}from"../../../api/index.js";import{InputError as y}from"../../../core/io.js";import{actsAsPerson as Xn,brokerMayReach as U,canReadNode as we,resolvedScopes as Zn}from"../router.js";import{forwardVerb as qn,queryWithoutMachine as et,relayError as nt,unknownError as tt,withMachine as it}from"../../peer/forward.js";import{fileRoot as ot}from"../../../core/spaces/file-root.js";import{activeGrant as rt,payerOfGrant as at,terminalGrant as dt}from"../../../core/grants/mirror.js";import{appRungForGrant as st}from"../../../core/llm/app-rungs.js";import{APP_FAMILY as lt}from"../../../core/model-routes.js";import{readConfig as ct}from"../../../core/config.js";import{hasConfiguredProviderCredential as ft,NO_PROVIDER_CREDENTIAL_MESSAGE as he}from"../../../core/runtime/provider-credential-gate.js";import{filterAsync as Y,mapAsync as ye}from"../../../core/async-array.js";async function h(e){const t=await R(e);if(t===null)throw P(`unknown node: ${e}`,{received:e});return t}s(h,"requireMeta");async function H(e){return{subscribesTo:await ae(e),subscribers:await Ve(e),children:await Ge(e)}}s(H,"edgesFor");async function g(e){const t=await h(e);return await J(t,await H(e))}s(g,"detailOf");async function ut(e){let t=(await ue(e)).length;try{t+=dn(await V(e),await de(e)).length}catch(n){if(!rn(n))throw n}return t}s(ut,"countFiles");function pt(e){if(typeof e!="object"||e===null)throw w("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw w("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw w("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw w("creator must be a non-empty node id when provided");if(t.scopes!==void 0&&me(t.scopes),t.isolated!==void 0&&typeof t.isolated!="boolean")throw new u(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw w("root_lifecycle must be 'resident' or 'terminal'");if(t.request_key!==void 0&&(typeof t.request_key!="string"||t.request_key.trim()===""||t.request_key.length>128))throw w("request_key must be a non-empty string of at most 128 characters when provided");return t}s(pt,"parseCreateBody");function mt(e){if(e===void 0)return;const t=Ln(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new u(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}s(mt,"parseDeadline");function wt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new u(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!Pn.test(e.action))throw new u(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new u(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new u(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>ce)throw new u(413,"payload_too_large",`serialized payload exceeds ${ce} bytes`)}return e}}s(wt,"parseOutcomeDelivery");function ht(e,t){const n=Dn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new u(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new u(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}s(ht,"resolveOutcomeDelivery");function yt(e,t,n){const o={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(o.mode=e.mode),e.name!==void 0&&(o.name=e.name),e.description!==void 0&&(o.description=e.description),t!==void 0&&(o.parent=t),e.creator!==void 0&&(o.creator=e.creator),e.scopes!==void 0&&(o.scopes=e.scopes),e.isolated!==void 0&&(o.isolated=e.isolated),e.root===!0&&(o.root=!0),e.root_lifecycle!==void 0&&(o.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(o.worktree=!0),typeof e.worktree=="string"&&(o.worktreeBase=e.worktree),e.worktree!==void 0&&(o.worktreeCwd=T(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(o.forkFrom=e.fork_from),e.model!==void 0&&(o.model=e.model),e.profile!==void 0&&(o.profile=e.profile),e.situational_context!==void 0&&(o.situationalContext=e.situational_context),e.node_id!==void 0&&(o.nodeId=e.node_id),o}s(yt,"buildRecipe");function _t(e,t,n){return!Gn()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0||e.isolated!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}s(_t,"warmRequestFor");import{resolveCreateKind as _o}from"../../../core/runtime/launch-target.js";function _e(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return An(e.model,t,e.modelExact===!0)}s(_e,"requestFromLaunch");function gt(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(o=>!I(t,o));if(n.length===0)return e;throw new u(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}s(gt,"withinCeiling");async function ge(e,t,n){const o=(await Rn(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await K(_e(o),{cwd:e.cwd,profileId:e.profile_id??null},n)}s(ge,"assertNodeModelChangeRegistered");async function be(e,t){const n=e.principal;if(n.class!=="broker"&&n.class!=="cron")return;const o=ot({app:n.app,resolved:await Zn(n),launched:n.scopes},t,"read");if("root"in o)return;const i="missing"in o?o.missing:null;throw new u(403,"scope_missing",i?`the child's directory ${t} needs missing scope ${i}`:`no permission of this run names the child's directory ${t}`,void 0,void 0,i?{scope:i}:void 0)}s(be,"assertCallerReaches");const Q=new Map;async function bt(e,t={},n={}){const o=gt(pt(e.body),e.ceiling);if(e.principal.class==="broker"){const c=e.principal;if(o.prefer_warm===!0&&c.app!=="app:terminal"&&(o.prefer_warm=!1),o.parent!=null){const r=await h(o.parent);if(r.grantee!==c.app)throw new u(403,"other_app_run","cannot create a child under another app's node");if(!await U(c,o.parent,r.grantee??"app:terminal"))throw P(`unknown node: ${o.parent}`,{received:o.parent})}if(o.creator!==void 0&&o.creator!==c.node)throw new u(403,"other_app_run","cannot create for another node");if(o.fork_from!==void 0){let r=null;try{r=await je(await Le(o.fork_from))}catch{}if(r?.grantee!==c.app||!await U(c,r.node_id,r.grantee))throw new u(403,"other_app_run","cannot fork another app's conversation")}o.creator=c.node}if(e.principal.class==="cron"){const c=e.principal;for(const l of["parent","creator","fork_from","node_id"])if(o[l]!=null)throw new u(403,"permission_error",`a cron cannot set ${l} on a node it starts`);o.prefer_warm=!1;const r=await nn({grantee:c.app,sub:c.sub,grant_id:c.grant,scopes:c.scopes});if(!r.allowed)throw new u(r.reason==="scope_missing"?403:401,r.reason==="scope_missing"?"scope_missing":"grant_revoked",r.message);if(o.scopes!==void 0){const l=o.scopes.find(p=>!I(r.effectiveScopes,p)||!I(c.scopes,p));if(l!==void 0)throw new u(403,"scope_missing",`scope ${l} is not held by this cron`,void 0,void 0,{scope:l})}else c.scopes!==null&&(o.scopes=[...c.scopes]);o.node_id=await ne(),c.isolated&&(o.isolated=!0,o.cwd=await V(o.node_id,c.app))}o.creator!==void 0&&Un(await h(o.creator),"crtr:act");const i=o.request_key?.trim();if(i===void 0||o.node_id!==void 0&&en(o.node_id)&&await R(o.node_id)!==null&&(await Fe(i))?.nodeId!==o.node_id)return D(e,o,t,n);const d=Q.get(i);if(d!==void 0)return d;const a=vt(e,o,i,t,n);Q.set(i,a);try{return await a}finally{Q.delete(i)}}s(bt,"handleCreate");async function vt(e,t,n,o,i){const d=await oe(n);if(d.nodeId!==null&&await R(d.nodeId)!==null){if(d.state!=="warm_claimed"){const a=await R(d.nodeId);if(e.principal.class!=="person"&&!await we(e.principal,a.grantee??"app:terminal",d.nodeId))throw new u(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:await g(d.nodeId)}}return D(e,t,o,i,d)}try{return await D(e,t,o,i,d)}catch(a){const c=await oe(n);throw(c.nodeId===null||await R(c.nodeId)===null)&&await te(n,c.nodeId),a}}s(vt,"handleKeyedCreateRequest");async function D(e,t,n,o,i=void 0){const d=o.deadlineAt??mt(t.deadline),a=wt(t.outcome_delivery),c=e.principal.class==="cron"?await tn({grantee:e.principal.app,sub:e.principal.sub,grant_id:e.principal.grant,scopes:e.principal.scopes,cron_id:e.principal.cron,origin_run_id:e.principal.origin_run,isolated:e.principal.isolated,creator:(await pe(e.principal.cron))?.created_by??null},t.node_id):null;c!==null&&(t.root=c.root===!0);const r=c?.parent??t.parent??void 0;if(r==null&&t.root!==!0)throw w("a node create requires a parent (or root: true for an independent root)");let l=null;if(t.output_schema!==void 0){try{l=JSON.parse(t.output_schema)}catch{throw w("output_schema must be a JSON schema string")}if(l===null||typeof l!="object"||Array.isArray(l))throw w("output_schema must be a JSON schema object");await En(l)}const{profileId:p,kind:m,cwd:f,launch:b}=await Bn(t,{validateKind:Oe});await be(e,f),t.worktree!==void 0&&await be(e,T(t.pin_cwd??t.cwd??f));const v={...t,kind:m},_=a===void 0?void 0:ht(a,f),X=("grant"in e.principal?e.principal.grant:null)??(r==null?null:(await R(r))?.grant_id??null);if(await K(_e(await Pe(b,X,t.model)),{cwd:f,profileId:p},n.modelRegistry),await at(X)!=="app"&&!await ft(p))throw new u(412,"no_provider_credential",he,{error:"no_provider_credential",message:he,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let M=null;{const A=i===void 0||i.nodeId===null||i.state==="warm_claimed"?_t(v,f,p):null,j=l===null&&o.beforeBrokerLaunch===void 0?void 0:async S=>{l!==null&&await Tn(S,"terminal",l),o.beforeBrokerLaunch?.(S)};if(i?.state==="warm_claimed"&&i.nodeId!==null){const S=A===null?null:await jn(A,i.nodeId,j);if(S===null)throw await te(i.requestKey,i.nodeId),new u(503,"create_resume_failed",`could not resume warm claim ${i.nodeId}; retry the create`);return await ie(i.requestKey,S),{status:201,body:await g(S)}}if(A!==null){const S=await Mn(A,{...d===void 0?{}:{deadlineAt:d},..._===void 0?{}:{outcomeDelivery:_},...i===void 0?{}:{requestKey:i.requestKey}},j);if(S!==null)return i!==void 0&&await ie(i.requestKey,S),fe(A),{status:201,body:await g(S)};M=A}const G=i?.nodeId??t.node_id??(i===void 0?void 0:await ne());i!==void 0&&i.nodeId===null&&await Ke(i.requestKey,G);const O=yt(G===void 0?v:{...v,node_id:G},r,f);c!==null&&(c.rootLifecycle!==void 0&&(O.rootLifecycle=c.rootLifecycle),c.scopes!==void 0&&v.scopes===void 0&&(O.scopes=c.scopes),c.run!==void 0&&(O.run=c.run),c.withinCreate!==void 0&&(O.withinCreate=c.withinCreate)),d!==void 0&&(O.deadlineAt=d),_!==void 0&&(O.outcomeDelivery=_),O.readiness=t.root===!0?"await":"launch";const Z=await Me(O,j,()=>{M!==null&&fe(M)});return i!==void 0&&await Be(i.requestKey,Z.node.node_id),{status:201,body:await g(Z.node.node_id)}}}s(D,"handleCreateRequest");function k(e,t){const n=e.query.getAll(t);if(n.length>1)throw w(`${t} must appear at most once`);return n[0]}s(k,"singleQueryValue");function ve(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw w(`${t} must be true or false`)}}s(ve,"optionalBoolean");function L(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw w(`${t} must be one of: ${n.join(", ")}`)}}s(L,"oneOf");function kt(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[b]of e.query)if(!t.has(b))throw w(`unknown nodes query parameter: ${b}`);const n=L(k(e,"status"),"status",["active","idle","done","dead","canceled"]),o=L(k(e,"lifecycle"),"lifecycle",["terminal","resident"]),i=k(e,"kind"),d=L(k(e,"mode"),"mode",["base","orchestrator"]),a=k(e,"profile_id"),c=k(e,"profile_prefix"),r=k(e,"parent"),l=ve(k(e,"top_level"),"top_level"),p=k(e,"under"),m=ve(k(e,"hanging"),"hanging"),f=L(k(e,"include"),"include",["activity"]);if(r!==void 0&&l===!0)throw w("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...o!==void 0?{lifecycle:o}:{},...i!==void 0?{kind:i}:{},...d!==void 0?{mode:d}:{},...a!==void 0?{profile_id:a}:{},...c!==void 0?{profile_prefix:c}:{},...r!==void 0?{parent:r}:{},...l!==void 0?{top_level:l}:{},...p!==void 0?{under:p}:{},...m!==void 0?{hanging:m}:{},...f!==void 0?{include:f}:{}}}s(kt,"parseListQuery");async function St(e){const t=kt(e);let n=t.status!==void 0?await re({status:t.status}):await re();if(e.principal.class!=="person"&&(n=await Y(n,async a=>await we(e.principal,a.grantee??"app:terminal",a.node_id))),t.lifecycle!==void 0&&(n=n.filter(a=>a.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(a=>a.kind===t.kind)),t.mode!==void 0&&(n=n.filter(a=>a.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(a=>a.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(a=>a.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(a=>a.parent===t.parent)),t.top_level===!0&&(n=n.filter(a=>a.parent===null)),t.under!==void 0){const a=new Set(await ze(t.under));n=n.filter(c=>a.has(c.node_id))}t.hanging===!0&&(n=await Y(n,async a=>a.parent!==null&&await R(a.parent)===null));const o=t.include==="activity"?await qe(n.map(a=>a.node_id)):null,i=n.length>0?$e():new Set;return{status:200,body:await ye(n,async a=>{const c=await Hn(a,a.profile_id!==null&&i.has(a.profile_id));if(o!==null){const r=await ue(a.node_id);c.activity={latest_report:r[0]??null,final_report:a.final_report===null?null:r.find(l=>l.name===a.final_report)??null,pending_human_count:o[a.node_id]??0}}return c})}}s(St,"handleList");async function Rt(e){const t=e.params.id,n=await qn(e,t,{method:"GET",path:`/v1/nodes/${encodeURIComponent(t)}`,query:et(e)});if(n.kind==="unknown")throw tt(t,n.unreachable);if(n.kind==="remote"){if(n.status>=400)throw nt(n.status,n.body);return{status:n.status,body:it(n.body,n.machine)}}return await h(t),{status:200,body:await g(t)}}s(Rt,"handleDetail");async function Ot(e){const t=e.params.id;await h(t);const n=await cn(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.turnReplies===void 0?{}:{turnReplies:n.snapshot.turnReplies},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(i=>({name:i.name,description:i.description,source:i.source})),captured_at:B()}}}s(Ot,"handleSnapshot");async function It(e){const t=e.params.id,n=await un(t);if(n===null)throw P(`unknown node: ${t}`,{received:t});return{status:200,body:n}}s(It,"handleSubject");function At(e){for(const[d]of e.query)if(d!=="cursor"&&d!=="limit")throw w(`unknown messages query parameter: ${d}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw w("cursor must appear at most once");if(n.length>1)throw w("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const o=n[0],i=Number(o);if(!Number.isSafeInteger(i)||o==="")throw w("limit must be an integer from 1 through 500");return t.length===0?{limit:i}:{cursor:t[0],limit:i}}s(At,"parseMessagesQuery");async function $t(e){const t=e.params.id,n=await sn(t,At(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:B()}}}s($t,"handleMessages");async function Ct(e){const t=e.params.id;await h(t);const n=await ln(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:B()}}}s(Ct,"handleSession");async function Nt(e){const t=e.params.id;return await h(t),{status:200,body:{node_id:t,markdown:await fn(t)}}}s(Nt,"handleTranscript");async function Tt(e){const t=e.params.id;await h(t);const n=s(async(i,d)=>({node_id:i,label:(await R(i))?.name??i,dir:await de(i),self:d,files:await ut(i)}),"root"),o=await Y([await n(t,!0),...await ye(await ae(t),async i=>await n(i.node_id,!1))],async i=>await Et(i.node_id,i.dir)||i.files>0);return{status:200,body:{node_id:t,roots:o}}}s(Tt,"handleContext");async function Et(e,t){try{return on(await V(e),t)}catch(n){if(an(n))return!1;throw n}}s(Et,"hasDir");async function Pt(e){const t=await h(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,o=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(d=>I(n,d)),...n.filter(d=>I(t.scopes,d))])],i=await De(t.node_id,o,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:await g(i.node.node_id)}}s(Pt,"handleFork");const Dt=1e4;async function Lt(e){const t=e.params.id;await h(t);const n=e.body,o=n?.resume??!0,i=n?.reopen??!1;await _n(t,i,e.principal.class==="broker"?e.principal.node:null);const d=!o&&n?.cron_id!==void 0?await pe(n.cron_id):null,a=await Ee(t,{resume:o,capacity:"refuse",...d!==null?{wakeReason:await zn(d,"schedule_revive")}:{}});a.outcome!=="already-live"&&await We(t,{failures:0,notBefore:null});const c=(await R(t))?.status??"active",r=(a.launch??E().get(t)?.handle)?.exited,l=a.outcome!=="frozen"&&await le(t,r,Dt);return{status:200,body:Qn(t,a,c,l)}}s(Lt,"handleRevive");async function Mt(e){const t=e.params.id;return{status:200,body:{newNodeId:(await yn(t))?.newNodeId??null}}}s(Mt,"handleRelaunchRoot");async function jt(e){const t=e.params.id;await h(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw w("caller_pid must be a positive integer when provided");const o=Jn(),i=await Te(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...o===null?{}:{registerDetached:o.registerDetached}});return{status:200,body:Yn(i)}}s(jt,"handleClose");async function Gt(e){if(!Xn(e.principal))throw new u(403,"permission_error","only the person marks a conversation read");const t=e.params.id;return await h(t),await Je(t),{status:204}}s(Gt,"handleMarkRead");async function Ft(e){const t=e.params.id;await h(t);const n=await hn(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}s(Ft,"handleRecycle");async function Bt(e){const t=e.params.id;return await h(t),await x(t,{lifecycle:"terminal"}),await $(e,t,["lifecycle"]),{status:200,body:await g(t)}}s(Bt,"handleDemote");async function Kt(e,t={}){const n=e.params.id,o=await h(n),i=e.body??{};i.kind!==void 0&&await z(i.kind,o.cwd,o.profile_id??null),i.model!==void 0&&await ge(o,{kind:i.kind??o.kind,mode:"orchestrator",lifecycle:i.resident===!0?"resident":o.lifecycle,model:i.model},t.modelRegistry);const d=await mn(n,{...i.kind!==void 0?{kind:i.kind}:{},...i.resident===!0?{resident:!0}:{},...i.model!==void 0?{model:i.model}:{}});await $(e,n,["mode",...i.kind!==void 0?["kind"]:[],...i.resident===!0?["lifecycle"]:[],...i.model!==void 0?["model"]:[]]);const a=await J(d.meta,await H(n));return a.roadmap_written=d.roadmapWritten,a.roadmap_ref=d.roadmapRef,a.goal_path=d.goalPath,{status:200,body:a}}s(Kt,"handlePromote");async function Wt(e,t={}){const n=e.params.id,o=await h(n),i=e.body??{};i.kind!==void 0&&await z(i.kind,o.cwd,o.profile_id??null),i.model!==void 0&&await ge(o,{kind:i.kind??o.kind,mode:i.promote===!0?"orchestrator":o.mode,lifecycle:o.lifecycle,model:i.model},t.modelRegistry);const d=i.note??"Refresh: continue against your roadmap or goal.";await gn(n,d);const a=await wn(n,{...i.promote===!0?{promote:!0}:{},...i.kind!==void 0?{kind:i.kind}:{},...i.model!==void 0?{model:i.model}:{}});return{status:200,body:await J(a.meta,await H(n))}}s(Wt,"handleYield");async function Vt(e){const t=e.params.id;await h(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw w("a wait requires a controller node id");const o=await R(n.controller);if(o===null)throw P(`unknown controller: ${n.controller}`,{received:n.controller});if(o.status!=="active"&&o.status!=="idle")throw new u(422,"unprocessable",`controller ${n.controller} is ${o.status}`);return await xe(t,n.controller),{status:200,body:await g(t)}}s(Vt,"handleWait");async function xt(e){const t=e.principal,n=await pn(t.class==="broker"?async i=>i.grantee===t.app&&await U(t,i.node_id,i.grantee):void 0);return{status:200,body:{revived:[...n.revived],failed:[...n.failed],frozen:[...n.frozen]}}}s(xt,"handleReviveAll");const zt=new Set(["interrupt","steer","after-turn","next-turn"]);function Jt(e){if(e===null)return null;const t=s(o=>{throw new y({error:"invalid_listen",message:o,received:e,field:"listen",next:'Send an object mapping levels "1".."10" to interrupt|steer|after-turn|next-turn (e.g. {"3":"next-turn"}), or null to reset to the global default.'})},"bad");if(typeof e!="object"||Array.isArray(e))return t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[o,i]of n)/^(?:[1-9]|10)$/.test(o)||t(`listen level must be 1..10: ${o}`),(typeof i!="string"||!zt.has(i))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(i)}`);return JSON.stringify(Object.fromEntries(n))}s(Jt,"listenJson");async function $(e,t,n,o){n.length===0&&o===void 0||await W(async i=>{if(o?.(i),n.length===0)return;const d=await Ue(i,t),a=await Qe(i,e),c=a.class==="person"?a.person:a.class==="app"?a.app:a.node;await Ye(i,c,d),await He(i,{event:"configured",object:d,actor:c,attrs:{changed:n.join(",")}})})}s($,"recordConfigured");function ke(e){const t=E().get(e);if(t===void 0)return!1;try{return process.kill(t.pid,"SIGTERM"),!0}catch{return!1}}s(ke,"restartLiveBroker");function Se(e,t){try{return q(e)===q(t)}catch{return!1}}s(Se,"sameDirectory");async function Ut(e,t={}){const n=e.params.id,o=e.body;let i;if(o===void 0)i={};else if(typeof o=="object"&&o!==null&&!Array.isArray(o))i=o;else throw new y({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:o,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(i.profile!==void 0){if(typeof i.profile!="string"||i.profile==="")throw new y({error:"profile_invalid",message:"profile must be a non-empty profile id or name",received:i.profile,field:"profile",next:"Send a profile id or exact name."});if(Object.keys(i).some(m=>m!=="profile"&&m!=="restart"&&i[m]!==void 0))throw new y({error:"profile_not_exclusive",message:"profile can only be combined with restart",field:"profile",next:"Send profile (and optionally restart) alone."});const r=await h(n),l=await Wn(e,i.profile);Vn(l.profileId);const p=xn(l.profileId).manifest.grantee??"app:terminal";if(p!==(r.grantee??"app:terminal"))throw new y({error:"profile_grantee_mismatch",message:`profile ${l.profileId} belongs to ${p}, node ${n} to ${r.grantee}`,received:i.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(r.profile_id??null)!==l.profileId&&(Fn(r.kind)?(await z(r.kind,r.cwd,l.profileId),await x(n,{profileId:l.profileId})):await C(n,{profile_id:l.profileId}),await $(e,n,["profile"])),i.restart===!0&&ke(n),{status:200,body:await g(n)}}if(Object.prototype.hasOwnProperty.call(i,"cwd")){const r=i.cwd;if(typeof r!="string"||r==="")throw new y({error:"cwd_invalid",message:"cwd must be a non-empty string",received:r,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(i).some(f=>f!=="cwd"&&f!=="keep_session"&&f!=="restart"&&i[f]!==void 0))throw new y({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:i,field:"cwd",next:"Send cwd as the only config field."});const l=await h(n),p=N(l.cwd);if(i.keep_session===!0||p&&F(r)&&N(r)&&Se(l.cwd,r)){if(!F(r))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${r}`,received:r,field:"cwd",next:"Send an absolute path."});const f=T(r);let b=!1;try{b=ee(f).isDirectory()}catch{}if(!b)throw new y({error:"cwd_missing",message:`cwd is not an existing directory: ${f}`,received:r,field:"cwd",next:"Send an existing absolute directory."});if(p&&!Se(l.cwd,f))throw new y({error:"cwd_not_same_directory",message:`${f} is not the same directory as the recorded ${l.cwd}; --keep-session only relocates an alias`,received:r,field:"cwd",next:"Drop --keep-session to repair a gone cwd, or pass the real path of the recorded directory."});if(l.managed_worktree?.state==="open")throw new y({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot relocate its cwd`,received:r,field:"cwd",next:"Reconcile the managed worktree first."});const v=l.cwd;return v!==f&&(await W(async _=>{await C(n,{cwd:f}),await _.prepare("UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(f,n,v),await Xe(n,v,f)}),await $(e,n,["cwd"])),i.restart===!0&&ke(n),{status:200,body:await g(n)}}if(E().has(n)){const f=`${n} cannot repair its cwd while its broker is live`;throw new u(409,"cwd_node_live",f,{error:"cwd_node_live",message:f,received:r,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(l.fork_from!=null)throw new y({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${l.cwd}`,received:r,field:"cwd",next:`Restore ${l.cwd}, then revive the fork normally.`});if(l.managed_worktree?.state==="open")throw new y({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:r,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(N(l.cwd))throw new y({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${l.cwd}; cwd repair is not a relocation command`,received:r,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!F(r))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${r}`,received:r,field:"cwd",next:"Send an absolute path."});const m=T(r);if(!N(m))throw new y({error:"cwd_missing",message:`cwd does not exist: ${m}`,received:r,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!ee(m).isDirectory())throw new y({error:"cwd_not_a_directory",message:`cwd is not a directory: ${m}`,received:r,field:"cwd",next:"Send an existing absolute directory."})}catch(f){throw f instanceof y?f:new y({error:"cwd_missing",message:`cwd does not exist: ${m}`,received:r,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return await W(async()=>{await C(n,{cwd:m}),await Ze(n)}),await $(e,n,["cwd"]),{status:200,body:await g(n)}}let d=await h(n);const a=i.listen===void 0?void 0:Jt(i.listen);if(i.scopes!==void 0){const r=me(i.scopes),l=d.grantee==="app:terminal"?await dt():d.grant_id?await rt(d.grant_id):null,p=d.grantee==="app:terminal"&&!ct("user").runtime?.issuer;if(!r.every(m=>I(d.scopes,m)&&(l?I(l.resolved,m):p)))throw new y({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:r,field:"scopes",next:"Send only scopes the node currently holds."});if(r.includes("crtr:act")&&!I(r,"crtr:llm"))throw new u(400,"invalid_scope","crtr:act requires crtr:llm");d=await C(n,{scopes:r})}if(i.situational_context!==void 0&&Ce(n,Ne(i.situational_context)),i.model!==void 0){const r=(await se(d.cwd,d.profile_id??null)).modelLadders,l=On(i.model,r),p=await st(d.grant_id,i.model,l===void 0),m=p?{family:lt,strength:p.strength}:l,f=p?p.model:In(i.model,r);await K({kind:"concrete",spec:f},{cwd:d.cwd,profileId:d.profile_id??null},t.modelRegistry);const b=E();let v=!1;if(b.isClaimed(n)&&await le(n,b.get(n)?.handle.exited)&&(v=await Cn(n,f,m).then(()=>!0,_=>{if(_ instanceof Nn)return!1;throw _})),!v){if(b.isClaimed(n)){const _=`${n}'s broker did not accept the model switch; the model was not changed`;throw new u(409,"broker_not_ready",_,{error:"broker_not_ready",message:_,received:i.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!f.includes("/"))throw w(`model must resolve to a provider/id spec: ${i.model}`);await $n(n,f,m)}d=await h(n)}if(i.kind!==void 0||i.mode!==void 0||i.lifecycle!==void 0){i.kind!==void 0&&await Oe(i.kind);const r=i.kind??d.kind,l=i.mode??d.mode,p=i.lifecycle??d.lifecycle;let m;l==="orchestrator"&&!await kn(n)&&(m=s(async()=>{const f=await bn(n);await vn(n,f!==null&&f.trim()!==""?{goal:f.trim()}:{})},"beforePersist")),d=await x(n,{...i.kind!==void 0?{kind:r}:{},...i.mode!==void 0?{mode:l}:{},...i.lifecycle!==void 0?{lifecycle:p}:{}},m)}i.name!==void 0&&(d=await C(n,{name:i.name}),d.window&&Sn(d.window,Kn(d)));const c=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(r=>i[r]!==void 0);return await $(e,n,c,a===void 0?void 0:async r=>{await r.prepare("UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(a,n)}),{status:200,body:await g(n)}}s(Ut,"handleConfig");async function Re(){return(await se(process.cwd(),Ae()||null)).kinds}s(Re,"daemonKinds");async function Oe(e){const t=Object.keys(await Re());if(!t.includes(e))throw w(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}s(Oe,"assertKindServer");async function Yt(){const e=await Re();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}s(Yt,"handleListKinds");const wo=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:bt},{method:"GET",pattern:"/v1/nodes",handler:St},{method:"GET",pattern:"/v1/kinds",handler:s(()=>Yt(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:xt},{method:"GET",pattern:"/v1/nodes/:id",handler:Rt},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:Ot},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:It},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:$t},{method:"GET",pattern:"/v1/nodes/:id/session",handler:Ct},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:Nt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:Tt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:Pt},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Lt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:Mt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:jt},{method:"POST",pattern:"/v1/nodes/:id/read",handler:Gt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:Ft},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Bt},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Kt},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Wt},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Vt},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Ut}];export{Ut as handleConfig,bt as handleCreate,Pt as handleFork,St as handleList,Kt as handlePromote,Wt as handleYield,wo as nodeRoutes,_o as resolveCreateKind};
|
|
1
|
+
var Ie=Object.defineProperty;var s=(e,t)=>Ie(e,"name",{value:t,configurable:!0});import{envProfileId as Ae}from"../../../shared/env.js";import{pausedCanvasProfiles as $e}from"../../../core/profiles/manifest.js";import{existsSync as N,realpathSync as q,statSync as ee}from"node:fs";import{isAbsolute as F,resolve as T}from"node:path";import{appendSituationalContext as Ce,formatSituationalProse as Ne}from"../../../core/runtime/situational-context.js";import{closeNode as Te}from"../../../core/runtime/close.js";import{reviveNode as Pe}from"../../../core/runtime/revive.js";import{nowIso as B}from"../../../core/fs-utils.js";import{appPaidLaunch as Ee,assertLaunchModelRegistered as K,forkNode as De,resolveForkSource as Le,spawnChildPrepared as Me}from"../../../core/runtime/spawn.js";import{forkSourceNode as je,newNodeId as ne}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as te,childrenOf as Ge,completeCreateRequest as ie,findCreateRequest as Fe,getNode as R,recordCreateRequestNode as Be,reserveCreateRequest as oe,reserveCreateRequestNode as Ke,listNodes as re,recordRespawnAttempt as We,subscribersOf as Ve,subscriptionsOf as ae,updateNode as C}from"../../../core/canvas/canvas.js";import{armControllerWait as xe}from"../../../core/canvas/waits.js";import{subtreeIds as ze}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as W}from"../../../core/canvas/db.js";import{markNodeRead as Je}from"../../../core/canvas/recovery.js";import{nodeObject as Ue}from"../../../core/graph/objects.js";import{recordActedOn as Ye}from"../../../core/graph/edges.js";import{publish as He}from"../../../core/graph/events.js";import{readerFor as Qe}from"../reader.js";import{relocateSessionCwd as Xe,unbindSession as Ze}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as qe}from"../../../core/canvas/attention.js";import{isSafeNodeId as en}from"../../../core/canvas/paths.js";import{contextDir as de,nodeAgentDir as V}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as nn}from"../../cron/authority.js";import{cronBirthPlacement as tn}from"../../cron/armed-context.js";import{existsBeneath as on,isAbsentOrRefused as rn,isBeneathRefusal as an,readdirBeneath as dn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as sn,readNodeSession as ln,readNodeSnapshot as cn,transcriptMarkdown as fn}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as un}from"../../../core/substrate/subject.js";import{reviveAll as pn}from"../../../core/runtime/revive-all.js";import{promoteAsync as mn,requestYieldAsync as wn,reshapeNodeAsync as x}from"../../../core/runtime/promote.js";import{recycleNode as hn}from"../../../core/runtime/recycle.js";import{relaunchRoot as yn}from"../../../core/runtime/reset.js";import{assertReopenGate as _n}from"../../../core/runtime/reopen.js";import{writeYieldMessage as gn,readGoal as bn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as vn,hasRoadmap as kn}from"../../../core/runtime/roadmap.js";import{renameWindow as Sn}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as Rn,explicitModelIntent as On,normalizeModel as In,readMergedLaunchConfigAsync as se}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as An}from"../../../core/model-routes.js";import{persistDormantModel as $n,setModelLive as Cn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as le}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as Nn}from"../../../core/runtime/broker-request.js";import{boundFleet as P}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as Tn}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as Pn}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as ce}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as En}from"../../../core/human/action-binding.js";import{resolveHumanAction as Dn}from"../../../core/human-actions.js";import{parseDurationMs as Ln}from"../../../core/wake.js";import{claimWarmNode as Mn,refillWarmPool as fe,resumeWarmClaim as jn,warmPoolEnabled as Gn}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as z,isLaunchKind as Fn,resolveLaunchTarget as Bn}from"../../../core/runtime/launch-target.js";import{fullName as Kn}from"../../../core/canvas/labels.js";import{reportsForNode as ue}from"./reports.js";import{requireUsableProfile as Wn}from"./profiles.js";import{assertProfileActive as Vn,loadExactProfileManifest as xn}from"../../../core/profiles/manifest.js";import{getCron as pe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as zn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as Jn}from"../../control.js";import{notFound as E,usage as w}from"../../../core/errors.js";import{assertScope as Un,validateScopes as me}from"../../../core/scopes.js";import{scopeAllowed as I}from"../../../shared/env.js";import{toCloseResultDTO as Yn,toNodeDetailDTO as J,toNodeSummaryDTO as Hn,toReviveResultDTO as Qn}from"../map.js";import{ApiError as u}from"../../../api/index.js";import{InputError as y}from"../../../core/io.js";import{actsAsPerson as Xn,brokerMayReach as U,canReadNode as we,resolvedScopes as Zn}from"../router.js";import{forwardVerb as qn,queryWithoutMachine as et,relayError as nt,unknownError as tt,withMachine as it}from"../../peer/forward.js";import{fileRoot as ot}from"../../../core/spaces/file-root.js";import{activeGrant as rt,payerOfGrant as at,terminalGrant as dt}from"../../../core/grants/mirror.js";import{appRungForGrant as st}from"../../../core/llm/app-rungs.js";import{APP_FAMILY as lt}from"../../../core/model-routes.js";import{readConfig as ct}from"../../../core/config.js";import{hasConfiguredProviderCredential as ft,NO_PROVIDER_CREDENTIAL_MESSAGE as he}from"../../../core/runtime/provider-credential-gate.js";import{filterAsync as Y,mapAsync as ye}from"../../../core/async-array.js";async function h(e){const t=await R(e);if(t===null)throw E(`unknown node: ${e}`,{received:e});return t}s(h,"requireMeta");async function H(e){return{subscribesTo:await ae(e),subscribers:await Ve(e),children:await Ge(e)}}s(H,"edgesFor");async function g(e){const t=await h(e);return await J(t,await H(e))}s(g,"detailOf");async function ut(e){let t=(await ue(e)).length;try{t+=dn(await V(e),await de(e)).length}catch(n){if(!rn(n))throw n}return t}s(ut,"countFiles");function pt(e){if(typeof e!="object"||e===null)throw w("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw w("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw w("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw w("creator must be a non-empty node id when provided");if(t.scopes!==void 0&&me(t.scopes),t.isolated!==void 0&&typeof t.isolated!="boolean")throw new u(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw w("root_lifecycle must be 'resident' or 'terminal'");if(t.request_key!==void 0&&(typeof t.request_key!="string"||t.request_key.trim()===""||t.request_key.length>128))throw w("request_key must be a non-empty string of at most 128 characters when provided");return t}s(pt,"parseCreateBody");function mt(e){if(e===void 0)return;const t=Ln(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new u(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}s(mt,"parseDeadline");function wt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new u(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!En.test(e.action))throw new u(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new u(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new u(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>ce)throw new u(413,"payload_too_large",`serialized payload exceeds ${ce} bytes`)}return e}}s(wt,"parseOutcomeDelivery");function ht(e,t){const n=Dn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new u(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new u(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}s(ht,"resolveOutcomeDelivery");function yt(e,t,n){const o={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(o.mode=e.mode),e.name!==void 0&&(o.name=e.name),e.description!==void 0&&(o.description=e.description),t!==void 0&&(o.parent=t),e.creator!==void 0&&(o.creator=e.creator),e.scopes!==void 0&&(o.scopes=e.scopes),e.isolated!==void 0&&(o.isolated=e.isolated),e.root===!0&&(o.root=!0),e.root_lifecycle!==void 0&&(o.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(o.worktree=!0),typeof e.worktree=="string"&&(o.worktreeBase=e.worktree),e.worktree!==void 0&&(o.worktreeCwd=T(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(o.forkFrom=e.fork_from),e.model!==void 0&&(o.model=e.model),e.profile!==void 0&&(o.profile=e.profile),e.situational_context!==void 0&&(o.situationalContext=e.situational_context),e.node_id!==void 0&&(o.nodeId=e.node_id),o}s(yt,"buildRecipe");function _t(e,t,n){return!Gn()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0||e.isolated!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}s(_t,"warmRequestFor");import{resolveCreateKind as _o}from"../../../core/runtime/launch-target.js";function _e(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return An(e.model,t,e.modelExact===!0)}s(_e,"requestFromLaunch");function gt(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(o=>!I(t,o));if(n.length===0)return e;throw new u(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}s(gt,"withinCeiling");async function ge(e,t,n){const o=(await Rn(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await K(_e(o),{cwd:e.cwd,profileId:e.profile_id??null},n)}s(ge,"assertNodeModelChangeRegistered");async function be(e,t){const n=e.principal;if(n.class!=="broker"&&n.class!=="cron")return;const o=ot({app:n.app,resolved:await Zn(n),launched:n.scopes},t,"read");if("root"in o)return;const i="missing"in o?o.missing:null;throw new u(403,"scope_missing",i?`the child's directory ${t} needs missing scope ${i}`:`no permission of this run names the child's directory ${t}`,void 0,void 0,i?{scope:i}:void 0)}s(be,"assertCallerReaches");const Q=new Map;async function bt(e,t={},n={}){const o=gt(pt(e.body),e.ceiling);if(e.principal.class==="broker"){const c=e.principal;if(o.prefer_warm===!0&&c.app!=="app:terminal"&&(o.prefer_warm=!1),o.parent!=null){const r=await h(o.parent);if(r.grantee!==c.app)throw new u(403,"other_app_run","cannot create a child under another app's node");if(!await U(c,o.parent,r.grantee??"app:terminal"))throw E(`unknown node: ${o.parent}`,{received:o.parent})}if(o.creator!==void 0&&o.creator!==c.node)throw new u(403,"other_app_run","cannot create for another node");if(o.fork_from!==void 0){let r=null;try{r=await je(await Le(o.fork_from))}catch{}if(r?.grantee!==c.app||!await U(c,r.node_id,r.grantee))throw new u(403,"other_app_run","cannot fork another app's conversation")}o.creator=c.node}if(e.principal.class==="cron"){const c=e.principal;for(const l of["parent","creator","fork_from","node_id"])if(o[l]!=null)throw new u(403,"permission_error",`a cron cannot set ${l} on a node it starts`);o.prefer_warm=!1;const r=await nn({grantee:c.app,sub:c.sub,grant_id:c.grant,scopes:c.scopes});if(!r.allowed)throw new u(r.reason==="scope_missing"?403:401,r.reason==="scope_missing"?"scope_missing":"grant_revoked",r.message);if(o.scopes!==void 0){const l=o.scopes.find(p=>!I(r.effectiveScopes,p)||!I(c.scopes,p));if(l!==void 0)throw new u(403,"scope_missing",`scope ${l} is not held by this cron`,void 0,void 0,{scope:l})}else c.scopes!==null&&(o.scopes=[...c.scopes]);o.node_id=await ne(),c.isolated&&(o.isolated=!0,o.cwd=await V(o.node_id,c.app))}o.creator!==void 0&&Un(await h(o.creator),"crtr:act");const i=o.request_key?.trim();if(i===void 0||o.node_id!==void 0&&en(o.node_id)&&await R(o.node_id)!==null&&(await Fe(i))?.nodeId!==o.node_id)return D(e,o,t,n);const d=Q.get(i);if(d!==void 0)return d;const a=vt(e,o,i,t,n);Q.set(i,a);try{return await a}finally{Q.delete(i)}}s(bt,"handleCreate");async function vt(e,t,n,o,i){const d=await oe(n);if(d.nodeId!==null&&await R(d.nodeId)!==null){if(d.state!=="warm_claimed"){const a=await R(d.nodeId);if(e.principal.class!=="person"&&!await we(e.principal,a.grantee??"app:terminal",d.nodeId))throw new u(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:await g(d.nodeId)}}return D(e,t,o,i,d)}try{return await D(e,t,o,i,d)}catch(a){const c=await oe(n);throw(c.nodeId===null||await R(c.nodeId)===null)&&await te(n,c.nodeId),a}}s(vt,"handleKeyedCreateRequest");async function D(e,t,n,o,i=void 0){const d=o.deadlineAt??mt(t.deadline),a=wt(t.outcome_delivery),c=e.principal.class==="cron"?await tn({grantee:e.principal.app,sub:e.principal.sub,grant_id:e.principal.grant,scopes:e.principal.scopes,cron_id:e.principal.cron,origin_run_id:e.principal.origin_run,isolated:e.principal.isolated,creator:(await pe(e.principal.cron))?.created_by??null},t.node_id):null;c!==null&&(t.root=c.root===!0);const r=c?.parent??t.parent??void 0;if(r==null&&t.root!==!0)throw w("a node create requires a parent (or root: true for an independent root)");let l=null;if(t.output_schema!==void 0){try{l=JSON.parse(t.output_schema)}catch{throw w("output_schema must be a JSON schema string")}if(l===null||typeof l!="object"||Array.isArray(l))throw w("output_schema must be a JSON schema object");await Pn(l)}const{profileId:p,kind:m,cwd:f,launch:b}=await Bn(t,{validateKind:Oe});await be(e,f),t.worktree!==void 0&&await be(e,T(t.pin_cwd??t.cwd??f));const v={...t,kind:m},_=a===void 0?void 0:ht(a,f),X=("grant"in e.principal?e.principal.grant:null)??(r==null?null:(await R(r))?.grant_id??null);if(await K(_e(await Ee(b,X,t.model)),{cwd:f,profileId:p},n.modelRegistry),await at(X)!=="app"&&!await ft(p))throw new u(412,"no_provider_credential",he,{error:"no_provider_credential",message:he,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let M=null;{const A=i===void 0||i.nodeId===null||i.state==="warm_claimed"?_t(v,f,p):null,j=l===null&&o.beforeBrokerLaunch===void 0?void 0:async S=>{l!==null&&await Tn(S,"terminal",l),o.beforeBrokerLaunch?.(S)};if(i?.state==="warm_claimed"&&i.nodeId!==null){const S=A===null?null:await jn(A,i.nodeId,j);if(S===null)throw await te(i.requestKey,i.nodeId),new u(503,"create_resume_failed",`could not resume warm claim ${i.nodeId}; retry the create`);return await ie(i.requestKey,S),{status:201,body:await g(S)}}if(A!==null){const S=await Mn(A,{...d===void 0?{}:{deadlineAt:d},..._===void 0?{}:{outcomeDelivery:_},...i===void 0?{}:{requestKey:i.requestKey}},j);if(S!==null)return i!==void 0&&await ie(i.requestKey,S),fe(A),{status:201,body:await g(S)};M=A}const G=i?.nodeId??t.node_id??(i===void 0?void 0:await ne());i!==void 0&&i.nodeId===null&&await Ke(i.requestKey,G);const O=yt(G===void 0?v:{...v,node_id:G},r,f);c!==null&&(c.rootLifecycle!==void 0&&(O.rootLifecycle=c.rootLifecycle),c.scopes!==void 0&&v.scopes===void 0&&(O.scopes=c.scopes),c.run!==void 0&&(O.run=c.run),c.withinCreate!==void 0&&(O.withinCreate=c.withinCreate)),d!==void 0&&(O.deadlineAt=d),_!==void 0&&(O.outcomeDelivery=_),O.readiness=t.root===!0?"await":"launch";const Z=await Me(O,j,()=>{M!==null&&fe(M)});return i!==void 0&&await Be(i.requestKey,Z.node.node_id),{status:201,body:await g(Z.node.node_id)}}}s(D,"handleCreateRequest");function k(e,t){const n=e.query.getAll(t);if(n.length>1)throw w(`${t} must appear at most once`);return n[0]}s(k,"singleQueryValue");function ve(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw w(`${t} must be true or false`)}}s(ve,"optionalBoolean");function L(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw w(`${t} must be one of: ${n.join(", ")}`)}}s(L,"oneOf");function kt(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[b]of e.query)if(!t.has(b))throw w(`unknown nodes query parameter: ${b}`);const n=L(k(e,"status"),"status",["active","idle","done","dead","canceled"]),o=L(k(e,"lifecycle"),"lifecycle",["terminal","resident"]),i=k(e,"kind"),d=L(k(e,"mode"),"mode",["base","orchestrator"]),a=k(e,"profile_id"),c=k(e,"profile_prefix"),r=k(e,"parent"),l=ve(k(e,"top_level"),"top_level"),p=k(e,"under"),m=ve(k(e,"hanging"),"hanging"),f=L(k(e,"include"),"include",["activity"]);if(r!==void 0&&l===!0)throw w("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...o!==void 0?{lifecycle:o}:{},...i!==void 0?{kind:i}:{},...d!==void 0?{mode:d}:{},...a!==void 0?{profile_id:a}:{},...c!==void 0?{profile_prefix:c}:{},...r!==void 0?{parent:r}:{},...l!==void 0?{top_level:l}:{},...p!==void 0?{under:p}:{},...m!==void 0?{hanging:m}:{},...f!==void 0?{include:f}:{}}}s(kt,"parseListQuery");async function St(e){const t=kt(e);let n=t.status!==void 0?await re({status:t.status}):await re();if(e.principal.class!=="person"&&(n=await Y(n,async a=>await we(e.principal,a.grantee??"app:terminal",a.node_id))),t.lifecycle!==void 0&&(n=n.filter(a=>a.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(a=>a.kind===t.kind)),t.mode!==void 0&&(n=n.filter(a=>a.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(a=>a.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(a=>a.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(a=>a.parent===t.parent)),t.top_level===!0&&(n=n.filter(a=>a.parent===null)),t.under!==void 0){const a=new Set(await ze(t.under));n=n.filter(c=>a.has(c.node_id))}t.hanging===!0&&(n=await Y(n,async a=>a.parent!==null&&await R(a.parent)===null));const o=t.include==="activity"?await qe(n.map(a=>a.node_id)):null,i=n.length>0?$e():new Set;return{status:200,body:await ye(n,async a=>{const c=await Hn(a,a.profile_id!==null&&i.has(a.profile_id));if(o!==null){const r=await ue(a.node_id);c.activity={latest_report:r[0]??null,final_report:a.final_report===null?null:r.find(l=>l.name===a.final_report)??null,pending_human_count:o[a.node_id]??0}}return c})}}s(St,"handleList");async function Rt(e){const t=e.params.id,n=await qn(e,t,{method:"GET",path:`/v1/nodes/${encodeURIComponent(t)}`,query:et(e)});if(n.kind==="unknown")throw tt(t,n.unreachable);if(n.kind==="remote"){if(n.status>=400)throw nt(n.status,n.body);return{status:n.status,body:it(n.body,n.machine)}}return await h(t),{status:200,body:await g(t)}}s(Rt,"handleDetail");async function Ot(e){const t=e.params.id;await h(t);const n=await cn(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.turnReplies===void 0?{}:{turnReplies:n.snapshot.turnReplies},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(i=>({name:i.name,description:i.description,source:i.source})),captured_at:B()}}}s(Ot,"handleSnapshot");async function It(e){const t=e.params.id,n=await un(t);if(n===null)throw E(`unknown node: ${t}`,{received:t});return{status:200,body:n}}s(It,"handleSubject");function At(e){for(const[d]of e.query)if(d!=="cursor"&&d!=="limit")throw w(`unknown messages query parameter: ${d}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw w("cursor must appear at most once");if(n.length>1)throw w("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const o=n[0],i=Number(o);if(!Number.isSafeInteger(i)||o==="")throw w("limit must be an integer from 1 through 500");return t.length===0?{limit:i}:{cursor:t[0],limit:i}}s(At,"parseMessagesQuery");async function $t(e){const t=e.params.id,n=await sn(t,At(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:B()}}}s($t,"handleMessages");async function Ct(e){const t=e.params.id;await h(t);const n=await ln(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:B()}}}s(Ct,"handleSession");async function Nt(e){const t=e.params.id;return await h(t),{status:200,body:{node_id:t,markdown:await fn(t)}}}s(Nt,"handleTranscript");async function Tt(e){const t=e.params.id;await h(t);const n=s(async(i,d)=>({node_id:i,label:(await R(i))?.name??i,dir:await de(i),self:d,files:await ut(i)}),"root"),o=await Y([await n(t,!0),...await ye(await ae(t),async i=>await n(i.node_id,!1))],async i=>await Pt(i.node_id,i.dir)||i.files>0);return{status:200,body:{node_id:t,roots:o}}}s(Tt,"handleContext");async function Pt(e,t){try{return on(await V(e),t)}catch(n){if(an(n))return!1;throw n}}s(Pt,"hasDir");async function Et(e){const t=await h(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,o=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(d=>I(n,d)),...n.filter(d=>I(t.scopes,d))])],i=await De(t.node_id,o,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:await g(i.node.node_id)}}s(Et,"handleFork");const Dt=1e4;async function Lt(e){const t=e.params.id;await h(t);const n=e.body,o=n?.resume??!0,i=n?.reopen??!1;await _n(t,i,e.principal.class==="broker"?e.principal.node:null);const d=!o&&n?.cron_id!==void 0?await pe(n.cron_id):null,a=await Pe(t,{resume:o,capacity:"refuse",...d!==null?{wakeReason:await zn(d,"schedule_revive")}:{}});a.outcome!=="already-live"&&await We(t,{failures:0,notBefore:null});const c=(await R(t))?.status??"active",r=(a.launch??P().get(t)?.handle)?.exited,l=a.outcome!=="frozen"&&await le(t,r,Dt);return{status:200,body:Qn(t,a,c,l)}}s(Lt,"handleRevive");async function Mt(e){const t=e.params.id;return{status:200,body:{newNodeId:(await yn(t))?.newNodeId??null}}}s(Mt,"handleRelaunchRoot");async function jt(e){const t=e.params.id;await h(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw w("caller_pid must be a positive integer when provided");const o=Jn(),i=new Promise(a=>{e.res.once("close",()=>a())}),d=await Te(t,{teardownAfter:i,rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...o===null?{}:{registerDetached:o.registerDetached}});return{status:200,body:Yn(d)}}s(jt,"handleClose");async function Gt(e){if(!Xn(e.principal))throw new u(403,"permission_error","only the person marks a conversation read");const t=e.params.id;return await h(t),await Je(t),{status:204}}s(Gt,"handleMarkRead");async function Ft(e){const t=e.params.id;await h(t);const n=await hn(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}s(Ft,"handleRecycle");async function Bt(e){const t=e.params.id;return await h(t),await x(t,{lifecycle:"terminal"}),await $(e,t,["lifecycle"]),{status:200,body:await g(t)}}s(Bt,"handleDemote");async function Kt(e,t={}){const n=e.params.id,o=await h(n),i=e.body??{};i.kind!==void 0&&await z(i.kind,o.cwd,o.profile_id??null),i.model!==void 0&&await ge(o,{kind:i.kind??o.kind,mode:"orchestrator",lifecycle:i.resident===!0?"resident":o.lifecycle,model:i.model},t.modelRegistry);const d=await mn(n,{...i.kind!==void 0?{kind:i.kind}:{},...i.resident===!0?{resident:!0}:{},...i.model!==void 0?{model:i.model}:{}});await $(e,n,["mode",...i.kind!==void 0?["kind"]:[],...i.resident===!0?["lifecycle"]:[],...i.model!==void 0?["model"]:[]]);const a=await J(d.meta,await H(n));return a.roadmap_written=d.roadmapWritten,a.roadmap_ref=d.roadmapRef,a.goal_path=d.goalPath,{status:200,body:a}}s(Kt,"handlePromote");async function Wt(e,t={}){const n=e.params.id,o=await h(n),i=e.body??{};i.kind!==void 0&&await z(i.kind,o.cwd,o.profile_id??null),i.model!==void 0&&await ge(o,{kind:i.kind??o.kind,mode:i.promote===!0?"orchestrator":o.mode,lifecycle:o.lifecycle,model:i.model},t.modelRegistry);const d=i.note??"Refresh: continue against your roadmap or goal.";await gn(n,d);const a=await wn(n,{...i.promote===!0?{promote:!0}:{},...i.kind!==void 0?{kind:i.kind}:{},...i.model!==void 0?{model:i.model}:{}});return{status:200,body:await J(a.meta,await H(n))}}s(Wt,"handleYield");async function Vt(e){const t=e.params.id;await h(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw w("a wait requires a controller node id");const o=await R(n.controller);if(o===null)throw E(`unknown controller: ${n.controller}`,{received:n.controller});if(o.status!=="active"&&o.status!=="idle")throw new u(422,"unprocessable",`controller ${n.controller} is ${o.status}`);return await xe(t,n.controller),{status:200,body:await g(t)}}s(Vt,"handleWait");async function xt(e){const t=e.principal,n=await pn(t.class==="broker"?async i=>i.grantee===t.app&&await U(t,i.node_id,i.grantee):void 0);return{status:200,body:{revived:[...n.revived],failed:[...n.failed],frozen:[...n.frozen]}}}s(xt,"handleReviveAll");const zt=new Set(["interrupt","steer","after-turn","next-turn"]);function Jt(e){if(e===null)return null;const t=s(o=>{throw new y({error:"invalid_listen",message:o,received:e,field:"listen",next:'Send an object mapping levels "1".."10" to interrupt|steer|after-turn|next-turn (e.g. {"3":"next-turn"}), or null to reset to the global default.'})},"bad");if(typeof e!="object"||Array.isArray(e))return t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[o,i]of n)/^(?:[1-9]|10)$/.test(o)||t(`listen level must be 1..10: ${o}`),(typeof i!="string"||!zt.has(i))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(i)}`);return JSON.stringify(Object.fromEntries(n))}s(Jt,"listenJson");async function $(e,t,n,o){n.length===0&&o===void 0||await W(async i=>{if(o?.(i),n.length===0)return;const d=await Ue(i,t),a=await Qe(i,e),c=a.class==="person"?a.person:a.class==="app"?a.app:a.node;await Ye(i,c,d),await He(i,{event:"configured",object:d,actor:c,attrs:{changed:n.join(",")}})})}s($,"recordConfigured");function ke(e){const t=P().get(e);if(t===void 0)return!1;try{return process.kill(t.pid,"SIGTERM"),!0}catch{return!1}}s(ke,"restartLiveBroker");function Se(e,t){try{return q(e)===q(t)}catch{return!1}}s(Se,"sameDirectory");async function Ut(e,t={}){const n=e.params.id,o=e.body;let i;if(o===void 0)i={};else if(typeof o=="object"&&o!==null&&!Array.isArray(o))i=o;else throw new y({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:o,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(i.profile!==void 0){if(typeof i.profile!="string"||i.profile==="")throw new y({error:"profile_invalid",message:"profile must be a non-empty profile id or name",received:i.profile,field:"profile",next:"Send a profile id or exact name."});if(Object.keys(i).some(m=>m!=="profile"&&m!=="restart"&&i[m]!==void 0))throw new y({error:"profile_not_exclusive",message:"profile can only be combined with restart",field:"profile",next:"Send profile (and optionally restart) alone."});const r=await h(n),l=await Wn(e,i.profile);Vn(l.profileId);const p=xn(l.profileId).manifest.grantee??"app:terminal";if(p!==(r.grantee??"app:terminal"))throw new y({error:"profile_grantee_mismatch",message:`profile ${l.profileId} belongs to ${p}, node ${n} to ${r.grantee}`,received:i.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(r.profile_id??null)!==l.profileId&&(Fn(r.kind)?(await z(r.kind,r.cwd,l.profileId),await x(n,{profileId:l.profileId})):await C(n,{profile_id:l.profileId}),await $(e,n,["profile"])),i.restart===!0&&ke(n),{status:200,body:await g(n)}}if(Object.prototype.hasOwnProperty.call(i,"cwd")){const r=i.cwd;if(typeof r!="string"||r==="")throw new y({error:"cwd_invalid",message:"cwd must be a non-empty string",received:r,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(i).some(f=>f!=="cwd"&&f!=="keep_session"&&f!=="restart"&&i[f]!==void 0))throw new y({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:i,field:"cwd",next:"Send cwd as the only config field."});const l=await h(n),p=N(l.cwd);if(i.keep_session===!0||p&&F(r)&&N(r)&&Se(l.cwd,r)){if(!F(r))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${r}`,received:r,field:"cwd",next:"Send an absolute path."});const f=T(r);let b=!1;try{b=ee(f).isDirectory()}catch{}if(!b)throw new y({error:"cwd_missing",message:`cwd is not an existing directory: ${f}`,received:r,field:"cwd",next:"Send an existing absolute directory."});if(p&&!Se(l.cwd,f))throw new y({error:"cwd_not_same_directory",message:`${f} is not the same directory as the recorded ${l.cwd}; --keep-session only relocates an alias`,received:r,field:"cwd",next:"Drop --keep-session to repair a gone cwd, or pass the real path of the recorded directory."});if(l.managed_worktree?.state==="open")throw new y({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot relocate its cwd`,received:r,field:"cwd",next:"Reconcile the managed worktree first."});const v=l.cwd;return v!==f&&(await W(async _=>{await C(n,{cwd:f}),await _.prepare("UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(f,n,v),await Xe(n,v,f)}),await $(e,n,["cwd"])),i.restart===!0&&ke(n),{status:200,body:await g(n)}}if(P().has(n)){const f=`${n} cannot repair its cwd while its broker is live`;throw new u(409,"cwd_node_live",f,{error:"cwd_node_live",message:f,received:r,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(l.fork_from!=null)throw new y({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${l.cwd}`,received:r,field:"cwd",next:`Restore ${l.cwd}, then revive the fork normally.`});if(l.managed_worktree?.state==="open")throw new y({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:r,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(N(l.cwd))throw new y({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${l.cwd}; cwd repair is not a relocation command`,received:r,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!F(r))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${r}`,received:r,field:"cwd",next:"Send an absolute path."});const m=T(r);if(!N(m))throw new y({error:"cwd_missing",message:`cwd does not exist: ${m}`,received:r,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!ee(m).isDirectory())throw new y({error:"cwd_not_a_directory",message:`cwd is not a directory: ${m}`,received:r,field:"cwd",next:"Send an existing absolute directory."})}catch(f){throw f instanceof y?f:new y({error:"cwd_missing",message:`cwd does not exist: ${m}`,received:r,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return await W(async()=>{await C(n,{cwd:m}),await Ze(n)}),await $(e,n,["cwd"]),{status:200,body:await g(n)}}let d=await h(n);const a=i.listen===void 0?void 0:Jt(i.listen);if(i.scopes!==void 0){const r=me(i.scopes),l=d.grantee==="app:terminal"?await dt():d.grant_id?await rt(d.grant_id):null,p=d.grantee==="app:terminal"&&!ct("user").runtime?.issuer;if(!r.every(m=>I(d.scopes,m)&&(l?I(l.resolved,m):p)))throw new y({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:r,field:"scopes",next:"Send only scopes the node currently holds."});if(r.includes("crtr:act")&&!I(r,"crtr:llm"))throw new u(400,"invalid_scope","crtr:act requires crtr:llm");d=await C(n,{scopes:r})}if(i.situational_context!==void 0&&Ce(n,Ne(i.situational_context)),i.model!==void 0){const r=(await se(d.cwd,d.profile_id??null)).modelLadders,l=On(i.model,r),p=await st(d.grant_id,i.model,l===void 0),m=p?{family:lt,strength:p.strength}:l,f=p?p.model:In(i.model,r);await K({kind:"concrete",spec:f},{cwd:d.cwd,profileId:d.profile_id??null},t.modelRegistry);const b=P();let v=!1;if(b.isClaimed(n)&&await le(n,b.get(n)?.handle.exited)&&(v=await Cn(n,f,m).then(()=>!0,_=>{if(_ instanceof Nn)return!1;throw _})),!v){if(b.isClaimed(n)){const _=`${n}'s broker did not accept the model switch; the model was not changed`;throw new u(409,"broker_not_ready",_,{error:"broker_not_ready",message:_,received:i.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!f.includes("/"))throw w(`model must resolve to a provider/id spec: ${i.model}`);await $n(n,f,m)}d=await h(n)}if(i.kind!==void 0||i.mode!==void 0||i.lifecycle!==void 0){i.kind!==void 0&&await Oe(i.kind);const r=i.kind??d.kind,l=i.mode??d.mode,p=i.lifecycle??d.lifecycle;let m;l==="orchestrator"&&!await kn(n)&&(m=s(async()=>{const f=await bn(n);await vn(n,f!==null&&f.trim()!==""?{goal:f.trim()}:{})},"beforePersist")),d=await x(n,{...i.kind!==void 0?{kind:r}:{},...i.mode!==void 0?{mode:l}:{},...i.lifecycle!==void 0?{lifecycle:p}:{}},m)}i.name!==void 0&&(d=await C(n,{name:i.name}),d.window&&Sn(d.window,Kn(d)));const c=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(r=>i[r]!==void 0);return await $(e,n,c,a===void 0?void 0:async r=>{await r.prepare("UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(a,n)}),{status:200,body:await g(n)}}s(Ut,"handleConfig");async function Re(){return(await se(process.cwd(),Ae()||null)).kinds}s(Re,"daemonKinds");async function Oe(e){const t=Object.keys(await Re());if(!t.includes(e))throw w(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}s(Oe,"assertKindServer");async function Yt(){const e=await Re();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}s(Yt,"handleListKinds");const wo=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:bt},{method:"GET",pattern:"/v1/nodes",handler:St},{method:"GET",pattern:"/v1/kinds",handler:s(()=>Yt(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:xt},{method:"GET",pattern:"/v1/nodes/:id",handler:Rt},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:Ot},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:It},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:$t},{method:"GET",pattern:"/v1/nodes/:id/session",handler:Ct},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:Nt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:Tt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:Et},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Lt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:Mt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:jt},{method:"POST",pattern:"/v1/nodes/:id/read",handler:Gt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:Ft},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Bt},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Kt},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Wt},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Vt},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Ut}];export{Ut as handleConfig,bt as handleCreate,Et as handleFork,St as handleList,Kt as handlePromote,Wt as handleYield,wo as nodeRoutes,_o as resolveCreateKind};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
content unavailable: ${r.unavailable}`,data:{...f,content:"markdown"in r?"live":"unavailable"}}})}l(et,"read");function Y(e,t,a,n){if(e!=null){if(!a.includes(e)){n.push({field:t,problem:`must be one of ${a.join(", ")}`,received:e});return}return e}}l(Y,"oneOf");async function be(e,t,a){if(t!=null){if(typeof t!="string"||!await De(e,t)){a.push({field:"type",problem:`must be a kind: one of ${(await Me(e)).join(", ")}`,received:t});return}return t}}l(be,"kindName");function je(e,t,a,n){if(e==null)return n;const i=Number(e);return!Number.isInteger(i)||i<1||i>100?(a.push({field:t,problem:"must be an integer from 1 to 100",received:e}),n):i}l(je,"limitOf");async function _e(e){const t=e.query,a=[],n=await be(await T(),t.get("type"),a),i=Y(t.get("privacy"),"privacy",Ae,a),o=je(t.get("limit"),"limit",a,50),r=t.get("cursor");r!==null&&!/^\d+$/.test(r)&&a.push({field:"cursor",problem:"is not a cursor from a previous page",received:r});const s=t.get("deleted");return s!==null&&!["0","1","true","false"].includes(s)&&a.push({field:"deleted",problem:"must be true or false",received:s}),a.length>0&&C("object list request",a),await _(async c=>{const u=await v(c,e),f={...n?{type:n}:{},...i?{privacy:i}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...s==="1"||s==="true"?{deleted:!0}:{}},h=t.get("owner");if(h!==null){const d=await he(c,u,h);if(d===null)return{items:[],next_cursor:null};f.owner=d}const g=t.get("name"),j=[];let m=r===null?0:Number(r),p=!0;for(;j.length<o&&p;){const d=await Ge(c,u,f,{limit:100,after_rowid:m});p=d.length===100;for(const E of d)if(m=E.rowid,(g===null||E.name.startsWith(g))&&j.push(E),j.length===o)break}const w=j.at(-1);return{items:await de(j,async d=>await me(c,d)),next_cursor:j.length===o&&w?String(w.rowid):null}})}l(_e,"listLocal");const tt={ms:3e4},nt="self",X=l((e,t)=>e.map(a=>({...a,machine:t})),"labelItems");async function ke(e,t,a,n){const i=S.current;try{const o=await i.call(t.id,{method:"GET",path:"/v1/objects",query:a},await i.envelope(e.principal),n);if(Ye(o))return{state:"unreachable",items:[],next:null};if(o.status===426)return{state:"too_old",items:[],next:null};const r=o.body;return o.status!==200||!Array.isArray(r?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:X(r.items,t),next:r.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}l(ke,"remotePage");async function at(e){const t=new Promise(a=>e.addEventListener("abort",()=>a(null),{once:!0}));return Promise.race([S.current.machines().catch(()=>null),t])}l(at,"machinesWithin");async function it(e){const t=e.query.get("machine");if(!le(e.principal)||!S.current.joined()||t===nt)return await _e(ve(e));const n=S.current.self(),i=t!==null&&A(t)!==n,o=i?null:await _e(ve(e)),r=new AbortController,s=setTimeout(()=>r.abort(),tt.ms);s.unref?.();try{const c=await at(r.signal);if(c===null){if(i)throw new y(503,"runtime_unreachable",`The directory did not answer, so ${A(t)} cannot be listed.`,{machine:A(t)});return o}const u=l(w=>({id:w,name:c.find(d=>d.machine_id===w)?.name??w}),"labelOf"),f=u(n),h=c.filter(w=>w.machine_id!==n&&w.kind!=="device"),g=B(e);if(t!==null){if(!i)return{items:X(o.items,f),next_cursor:o.next_cursor,machines:[{machine_id:n,name:f.name,state:"ok",more:o.next_cursor!==null}]};const w=A(t);if(!h.some(E=>E.machine_id===w))throw new y(404,"not_found",`no machine ${w} on your account`,{machine:w});const d=await ke(e,u(w),g,r.signal);return{items:d.items,next_cursor:d.next,machines:[{machine_id:w,name:u(w).name,state:d.state,more:d.next!==null}]}}const{cursor:j,...m}=g,p=await Promise.all(h.map(w=>ke(e,u(w.machine_id),m,r.signal)));return{items:[...X(o.items,f),...p.flatMap(w=>w.items)],next_cursor:o.next_cursor,machines:[{machine_id:n,name:f.name,state:"ok",more:o.next_cursor!==null},...h.map((w,d)=>({machine_id:w.machine_id,name:w.name,state:p[d].state,more:p[d].next!==null}))]}}finally{clearTimeout(s)}}l(it,"list");function ve(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}l(ve,"withoutMachine");async function rt(e){const t=[],a=I(e.body)?e.body:{};I(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const n=a.text;(typeof n!="string"||n.trim()==="")&&t.push({field:"text",problem:"is required",received:n});const i=a.grep;if(i!==void 0)if(typeof i!="string")t.push({field:"grep",problem:"must be a regular expression string",received:i});else try{new RegExp(i)}catch(s){t.push({field:"grep",problem:`is not a valid regular expression: ${s.message}`,received:i})}a.body!==void 0&&typeof a.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:a.body});const o=await be(await T(),a.type,t);a.kind!==void 0&&typeof a.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:a.kind}),a.owner!==void 0&&typeof a.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:a.owner});const r=je(a.limit,"limit",t,50);return t.length>0&&C("object search request",t),await _(async s=>{const c=await v(s,e),u=typeof a.owner=="string"?await he(s,c,a.owner):null;if(typeof a.owner=="string"&&u===null)return{items:[]};const f=await oe(s,c,{text:n,body:a.body===!0||typeof i=="string"}),h=new Set(f.map(m=>m.object.rowid)),j=(typeof i=="string"?(await oe(s,c,{text:i,grep:!0})).filter(m=>h.has(m.object.rowid)):f).filter(m=>(!o||m.object.type===o)&&(a.kind===void 0||m.object.kind===a.kind)&&(!u||m.object.owner===u.rowid));return{items:await de(j.slice(0,r),async m=>({object:await me(s,m.object),...m.line!==void 0?{matches:[{line:m.line,text:m.text??""}]}:{}}))}})}l(rt,"search");const Oe=["interrupt","steer","after-turn","next-turn"],ot=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function st(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(a=>typeof a!="string"||!ot.test(a)||a.includes(">")&&!a.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}l(st,"patternsOf");function ut(e,t){if(e===void 0)return;if(!I(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const a=[];for(const[n,i]of Object.entries(e)){const o=Number(n);!Number.isInteger(o)||o<1||o>10?t.push({field:`config.${n}`,problem:"level must be an integer from 1 to 10"}):Oe.includes(i)?a.push({threshold:o,delivery:i}):t.push({field:`config.${n}`,problem:`delivery must be one of ${Oe.join(", ")}`,received:i})}return a.sort((n,i)=>i.threshold-n.threshold)}l(ut,"configOf");async function Ee(e){const t=await ye(e);if(t!==null)throw new y(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}l(Ee,"refuseStubWatch");async function x(e,t){const a=await W(e,t)??await(async()=>{const n=await Ne(e,await Fe(e,{class:"person"},async()=>[]),t);return"object"in n?n.object:null})();return a===null||a.deleted_at!==null||!(a.type.includes(".")||a.type==="node")?null:a}l(x,"findWatcher");const O=l(()=>{throw new y(404,"not_found","watcher not found")},"watcherNotFound");async function Re(e,t,a){if(typeof t!="string"||a===void 0||a===null)return null;if(typeof a!="string")throw new y(400,"invalid_request","invalid watcher_machine");if(await x(e,t)!==null)return null;const n=S.current;let i;try{i=await n.machines()}catch{throw new y(503,"runtime_unreachable","The directory did not answer, so the watcher machine cannot be checked.")}const o=A(a);return(o===n.self()||!i.some(r=>A(r.machine_id)===o))&&O(),o}l(Re,"remoteWatcherMachine");async function qe(e,t,a,n){if(t.publishToken||t.principal.class==="anonymous")return O();const i=await v(e,t);if(i.class==="person")return O();let o;try{o=await R(e,i,n)}catch{return O()}const r=o.owner===null?null:await we(e,o.owner);return r===null||!await ae(e,i,r)||!await Pe(e,i,"link",a)?O():(await G(e,t,a),{actor:i.app,object:o})}l(qe,"linkWatcher");async function Te(e,t,a){if(t.publishToken)return!0;if(t.principal.class==="anonymous"||!a.type.includes("."))return!1;const n=await v(e,t),i=a.owner===null?null:await we(e,a.owner);return i!==null&&await ae(e,n,i)&&await Le(e,n,a)}l(Te,"ownsWatcher");async function ct(e){const t=k(e),a=I(e.body)?e.body:{};if(typeof a.watcher=="string"&&await Ee(t),typeof a.watcher!="string"){const i=await J(e,t,{method:"POST",path:`${Q(t)}/watch`,body:e.body});if(i.kind==="unknown")throw fe(t,i.unreachable);if(i.kind==="remote"){if(i.status>=400)throw D(i.status,i.body);const o=i.body.patterns;return await ge(e,i.body,i.machine.id,"ask",o),K(i.body,i.machine)}}const n=await Re(await T(),a.watcher,a.watcher_machine);return await lt(e,n)}l(ct,"watch");async function lt(e,t=null){const a=[],n=e.body===void 0?{}:I(e.body)?e.body:(a.push({field:"body",problem:"must be an object"}),{}),i=st(n.patterns,a),o=ut(n.config,a);return n.filter!==void 0&&!I(n.filter)&&a.push({field:"filter",problem:"must be an object",received:n.filter}),n.watcher!==void 0&&typeof n.watcher!="string"&&a.push({field:"watcher",problem:"must be a custom-object ref",received:n.watcher}),n.watcher_machine!==void 0&&typeof n.watcher_machine!="string"&&a.push({field:"watcher_machine",problem:"must be a machine id",received:n.watcher_machine}),a.length>0&&C("watch request",a),await _(async r=>{const s=typeof n.watcher=="string";if((e.publishToken||e.principal.class==="anonymous")&&!s)throw new y(404,"not_found","watcher not found");const c=i??[">"],u={patterns:c,...o?{config:o}:{},...n.filter!==void 0?{filter:n.filter}:{}};if(s){const j=n.watcher,m=t===null?null:await ft(r,e,j,t),p=m??(e.publishToken?await ie(r,j):await x(r,j));if(p===null)return O();if(m===null&&await Te(r,e,p)){const E=await re(r,e,p);await G(r,e,p);const ee=await M(r,p),q=await R(r,ee,k(e));if(!await ne(r,ee,q))throw new y(404,"not_found","object not found");return await L(r,p,q,"act",u),await P(r,p,q),await U(r,{event:"watched",object:q,actor:E,attrs:{}},await F(r)),{object:await $(r,q,await b(r,q)),patterns:c}}const{actor:w,object:d}=await qe(r,e,p,k(e));return await L(r,p,d,"act",{...u,linkApp:w}),await P(r,p,d),await U(r,{event:"watched",object:d,actor:w,attrs:{}},await F(r)),{object:await $(r,d,await b(r,d)),patterns:c}}const f=await v(r,e),h=await V(r,e)??te(f),g=await R(r,f,k(e));return await L(r,h,g,"ask",u),await P(r,h,g),await U(r,{event:"watched",object:g,actor:h,attrs:{}},await F(r)),{object:await $(r,g,await b(r,g)),patterns:c}})}l(lt,"watchLocal");async function ft(e,t,a,n){return t.publishToken||t.principal.class==="anonymous"?O():await Je(e,a,n)}l(ft,"ensureNodeStubFor");async function Ie(e,t,a,n){const i=l(async()=>(await e.prepare(`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.rowid = s.watch
|
|
3
|
-
WHERE w.watcher = ? AND w.object = ?`).get(t.
|
|
1
|
+
var Ne=Object.defineProperty;var l=(e,t)=>Ne(e,"name",{value:t,configurable:!0});import{ApiError as y}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as $e}from"../../../api/dto/objects.js";import{openDb as I,withCanvasWrite as _}from"../../../core/canvas/db.js";import{actorOf as te}from"../../../core/graph/documents.js";import{readerForObject as U,readerFor as Ae}from"../../../core/graph/reader.js";import{resolveName as Fe,stubsNamed as Se,unwrapRef as ne}from"../../../core/graph/names.js";import{canRead as ae,customReachable as We,holdsObjectsScope as Le,mayActAs as ie}from"../../../core/graph/access.js";import{customObjectRef as re,authorizeCustom as oe,fenceArgv as z}from"./custom-objects.js";import{edgesOf as Pe}from"../../../core/graph/edges.js";import{publish as H}from"../../../core/graph/events.js";import{objectDTO as g}from"../../../core/graph/kinds/dto.js";import{isKind as Ce,kindNames as De,kindOf as V}from"../../../core/graph/kinds/registry.js";import{listObjects as Me,searchObjects as se}from"../../../core/graph/objects.js";import{checkoutsForCwd as Ge}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as L,unwatch as Ue,watchersOf as ze,watchesOf as He}from"../../../core/graph/watches.js";import{armObjectWaitForWatch as P,settleObjectWaitForUnwatch as Ve}from"../../../core/graph/object-waits.js";import{readerFor as v,resolveRef as B}from"../reader.js";import{readDelegationFor as ue,runReadLeaf as Be}from"../../plugin-objects/read-leaf.js";import{invalidRequest as C,isRecord as N}from"./validate.js";import{callerNode as ce,callerStub as K,forwardNamed as Ke,forwardVerb as le,originates as fe,queryWithoutMachine as D,relayError as M,remoteStub as Ze,unknownError as de,forwarding as W,withMachine as Z}from"../../peer/forward.js";import{getById as E}from"../../../core/graph/objects.js";import{ensureNodeStub as Je,isStub as J,stubOf as Qe,withKindDecl as $}from"../../../core/peer/stubs.js";import{isUnreachable as Ye}from"../../../core/peer/client.js";import{normalizeMachineId as A}from"../../../core/peer/directory.js";import{mapAsync as we}from"../../../core/async-array.js";const F=l(async e=>async t=>await Ge(e,t),"reposFnFor");async function me(e,t){return{...await g(e,t),...await(await V(e,t.type)).listItem?.(e,t)}}l(me,"listItem");function Xe(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}l(Xe,"remoteMessage");async function he(e,t,a){try{return await T(e,t,a)}catch(n){if(n instanceof y&&n.code==="not_found"&&!n.details?.deleted)return null;throw n}}l(he,"ownerFilter");async function T(e,t,a){const n=await B(e,t,a);if("remote"in n)throw new y(404,"not_found",Xe(n.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in n)throw new y(404,"not_found",`${n.deleted.name} is deleted`,{id:n.deleted.id,deleted:!0});return n}l(T,"liveRef");const k=l(e=>decodeURIComponent(e.params.ref),"refParam"),pe=l(e=>{const t=ne(e),a=t.indexOf("/");return a>0?t.slice(0,a):t},"idOf");async function ye(e){const t=await E(await I(),pe(e));return t!==null&&await J(await I(),t)?t.id:null}l(ye,"stubIdOf");async function xe(e,t){const a=await ye(e);return a!==null?{stub:a,hit:!0}:await _(async n=>{try{const i=await v(n,t),o=l(async()=>{const s=await Se(n,i,e);if(s.length>1)throw new y(409,"ambiguous_name",`'${e}' names more than one remote object`,{candidates:s.map(c=>c.id),next:"Read one by its object id."});return{stub:s[0]?.id??null,hit:!1}},"named");let r;try{r=await B(n,i,e)}catch(s){if(s instanceof y&&s.code==="not_found")return await o();throw s}if("remote"in r)return await o();if("deleted"in r){const s=await o();return s.stub===null?{stub:null,hit:!0}:s}return{stub:await J(n,r)?r.id:null,hit:!0}}catch(i){if(i instanceof y&&i.code==="ambiguous_name")throw i;return{stub:null,hit:!1}}})}l(xe,"resolvedLocally");async function Q(e,t,a){const n=await xe(t,e);if(n.stub!==null)return le(e,n.stub,a);if(n.hit||!fe(e.principal))return{kind:"local"};const i=await le(e,pe(t),a);return i.kind==="local"&&ne(t).includes("/")?Ke(e,a,{method:"GET",path:G(t),query:D(e)}):i}l(Q,"forwardRef");const G=l(e=>`/v1/objects/${encodeURIComponent(e)}`,"objectPath");async function be(e,t,a,n,i){const o=t?.object;!o?.id||!o.type||await _(async r=>{const s=await ce(r,e);if(s===null)return;const c=await Ze(r,o.id,o.type,a,{kind:o.kind??null,name:o.name??o.id,...o.preview===void 0?{}:{preview:o.preview},owner:o.owner??null,...o.kind_decl===void 0?{}:{kind_decl:o.kind_decl},...o.privacy===void 0?{}:{privacy:o.privacy}});await L(r,s,c,n,i===void 0?{}:{patterns:i}),n==="ask"&&await P(r,s,c)})}l(be,"watchRemote");async function et(e){const t=k(e),a=["1","true"].includes(e.query.get("fields")??""),n=await Q(e,t,{method:"GET",path:G(t),query:D(e)});if(n.kind==="unknown")return{state:"unknown",ref:t,unreachable:n.unreachable};if(n.kind==="remote"){if(n.status>=400)throw M(n.status,n.body);return await be(e,n.body,n.machine.id,"read"),Z(n.body,n.machine)}const i=l(async s=>{const c=await K(s,e);return c===null?await v(s,e):await U(s,c,await F(s))},"readerOf"),o=await _(async s=>{const c=await i(s),u=await B(s,c,t);if("remote"in u)return{state:"remote",remote:u.remote};if("deleted"in u)return{state:"deleted",deleted:await g(s,u.deleted)};const f=await ue(s,u);if(f!==null)return{delegate:f,hitId:u.id};const{data:h,text:b}=await(await V(s,u.type)).read(s,c,u,{fields:a,reposFn:await F(s)});return{state:"object",type:u.type,object:await $(s,u,await g(s,u)),text:b,data:h}});if(!("delegate"in o))return o;const r=await Be(o.delegate,e.principal);return await _(async s=>{const c=await i(s),u=await E(s,o.hitId);if(u===null)throw new y(404,"not_found","object not found");if(u.deleted_at!==null)return{state:"deleted",deleted:await g(s,u)};if(!await ae(s,c,u))throw new y(404,"not_found","object not found");const{data:f,text:h}=await(await V(s,u.type)).read(s,c,u,{fields:a,reposFn:await F(s)});return await ue(s,u)===null?{state:"object",type:u.type,object:await $(s,u,await g(s,u)),text:h,data:f}:{state:"object",type:u.type,object:await $(s,u,await g(s,u)),text:"markdown"in r?r.markdown:`${h}
|
|
2
|
+
content unavailable: ${r.unavailable}`,data:{...f,content:"markdown"in r?"live":"unavailable"}}})}l(et,"read");function Y(e,t,a,n){if(e!=null){if(!a.includes(e)){n.push({field:t,problem:`must be one of ${a.join(", ")}`,received:e});return}return e}}l(Y,"oneOf");async function ge(e,t,a){if(t!=null){if(typeof t!="string"||!await Ce(e,t)){a.push({field:"type",problem:`must be a kind: one of ${(await De(e)).join(", ")}`,received:t});return}return t}}l(ge,"kindName");function je(e,t,a,n){if(e==null)return n;const i=Number(e);return!Number.isInteger(i)||i<1||i>100?(a.push({field:t,problem:"must be an integer from 1 to 100",received:e}),n):i}l(je,"limitOf");async function _e(e){const t=e.query,a=[],n=await ge(await I(),t.get("type"),a),i=Y(t.get("privacy"),"privacy",$e,a),o=je(t.get("limit"),"limit",a,50),r=t.get("cursor");r!==null&&!/^\d+$/.test(r)&&a.push({field:"cursor",problem:"is not a cursor from a previous page",received:r});const s=t.get("deleted");return s!==null&&!["0","1","true","false"].includes(s)&&a.push({field:"deleted",problem:"must be true or false",received:s}),a.length>0&&C("object list request",a),await _(async c=>{const u=await v(c,e),f={...n?{type:n}:{},...i?{privacy:i}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...s==="1"||s==="true"?{deleted:!0}:{}},h=t.get("owner");if(h!==null){const w=await he(c,u,h);if(w===null)return{items:[],next_cursor:null};f.owner=w}const b=t.get("name"),j=[];let m=r===null?0:Number(r),p=!0;for(;j.length<o&&p;){const w=await Me(c,u,f,{limit:100,after_seq:m});p=w.length===100;for(const q of w)if(m=q.seq,(b===null||q.name.startsWith(b))&&j.push(q),j.length===o)break}const d=j.at(-1);return{items:await we(j,async w=>await me(c,w)),next_cursor:j.length===o&&d?String(d.seq):null}})}l(_e,"listLocal");const tt={ms:3e4},nt="self",X=l((e,t)=>e.map(a=>({...a,machine:t})),"labelItems");async function ke(e,t,a,n){const i=W.current;try{const o=await i.call(t.id,{method:"GET",path:"/v1/objects",query:a},await i.envelope(e.principal),n);if(Ye(o))return{state:"unreachable",items:[],next:null};if(o.status===426)return{state:"too_old",items:[],next:null};const r=o.body;return o.status!==200||!Array.isArray(r?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:X(r.items,t),next:r.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}l(ke,"remotePage");async function at(e){const t=new Promise(a=>e.addEventListener("abort",()=>a(null),{once:!0}));return Promise.race([W.current.machines().catch(()=>null),t])}l(at,"machinesWithin");async function it(e){const t=e.query.get("machine");if(!fe(e.principal)||!W.current.joined()||t===nt)return await _e(ve(e));const n=W.current.self(),i=t!==null&&A(t)!==n,o=i?null:await _e(ve(e)),r=new AbortController,s=setTimeout(()=>r.abort(),tt.ms);s.unref?.();try{const c=await at(r.signal);if(c===null){if(i)throw new y(503,"runtime_unreachable",`The directory did not answer, so ${A(t)} cannot be listed.`,{machine:A(t)});return o}const u=l(d=>({id:d,name:c.find(w=>w.machine_id===d)?.name??d}),"labelOf"),f=u(n),h=c.filter(d=>d.machine_id!==n&&d.kind!=="device"),b=D(e);if(t!==null){if(!i)return{items:X(o.items,f),next_cursor:o.next_cursor,machines:[{machine_id:n,name:f.name,state:"ok",more:o.next_cursor!==null}]};const d=A(t);if(!h.some(q=>q.machine_id===d))throw new y(404,"not_found",`no machine ${d} on your account`,{machine:d});const w=await ke(e,u(d),b,r.signal);return{items:w.items,next_cursor:w.next,machines:[{machine_id:d,name:u(d).name,state:w.state,more:w.next!==null}]}}const{cursor:j,...m}=b,p=await Promise.all(h.map(d=>ke(e,u(d.machine_id),m,r.signal)));return{items:[...X(o.items,f),...p.flatMap(d=>d.items)],next_cursor:o.next_cursor,machines:[{machine_id:n,name:f.name,state:"ok",more:o.next_cursor!==null},...h.map((d,w)=>({machine_id:d.machine_id,name:d.name,state:p[w].state,more:p[w].next!==null}))]}}finally{clearTimeout(s)}}l(it,"list");function ve(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}l(ve,"withoutMachine");async function rt(e){const t=[],a=N(e.body)?e.body:{};N(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const n=a.text;(typeof n!="string"||n.trim()==="")&&t.push({field:"text",problem:"is required",received:n});const i=a.grep;if(i!==void 0)if(typeof i!="string")t.push({field:"grep",problem:"must be a regular expression string",received:i});else try{new RegExp(i)}catch(s){t.push({field:"grep",problem:`is not a valid regular expression: ${s.message}`,received:i})}a.body!==void 0&&typeof a.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:a.body});const o=await ge(await I(),a.type,t);a.kind!==void 0&&typeof a.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:a.kind}),a.owner!==void 0&&typeof a.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:a.owner});const r=je(a.limit,"limit",t,50);return t.length>0&&C("object search request",t),await _(async s=>{const c=await v(s,e),u=typeof a.owner=="string"?await he(s,c,a.owner):null;if(typeof a.owner=="string"&&u===null)return{items:[]};const f=await se(s,c,{text:n,body:a.body===!0||typeof i=="string"}),h=new Set(f.map(m=>m.object.id)),j=(typeof i=="string"?(await se(s,c,{text:i,grep:!0})).filter(m=>h.has(m.object.id)):f).filter(m=>(!o||m.object.type===o)&&(a.kind===void 0||m.object.kind===a.kind)&&(!u||m.object.owner===u.id));return{items:await we(j.slice(0,r),async m=>({object:await me(s,m.object),...m.line!==void 0?{matches:[{line:m.line,text:m.text??""}]}:{}}))}})}l(rt,"search");const Oe=["interrupt","steer","after-turn","next-turn"],ot=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function st(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(a=>typeof a!="string"||!ot.test(a)||a.includes(">")&&!a.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}l(st,"patternsOf");function ut(e,t){if(e===void 0)return;if(!N(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const a=[];for(const[n,i]of Object.entries(e)){const o=Number(n);!Number.isInteger(o)||o<1||o>10?t.push({field:`config.${n}`,problem:"level must be an integer from 1 to 10"}):Oe.includes(i)?a.push({threshold:o,delivery:i}):t.push({field:`config.${n}`,problem:`delivery must be one of ${Oe.join(", ")}`,received:i})}return a.sort((n,i)=>i.threshold-n.threshold)}l(ut,"configOf");async function qe(e){const t=await ye(e);if(t!==null)throw new y(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}l(qe,"refuseStubWatch");async function x(e,t){const a=await E(e,t)??await(async()=>{const n=await Fe(e,await Ae(e,{class:"person"},async()=>[]),t);return"object"in n?n.object:null})();return a===null||a.deleted_at!==null||!(a.type.includes(".")||a.type==="node")?null:a}l(x,"findWatcher");const O=l(()=>{throw new y(404,"not_found","watcher not found")},"watcherNotFound");async function Ee(e,t,a){if(typeof t!="string"||a===void 0||a===null)return null;if(typeof a!="string")throw new y(400,"invalid_request","invalid watcher_machine");if(await x(e,t)!==null)return null;const n=W.current;let i;try{i=await n.machines()}catch{throw new y(503,"runtime_unreachable","The directory did not answer, so the watcher machine cannot be checked.")}const o=A(a);return(o===n.self()||!i.some(r=>A(r.machine_id)===o))&&O(),o}l(Ee,"remoteWatcherMachine");async function Te(e,t,a,n){if(t.publishToken||t.principal.class==="anonymous")return O();const i=await v(e,t);if(i.class==="person")return O();let o;try{o=await T(e,i,n)}catch{return O()}const r=o.owner===null?null:await E(e,o.owner);return r===null||!await ie(e,i,r)||!await Le(e,i,"link",a)?O():(await z(e,t,a),{actor:i.app,object:o})}l(Te,"linkWatcher");async function Re(e,t,a){if(t.publishToken)return!0;if(t.principal.class==="anonymous"||!a.type.includes("."))return!1;const n=await v(e,t),i=a.owner===null?null:await E(e,a.owner);return i!==null&&await ie(e,n,i)&&await We(e,n,a)}l(Re,"ownsWatcher");async function ct(e){const t=k(e),a=N(e.body)?e.body:{};if(typeof a.watcher=="string"&&await qe(t),typeof a.watcher!="string"){const i=await Q(e,t,{method:"POST",path:`${G(t)}/watch`,body:e.body});if(i.kind==="unknown")throw de(t,i.unreachable);if(i.kind==="remote"){if(i.status>=400)throw M(i.status,i.body);const o=i.body.patterns;return await be(e,i.body,i.machine.id,"ask",o),Z(i.body,i.machine)}}const n=await Ee(await I(),a.watcher,a.watcher_machine);return await lt(e,n)}l(ct,"watch");async function lt(e,t=null){const a=[],n=e.body===void 0?{}:N(e.body)?e.body:(a.push({field:"body",problem:"must be an object"}),{}),i=st(n.patterns,a),o=ut(n.config,a);return n.filter!==void 0&&!N(n.filter)&&a.push({field:"filter",problem:"must be an object",received:n.filter}),n.watcher!==void 0&&typeof n.watcher!="string"&&a.push({field:"watcher",problem:"must be a custom-object ref",received:n.watcher}),n.watcher_machine!==void 0&&typeof n.watcher_machine!="string"&&a.push({field:"watcher_machine",problem:"must be a machine id",received:n.watcher_machine}),a.length>0&&C("watch request",a),await _(async r=>{const s=typeof n.watcher=="string";if((e.publishToken||e.principal.class==="anonymous")&&!s)throw new y(404,"not_found","watcher not found");const c=i??[">"],u={patterns:c,...o?{config:o}:{},...n.filter!==void 0?{filter:n.filter}:{}};if(s){const j=n.watcher,m=t===null?null:await ft(r,e,j,t),p=m??(e.publishToken?await re(r,j):await x(r,j));if(p===null)return O();if(m===null&&await Re(r,e,p)){const q=await oe(r,e,p);await z(r,e,p);const ee=await U(r,p),R=await T(r,ee,k(e));if(!await ae(r,ee,R))throw new y(404,"not_found","object not found");return await L(r,p,R,"act",u),await P(r,p,R),await H(r,{event:"watched",object:R,actor:q,attrs:{}},await F(r)),{object:await $(r,R,await g(r,R)),patterns:c}}const{actor:d,object:w}=await Te(r,e,p,k(e));return await L(r,p,w,"act",{...u,linkApp:d}),await P(r,p,w),await H(r,{event:"watched",object:w,actor:d,attrs:{}},await F(r)),{object:await $(r,w,await g(r,w)),patterns:c}}const f=await v(r,e),h=await K(r,e)??te(f),b=await T(r,f,k(e));return await L(r,h,b,"ask",u),await P(r,h,b),await H(r,{event:"watched",object:b,actor:h,attrs:{}},await F(r)),{object:await $(r,b,await g(r,b)),patterns:c}})}l(lt,"watchLocal");async function ft(e,t,a,n){return t.publishToken||t.principal.class==="anonymous"?O():await Je(e,a,n)}l(ft,"ensureNodeStubFor");async function Ie(e,t,a,n){const i=l(async()=>(await e.prepare(`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.watch_id = s.watch
|
|
3
|
+
WHERE w.watcher = ? AND w.object = ?`).get(t.id,a.id)).n,"count"),o=await i();await Ue(e,t,a,n??void 0);const r=await i();return r===0&&await Ve(e,t,a),{object:await g(e,a),removed:o-r}}l(Ie,"dropWatch");async function dt(e){const t=k(e);if(e.query.get("watcher")&&await qe(t),!e.query.get("watcher")){const n=await Q(e,t,{method:"DELETE",path:`${G(t)}/watch`,query:D(e)});if(n.kind==="unknown")throw de(t,n.unreachable);if(n.kind==="remote"){const i=n.status===404?n.body.error?.details:void 0,o=i?.deleted===!0?i.id:void 0;if(n.status>=400&&o===void 0)throw M(n.status,n.body);const r=o??n.body.object?.id,s=await _(async c=>{const u=await ce(c,e),f=r===void 0?null:await E(c,r);return u===null||f===null||!await J(c,f)?null:await Ie(c,u,f,e.query.get("pattern"))});if(o!==void 0){if(s===null)throw M(n.status,n.body);return{...s,machine:n.machine}}return Z(n.body,n.machine)}}const a=await Ee(await I(),e.query.get("watcher")??void 0,e.query.get("watcher_machine")??void 0);return await wt(e,a)}l(dt,"unwatchRoute");async function wt(e,t=null){const a=e.query.get("pattern"),n=e.query.get("watcher");return await _(async i=>{if((e.publishToken||e.principal.class==="anonymous")&&!n)throw new y(404,"not_found","watcher not found");const o=l(async(c,u)=>await Ie(i,c,u,a),"drop");if(n){const c=t===null?null:await(async()=>{const f=await E(i,n);return f!==null&&await Qe(i,f)!==null?f:null})();if(t!==null&&c===null)return O();const u=c??(e.publishToken?await re(i,n):await x(i,n));return u===null?O():c===null&&await Re(i,e,u)?(await oe(i,e,u),await z(i,e,u),await o(u,await T(i,await U(i,u),k(e)))):await o(u,(await Te(i,e,u,k(e))).object)}const r=await v(i,e),s=await K(i,e)??te(r);return await o(s,await T(i,r,k(e)))})}l(wt,"unwatchLocal");async function mt(e){const t=[],a=Y(e.query.get("type"),"type",["acted-on","links-to","watches"],t),n=Y(e.query.get("direction"),"direction",["out","in"],t);return t.length>0&&C("edges request",t),await _(async i=>{const o=await v(i,e),r=await T(i,o,k(e)),s=[];if(a!=="watches")for(const c of await Pe(i,o,r,{...a?{type:a}:{},direction:n??"both"}))s.push({type:c.type,src:await g(i,c.src),dst:await g(i,c.dst),...c.written_as?{written_as:c.written_as}:{}});if(a===void 0||a==="watches"){const c=[...n!=="in"?await He(i,o,r):[],...n!=="out"?await ze(i,o,r):[]];for(const u of c)s.push({type:"watches",src:await g(i,u.watcher),dst:await g(i,u.object)})}return{items:s}})}l(mt,"edges");const S=l(e=>async t=>({status:200,body:await e(t)}),"ok"),Gt=[{method:"POST",pattern:"/v1/objects/search",handler:S(rt)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:S(mt)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:S(ct)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:S(dt)},{method:"GET",pattern:"/v1/objects/:ref",handler:S(et)},{method:"GET",pattern:"/v1/objects",handler:S(it)}];export{tt as listBudget,Gt as objectRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var k=Object.defineProperty;var s=(t,e)=>k(t,"name",{value:e,configurable:!0});import{ApiError as m}from"../../../api/index.js";import{withCanvasWrite as R}from"../../../core/canvas/db.js";import{isSafeNodeId as p}from"../../../core/canvas/paths.js";import{readDocument as q}from"../../../core/graph/documents.js";import{
|
|
1
|
+
var k=Object.defineProperty;var s=(t,e)=>k(t,"name",{value:e,configurable:!0});import{ApiError as m}from"../../../api/index.js";import{withCanvasWrite as R}from"../../../core/canvas/db.js";import{isSafeNodeId as p}from"../../../core/canvas/paths.js";import{readDocument as q}from"../../../core/graph/documents.js";import{getById as E}from"../../../core/graph/objects.js";import{checkoutsForCwd as S}from"../../../core/graph/repo-sync/repos.js";import{getNode as b}from"../../../core/canvas/canvas.js";import{assertScope as T}from"../../../core/scopes.js";import{createReview as $}from"../../../core/review/birth.js";import{readAnchorBase as C,listReviews as I,requireVisibleReview as y}from"../../../core/review/store.js";import{cancelReview as D,submitReviewApproval as A}from"../../review/finish.js";import{toFeedbackResultDTO as O,toReviewDTO as F}from"../map.js";import{readerFor as L,resolveRef as B}from"../reader.js";import{canReadNode as N}from"../router.js";import{invalidRequest as P,objectBody as v,optionalString as c,requireParam as j,requiredString as g}from"./validate.js";import{filterAsync as G}from"../../../core/async-array.js";const V=new Set(["open","approved","canceled"]),W=["origin_kind","origin_node_id","document","file","idempotency_key","subtitle","output_path"],K=["reason","actor","disposition"];function l(t){P("review request",t)}s(l,"invalidRequest");function h(t,e){return j(t,"review_id","must be a safe review id",p,e)}s(h,"requireReviewId");function f(t){return{...F(t,t.state==="approved"?{result_path:`${t.review_dir}/result.json`}:{}),review_dir:t.review_dir}}s(f,"toReviewResponseDTO");function M(t){const e=[],n=v(t.body,W,e),o=n.origin_kind,i=o==="ticket"||o==="inline"?o:void 0;i===void 0&&e.push({field:"origin_kind",problem:"must be ticket or inline",...o===void 0?{}:{received:o}});const r=g(n,"origin_node_id",e);r!==void 0&&!p(r)&&e.push({field:"origin_node_id",problem:"must be a safe node id",received:r});const d=c(n,"document",e),u=c(n,"file",e);i==="ticket"&&(d===void 0||u!==void 0)&&e.push({field:"document",problem:"is required for ticket reviews, and file is not allowed"}),i==="inline"&&u===void 0==(d===void 0)&&e.push({field:"file",problem:"inline reviews take exactly one of file or document"});const a=g(n,"idempotency_key",e);a!==void 0&&a.length>128&&e.push({field:"idempotency_key",problem:"must be at most 128 characters",received:a});const w=c(n,"subtitle",e),_=c(n,"output_path",e);return i==="ticket"&&w===void 0&&n.subtitle===void 0&&e.push({field:"subtitle",problem:"is required for ticket reviews"}),i==="inline"&&n.subtitle!==void 0&&e.push({field:"subtitle",problem:"is only allowed for ticket reviews",received:n.subtitle}),i==="inline"&&n.output_path!==void 0&&e.push({field:"output_path",problem:"is only allowed for ticket reviews",received:n.output_path}),(e.length>0||i===void 0||r===void 0||!p(r)||a===void 0||a.length>128)&&l(e),{origin_kind:i,origin_node_id:r,...d===void 0?{}:{document:d},...u===void 0?{}:{file:u},idempotency_key:a,...w===void 0?{}:{subtitle:w},..._===void 0?{}:{output_path:_}}}s(M,"parseCreate");function x(t){const e=[],n={},o=new Set(["state","origin_node_id","file"]);for(const[i,r]of t.query.entries())o.has(i)||e.push({field:i,problem:"is not allowed",received:r});for(const i of o){const r=t.query.getAll(i);if(r.length>1){e.push({field:i,problem:"must appear at most once",received:r});continue}const d=r[0];d!==void 0&&(i==="state"?V.has(d)?n.state=d:e.push({field:i,problem:"must be open, approved, or canceled",received:d}):i==="origin_node_id"?p(d)?n.origin_node_id=d:e.push({field:i,problem:"must be a safe node id",received:d}):d===""?e.push({field:i,problem:"must be a non-empty string",received:d}):n.file=d)}return e.length>0&&l(e),n}s(x,"parseList");function z(t,e){const n=t.body===void 0?{}:v(t.body,K,e),o=c(n,"reason",e),i=c(n,"actor",e),r=c(n,"disposition",e);return r!==void 0&&r!=="canceled"&&r!=="dismissed"&&e.push({field:"disposition",problem:'must be "canceled" or "dismissed"',received:r}),{...o===void 0?{}:{reason:o},...i===void 0?{}:{actor:i},...r==="canceled"||r==="dismissed"?{disposition:r}:{}}}s(z,"parseCancel");function H(t,e){v(t.body,[],e)}s(H,"requireEmptyBody");async function J(t){const e=M(t),n=await b(e.origin_node_id);n!==null&&T(n,"crtr:act");const{document:o,file:i,...r}=e,d=await $({...r,...o===void 0?{file:i??""}:{document:await Q(t,o)}});return{status:200,body:f(d)}}s(J,"handleCreate");async function Q(t,e){return await R(async n=>{const o=await L(n,t),i=await B(n,o,e);if("remote"in i)throw new m(404,"not_found",`no document named ${i.remote} on this runtime`,{next:"Check the name with `crtr canvas search`."});if("deleted"in i)throw new m(404,"not_found",`${i.deleted.name} is deleted`,{id:i.deleted.id,deleted:!0});if(i.type!=="document")throw new m(400,"invalid_request",`${e} is a ${i.type}, not a document`);const r=await q(n,o,i,async a=>await S(n,a));if(r.needsMerge)throw new m(409,"needs_merge",`${i.name} has ${r.heads.length} heads; merge them before a review`,{id:i.id,next:`Read it with \`crtr canvas read ${i.id}\` and write the merged body with \`crtr doc edit\`.`});const d=i.owner===null?null:await E(n,i.owner),u=d===null?"":d.type==="node"?d.id:d.name;return{id:i.id,name:u===""?i.name:`${u}/${i.name}`,base:r.record.heads_key,body:r.heads[0].body}})}s(Q,"reviewedDocument");async function U(t){const e=x(t);return{status:200,body:{reviews:(await G(await I(e),async o=>{if(t.principal.class==="person")return!0;const i=await b(o.origin_node_id);return i!==null&&await N(t.principal,i.grantee??"app:terminal",i.node_id)})).map(f)}}}s(U,"handleList");async function X(t){const e=[],n=h(t,e);return(e.length>0||n===void 0)&&l(e),{status:200,body:f(await y(n))}}s(X,"handleRead");async function Y(t){const e=[],n=h(t,e);H(t,e),(e.length>0||n===void 0)&&l(e);const o=await A(n);return{status:200,body:o.outcome==="awaiting_companion"?{review:f(o.record),outcome:o.outcome}:{review:f(o.record),result:O(o.result),outcome:o.outcome}}}s(Y,"handleSubmit");async function Z(t){const e=[],n=h(t,e),o=z(t,e);(e.length>0||n===void 0)&&l(e);const i=await D(n,o);return{status:200,body:{review:f(i.record),outcome:i.outcome}}}s(Z,"handleCancel");async function ee(t){const e=[],n=h(t,e);(e.length>0||n===void 0)&&l(e);const o=await y(n),i=await C(o.review_id);if(i===null)throw new Error(`review anchor base is missing: ${o.review_id}`);return{status:200,body:{review_id:o.review_id,anchor_base_sha256:i.sha256,anchor_base_text:new TextDecoder("utf-8",{fatal:!0}).decode(i.bytes),file:o.file}}}s(ee,"handleDocument");const _e=[{method:"POST",pattern:"/v1/human/reviews",scope:"crtr:act",handler:J},{method:"GET",pattern:"/v1/human/reviews",handler:U},{method:"GET",pattern:"/v1/human/reviews/:review_id",handler:X},{method:"POST",pattern:"/v1/human/reviews/:review_id/submit",handler:Y},{method:"POST",pattern:"/v1/human/reviews/:review_id/cancel",handler:Z},{method:"GET",pattern:"/v1/human/reviews/:review_id/document",handler:ee}];export{M as parseCreate,_e as reviewRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var A=Object.defineProperty;var s=(t,e)=>A(t,"name",{value:e,configurable:!0});import{isSafeNodeId as S}from"../../../core/canvas/paths.js";import{admitStructuredRequest as D,bindStructuredRequest as T,getPendingStructuredRequestForNode as j,getStructuredRequest as l,settleStructuredRequest as _,toStructuredRequestDTO as f}from"../../../core/canvas/structured-requests.js";import{getNode as k}from"../../../core/canvas/canvas.js";import{CanvasConstraintError as N}from"../../../core/canvas/db.js";import{ApiError as $}from"../../../api/errors.js";import{handleCreate as C}from"./nodes.js";import{handleMessage as x}from"./messages.js";import{outputSchemaProblem as E,writeStructuredRequestSidecar as v}from"../../../core/runtime/structured-output.js";import{requestBrokerTeardown as F}from"../../../core/runtime/host.js";import{transition as M}from"../../../core/runtime/lifecycle.js";import{subscribeStructuredRequest as B}from"../../structured-requests/notifier.js";import{SYNC_WORK_BUDGET_MS as R}from"../../../api/index.js";import{waitSeconds as G}from"../long-poll-wait.js";function n(t,e,r){throw new $(t,e,r)}s(n,"fail");function I(t){(typeof t!="object"||t===null||Array.isArray(t))&&n(400,"invalid_request","a structured request requires a JSON object");const e=t;(typeof e.request_id!="string"||!S(e.request_id))&&n(400,"request_id_invalid","request_id must use the node-id character rule"),e.mode!=="sync"&&e.mode!=="async"&&n(400,"invalid_request","mode must be sync or async"),typeof e.prompt!="string"&&n(400,"invalid_request","prompt must be a string"),(typeof e.output_schema!="object"||e.output_schema===null||Array.isArray(e.output_schema))&&n(400,"invalid_request","output_schema must be a JSON Schema object");const r=e.target;(typeof r!="object"||r===null)&&n(400,"invalid_request","target is required");const a=r;if(a.kind==="node")(typeof a.node_id!="string"||!S(a.node_id))&&n(400,"invalid_request","target.node_id must use the node-id character rule");else if(a.kind==="new"){(typeof a.create!="object"||a.create===null||Array.isArray(a.create))&&n(400,"invalid_request","target.create must be an object");for(const i of["prompt","output_schema","deadline","root_lifecycle","no_kickoff"])Object.hasOwn(a.create,i)&&n(400,"create_field_forbidden",`target.create may not carry ${i}`)}else n(400,"invalid_request","target.kind must be new or node");return e.work_budget_ms!==void 0&&(!Number.isInteger(e.work_budget_ms)||e.work_budget_ms<=0)&&n(400,"work_budget_invalid","work_budget_ms must be a positive integer"),e.deadline_at!==void 0&&(typeof e.deadline_at!="string"||Number.isNaN(Date.parse(e.deadline_at)))&&n(400,"invalid_request","deadline_at must be an ISO timestamp"),e}s(I,"parseCreate");function J(t,e){const r=t.deadline_at===void 0?null:Date.parse(t.deadline_at),a=t.work_budget_ms===void 0?null:e+t.work_budget_ms,i=r===null?a:a===null?r:Math.min(r,a);return t.mode==="sync"?Math.min(i??e+R,e+R):i}s(J,"deadlineFor");function O(t,e,r=""){return{...t,method:"POST",path:"",params:r===""?{}:{id:r},query:new URLSearchParams,body:e}}s(O,"context");async function w(t){return{status:200,body:{admitted:!0,request:f(t)}}}s(w,"terminalAdmission");function m(t){return t!==null&&Date.now()>=t}s(m,"deadlinePassed");async function p(t){return await w((await _(t,{intended:"expired"})).row)}s(p,"expireAdmission");async function P(t,e){let r;const a=new Promise(u=>{r=u}),i=B(t,r);try{return(await l(t)).state==="pending"&&e>0&&await Promise.race([a,new Promise(q=>setTimeout(q,e))]),f(await l(t))}finally{i()}}s(P,"waitForRequest");async function L(t,e){const r=await P(t,Math.max(0,e-Date.now()));return r.state==="pending"?f((await _(t,{intended:"expired"})).row):r}s(L,"waitForTerminal");async function U(t){const e=I(t.body),r=await E(e.output_schema);r!==null&&n(400,"invalid_request",`output_schema is not usable: ${r}`),e.mode==="sync"&&e.target.kind!=="new"&&n(400,"sync_requires_dedicated_node","sync requests require target.kind=new");const a=Date.now(),i=J(e,a);if(m(i))return{status:200,body:{admitted:!1,reason:"work_budget_exhausted"}};let u=null,q="terminal",y=!0;if(e.target.kind==="node"){u=e.target.node_id;const d=await k(u);d===null&&n(404,"node_not_found",`unknown node: ${u}`),(d.final_report!==null||d.status==="done"||d.status==="canceled"||d.status==="dead")&&n(409,"node_terminal",`node ${u} is terminal`),await j(u)!==null&&n(409,"structured_request_conflict",`node ${u} already has a pending structured request`),q="oneoff",y=!1}if(m(i))return{status:200,body:{admitted:!1,reason:"work_budget_exhausted"}};let b;try{b=await D({requestId:e.request_id,mode:e.mode,submission:q,dedicated:y,schema:e.output_schema,deadlineAt:i,nodeId:u,now:Date.now()})}catch(d){throw d instanceof N&&(d.constraint==="structured_requests_pkey"&&n(409,"request_id_in_use",`request_id ${e.request_id} is already in use`),d.constraint==="idx_structured_requests_one_pending_node"&&n(409,"structured_request_conflict","the target node already has a pending structured request")),d}if(m(i))return await p(e.request_id);if(e.target.kind==="new")try{u=(await C(O(t,{...e.target.create,root:!0,root_lifecycle:"terminal",prompt:""}),{},{...i===null?{}:{deadlineAt:new Date(i).toISOString()},beforeBrokerLaunch:s(async o=>{if(u=o,m(i))throw new Error("structured request deadline expired before binding");const c=await T(e.request_id,o);if(!c.changed||c.row===null||c.row.state!=="pending")throw new Error("structured request bind did not remain pending");u=o,v(c.row)},"beforeBrokerLaunch")})).body.node_id}catch{const o=await l(e.request_id),c=o.state==="pending"?(await _(e.request_id,{intended:"failed",failureReason:o.node_id===null?"node_create_failed":"bind_failed"})).row:o;if(u!==null&&c.node_id===null){const g=await k(u);(g?.status==="active"||g?.status==="idle")&&await M(u,"cancel",{reason:"stranded"}),await F(u)}return await w(c)}else{if(m(i))return await p(e.request_id);try{v(b)}catch{return await w((await _(e.request_id,{intended:"failed",failureReason:"bind_failed"})).row)}}const h=await l(e.request_id);if(h.state!=="pending")return await w(h);if(m(i))return await p(e.request_id);try{await x(O(t,{body:e.prompt,tier:"normal"},u))}catch{return await w((await _(e.request_id,{intended:"failed",failureReason:"prompt_delivery_failed"})).row)}return e.mode==="async"?{status:202,body:{admitted:!0,request:f(await l(e.request_id))}}:{status:200,body:{admitted:!0,request:await L(e.request_id,i)}}}s(U,"handleCreateStructuredRequest");async function K(t){const e=t.params.request_id,r=G("structured-request.get",t.query),a=await l(e);return a===null&&n(404,"structured_request_not_found",`unknown structured request: ${e}`),{status:200,body:r===0?f(a):await P(e,r*1e3)}}s(K,"handleReadStructuredRequest");async function W(t){const e=await _(t.params.request_id,{intended:"canceled"});return e.row===null&&n(404,"structured_request_not_found",`unknown structured request: ${t.params.request_id}`),{status:200,body:f(e.row)}}s(W,"handleCancelStructuredRequest");const se=[{method:"POST",pattern:"/v1/structured-requests",handler:U},{method:"GET",pattern:"/v1/structured-requests/:request_id",handler:K},{method:"POST",pattern:"/v1/structured-requests/:request_id/cancel",handler:W}];export{se as structuredRequestRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var g=Object.defineProperty;var c=(n,e)=>g(n,"name",{value:e,configurable:!0});import{ApiError as d}from"../../api/index.js";import{readerFor as E}from"../../core/graph/reader.js";import{canRead as R}from"../../core/graph/access.js";import{ownersByHandle as y,resolveName as v,viewOf as x}from"../../core/graph/names.js";import{ensureOwner as h}from"../../core/graph/objects.js";import{checkoutsForCwd as F,reposForCwd as N}from"../../core/graph/repo-sync/repos.js";import{lookupProfile as j}from"../../core/profiles/manifest.js";import{filterAsync as L,mapAsync as _}from"../../core/async-array.js";async function T(n,e){return await E(n,e.principal,async o=>await F(n,o))}c(T,"readerFor");async function U(n,e,o){const r=await v(n,e,o);if("object"in r)return r.object;if("deleted"in r||"remote"in r)return r;if("ambiguous"in r){const s=await _(r.ambiguous,async
|
|
1
|
+
var g=Object.defineProperty;var c=(n,e)=>g(n,"name",{value:e,configurable:!0});import{ApiError as d}from"../../api/index.js";import{readerFor as E}from"../../core/graph/reader.js";import{canRead as R}from"../../core/graph/access.js";import{ownersByHandle as y,resolveName as v,viewOf as x}from"../../core/graph/names.js";import{ensureOwner as h}from"../../core/graph/objects.js";import{checkoutsForCwd as F,reposForCwd as N}from"../../core/graph/repo-sync/repos.js";import{lookupProfile as j}from"../../core/profiles/manifest.js";import{filterAsync as L,mapAsync as _}from"../../core/async-array.js";async function T(n,e){return await E(n,e.principal,async o=>await F(n,o))}c(T,"readerFor");async function U(n,e,o){const r=await v(n,e,o);if("object"in r)return r.object;if("deleted"in r||"remote"in r)return r;if("ambiguous"in r){const s=await _(r.ambiguous,async m=>`${await A(n,m)}/${m.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one object: ${s.join(", ")}`,{candidates:s,next:"Read one of them by its full `<type>:<owner>/<name>`."})}const t=o.replace(/^\s*\[\[(.*)\]\]\s*$/,"$1").trim(),i=/^(person|app|repo|profile):([^/]+)$/.exec(t),a=await L(i?await y(n,i[2],i[1]):(await y(n,t)).filter(s=>s.type!=="node"),async s=>await R(n,e,s));if(a.length>0){const s=await x(n,e),m=c(w=>{const f=s.findIndex($=>$.id===w.id);return f<0?1/0:f},"rank"),l=[...a].sort((w,f)=>m(w)-m(f))[0];if(m(l)===1/0&&a.length>1){const w=a.map(f=>`${f.type}:${f.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one owner: ${w.join(", ")}`,{candidates:w,next:"Name one as `<type>:<handle>`."})}return l.deleted_at?{deleted:l}:l}const p=`'${o}' not found: no object by that name in your view`,u=`Search for it with \`crtr canvas search ${t}\`.`;throw new d(404,"not_found",p,{error:"not_found",message:p,next:u})}c(U,"resolveRef");async function A(n,e){if(e.owner===null)return"";const o=await n.prepare("SELECT type, id, name FROM objects WHERE id = ?").get(e.owner);return o.type==="node"?o.id:`${o.type}:${o.name}`}c(A,"typedOwnerHandle");async function B(n,e,o,r){const t=o??(e.class==="node"?"node":e.class==="person"?"user":"app"),i=c(a=>new d(400,"invalid_owner",a,{next:"Run `crtr doc write --owner -h`."}),"refuse");if(t==="node"){if(e.class!=="node")throw i("`--owner node` needs a node; you are not running as one");return e.node}if(t==="user")return await h(n,"person","local-user","user:local","user");if(t==="app"){if(e.class==="person")throw i("`--owner app` needs an app; a person has none \u2014 use `--owner user`");return e.app}if(t==="profile"){if(e.class!=="node"||!e.profile)throw i("`--owner profile` needs a profile; you have none");return e.profile}if(t==="repo"){const a=r?await N(n,r):[],p=a[0]?a:e.class==="node"?e.repos:[];if(!p[0])throw i(`\`--owner repo\` needs a repo; ${r??(e.class==="node"?e.cwd:"your directory")} is not inside one`);return p[0]}if(t.startsWith("repo:"))return await I(n,"repo",t.slice(5),i);if(t.startsWith("profile:")){const a=t.slice(8),p=await n.prepare("SELECT * FROM objects WHERE type = 'profile' AND name = ? AND home_machine IS NULL").get(a);if(p)return p;const u=j(a);if(u.kind!=="resolved")throw i(`no profile named '${a}'`);const s=e.class==="person"?e.person:e.app;return await h(n,"profile","profile",u.entry.profileId,u.entry.manifest.name,s)}throw i(`unknown --owner value '${t}'`)}c(B,"ownerFromFlag");async function I(n,e,o,r){const t=await n.prepare("SELECT * FROM objects WHERE type = ? AND name = ? AND deleted_at IS NULL AND home_machine IS NULL").get(e,o);if(!t)throw r(`no ${e} named '${o}'`);return t}c(I,"namedOwner");export{B as ownerFromFlag,T as readerFor,U as resolveRef};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
2
1
|
import type { BrokerExtensionNodeDTO } from '../../api/dto/broker-ops.js';
|
|
3
2
|
/** Node-owned mutable fields in extensionNode's projection. Keep this list and
|
|
4
3
|
* the typed cache view together; object/worktree-owned fields are never cached. */
|
|
5
4
|
export declare const BROKER_SIGNAL_NODE_COLUMNS: readonly ["description", "title", "icon", "mode", "lifecycle", "status", "cwd", "parent", "fork_from", "profile_id", "review_binding_json", "persona_ack_json", "intent"];
|
|
6
5
|
type ProjectedNodeKey<C extends string> = C extends 'review_binding_json' ? 'review_binding' : C extends 'persona_ack_json' ? 'persona_ack' : C;
|
|
7
6
|
export type BrokerSignalCachedNode = Pick<BrokerExtensionNodeDTO, Extract<ProjectedNodeKey<(typeof BROKER_SIGNAL_NODE_COLUMNS)[number]>, keyof BrokerExtensionNodeDTO>>;
|
|
8
|
-
/** Only node-owned columns are suitable for P4's cache. The
|
|
9
|
-
*
|
|
7
|
+
/** Only node-owned columns are suitable for P4's cache. The same columns
|
|
8
|
+
* appear in `crtr_sig_node_upd` in schema-pg.sql; keep the two lists together. */
|
|
10
9
|
export declare function cachedBrokerNodeFields(node: BrokerExtensionNodeDTO): BrokerSignalCachedNode;
|
|
11
10
|
export type BrokerSignalKind = 'mail' | 'node';
|
|
12
11
|
export type BrokerSignalSubscriber = (nodeId: string, kind: BrokerSignalKind) => void;
|
|
@@ -21,9 +20,18 @@ export declare class BrokerSignalBus {
|
|
|
21
20
|
markNode(nodeId: string): void;
|
|
22
21
|
private mark;
|
|
23
22
|
private flush;
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
/** Start listening on `crtr_signal` over a second, listen-only connection to `url` (the schema's `pg_notify`
|
|
24
|
+
* triggers publish `mail:<node id>` and `node:<node id>` at commit). Resolves once LISTEN is active, so a write
|
|
25
|
+
* committed after it returns is heard. A lost connection reconnects with backoff; signals sent while it was down
|
|
26
|
+
* are lost, which is safe because they are hints and every consumer re-reads durable state. */
|
|
27
|
+
listen(url: string): Promise<void>;
|
|
28
|
+
private listener;
|
|
29
|
+
private listening;
|
|
30
|
+
private url;
|
|
31
|
+
private reconnect;
|
|
32
|
+
private connectListener;
|
|
33
|
+
/** Stop listening and drop pending marks. The returned promise resolves once the connection has closed. */
|
|
34
|
+
close(): Promise<void>;
|
|
27
35
|
}
|
|
28
36
|
/** One daemon-process bus; the API fixture binds this same instance. */
|
|
29
37
|
export declare const brokerSignalBus: BrokerSignalBus;
|
|
@@ -1,10 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var
|
|
2
|
-
CREATE TEMP TRIGGER crtr_sig_deliv_ins AFTER INSERT ON main.deliveries
|
|
3
|
-
WHEN NEW.wake = 1 BEGIN SELECT crtr_signal('mail', NEW.destination_id); END;
|
|
4
|
-
CREATE TEMP TRIGGER crtr_sig_deliv_upd AFTER UPDATE OF state, canceled_at, claim_owner ON main.deliveries
|
|
5
|
-
WHEN NEW.wake = 1 BEGIN SELECT crtr_signal('mail', NEW.destination_id); END;
|
|
6
|
-
CREATE TEMP TRIGGER crtr_sig_deliv_del AFTER DELETE ON main.deliveries
|
|
7
|
-
WHEN OLD.wake = 1 BEGIN SELECT crtr_signal('mail', OLD.destination_id); END;
|
|
8
|
-
CREATE TEMP TRIGGER crtr_sig_node_upd AFTER UPDATE OF ${d.join(", ")} ON main.nodes
|
|
9
|
-
BEGIN SELECT crtr_signal('node', NEW.node_id); END;
|
|
10
|
-
`)}close(){this.scheduled!==void 0&&clearImmediate(this.scheduled),this.scheduled=void 0,this.dirty.clear(),this.subscribers.clear()}}const _=new o;export{d as BROKER_SIGNAL_NODE_COLUMNS,o as BrokerSignalBus,_ as brokerSignalBus,l as cachedBrokerNodeFields};
|
|
1
|
+
var a=Object.defineProperty;var s=(n,e)=>a(n,"name",{value:e,configurable:!0});import h from"pg";const u=["description","title","icon","mode","lifecycle","status","cwd","parent","fork_from","profile_id","review_binding_json","persona_ack_json","intent"],f=s(n=>n==="review_binding_json"?"review_binding":n==="persona_ack_json"?"persona_ack":n,"nodeField");function _(n){const e={};for(const i of u){const t=f(i);e[t]=n[t]}return e}s(_,"cachedBrokerNodeFields");class m{static{s(this,"BrokerSignalBus")}dirty=new Map;subscribers=new Set;scheduled;async subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e)}}markMail(e){this.mark(e,1)}markNode(e){this.mark(e,2)}mark(e,i){this.dirty.set(e,(this.dirty.get(e)??0)|i),this.scheduled??=setImmediate(()=>this.flush())}flush(){this.scheduled=void 0;const e=[...this.dirty];this.dirty.clear();for(const[i,t]of e)for(const r of this.subscribers)try{t&1&&r(i,"mail"),t&2&&r(i,"node")}catch{}}async listen(e){this.listener!==void 0||this.listening!==void 0||(this.url=e,this.listening=this.connectListener().finally(()=>{this.listening=void 0}),await this.listening)}listener;listening;url;reconnect;async connectListener(){const e=new h.Client({connectionString:this.url,application_name:`crtr-signal-${process.pid}`});e.on("notification",r=>{const c=r.payload??"",o=c.indexOf(":");if(o<0)return;const d=c.slice(0,o),l=c.slice(o+1);d==="mail"?this.markMail(l):d==="node"&&this.markNode(l)});const i=s(()=>{this.listener===e&&(this.listener=void 0,e.removeAllListeners(),e.on("error",()=>{}),e.end().catch(()=>{}),this.url!==void 0&&(this.reconnect=setTimeout(()=>{this.reconnect=void 0,this.connectListener().catch(()=>t())},1e3)))},"lost"),t=s(()=>{this.url===void 0||this.reconnect!==void 0||(this.reconnect=setTimeout(()=>{this.reconnect=void 0,this.connectListener().catch(()=>t())},1e3))},"lostRetry");e.on("error",i),e.on("end",i),await e.connect(),await e.query("LISTEN crtr_signal"),this.listener=e}close(){this.url=void 0,this.reconnect!==void 0&&clearTimeout(this.reconnect),this.reconnect=void 0;const e=this.listener;return this.listener=void 0,this.scheduled!==void 0&&clearImmediate(this.scheduled),this.scheduled=void 0,this.dirty.clear(),this.subscribers.clear(),e===void 0?Promise.resolve():(e.removeAllListeners("notification"),e.end().catch(()=>{}))}}const g=new m;export{u as BROKER_SIGNAL_NODE_COLUMNS,m as BrokerSignalBus,g as brokerSignalBus,_ as cachedBrokerNodeFields};
|
package/dist/daemon/crtrd-cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=Object.defineProperty;var i=(e,r)=>p(e,"name",{value:r,configurable:!0});import"../suppress-experimental-warnings.js";import{runDaemon as o}from"./crtrd.js";import{configureDaemonHttpDispatcher as c}from"./http-dispatcher.js";function s(e){for(let r=0;r<e.length;r++){const t=e[r];if(t==="--tcp")return e[r+1];if(t!==void 0&&t.startsWith("--tcp="))return t.slice(6)}}i(s,"parseTcpArg");function a(e){return e.includes("--prepare")}i(a,"parsePrepareArg");const n=process.argv.slice(2);if(n[0]==="export-sqlite"){const{runExportSqlite:e}=await import("./export-sqlite-run.js");process.exitCode=await e()}else c(),await o({tcp:s(n),prepare:a(n)});
|