@north-light/cli 0.3.576 → 0.3.578

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.
Files changed (54) hide show
  1. package/dist/api/contract.d.ts +1 -1
  2. package/dist/api/contract.js +1 -1
  3. package/dist/api/dto/run-events.d.ts +10 -4
  4. package/dist/builtin-memory/crouter-sdk/release-notes.md +12 -0
  5. package/dist/builtin-memory/crouter-sdk/streaming.md +2 -0
  6. package/dist/builtin-memory/northlight-apps/concepts/runs.md +2 -0
  7. package/dist/builtin-memory/northlight-apps/guides/stream-a-run.md +1 -1
  8. package/dist/builtin-memory/northlight-apps/guides/test-your-app.md +1 -1
  9. package/dist/clients/attach/viewer.js +207 -207
  10. package/dist/core/io.js +4 -4
  11. package/dist/core/llm/refusal.d.ts +2 -1
  12. package/dist/core/llm/refusal.js +1 -1
  13. package/dist/core/llm/run.js +1 -1
  14. package/dist/core/model-routes.d.ts +11 -0
  15. package/dist/core/model-routes.js +1 -1
  16. package/dist/core/peer/envelope.d.ts +2 -0
  17. package/dist/core/peer/envelope.js +1 -1
  18. package/dist/core/providers/call.js +1 -1
  19. package/dist/core/runs/operations.d.ts +1 -1
  20. package/dist/core/runs/operations.js +5 -5
  21. package/dist/core/runtime/broker/daemon-ops.d.ts +4 -0
  22. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  23. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +4 -0
  24. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  25. package/dist/core/runtime/broker/rebind.d.ts +3 -0
  26. package/dist/core/runtime/broker/rebind.js +1 -1
  27. package/dist/core/runtime/broker/run-steer.d.ts +15 -0
  28. package/dist/core/runtime/broker/run-steer.js +1 -0
  29. package/dist/core/runtime/broker/run-turn-queue.d.ts +2 -0
  30. package/dist/core/runtime/broker/run-turn-queue.js +1 -1
  31. package/dist/core/runtime/broker.js +1 -1
  32. package/dist/core/runtime/revive.d.ts +6 -0
  33. package/dist/core/runtime/revive.js +2 -2
  34. package/dist/core/runtime/run-command.js +1 -1
  35. package/dist/core/runtime/runner/blaxel/client.d.ts +2 -2
  36. package/dist/core/runtime/runner/blaxel/client.js +1 -1
  37. package/dist/core/runtime/runner/blaxel/runner.js +2 -2
  38. package/dist/core/runtime/spawn.js +2 -2
  39. package/dist/daemon/api/handlers/messages.js +2 -2
  40. package/dist/daemon/api/handlers/nodes.js +1 -1
  41. package/dist/daemon/api/handlers/runs.js +1 -1
  42. package/dist/daemon/peer/forward.js +1 -1
  43. package/dist/daemon/runs/append-section.js +2 -2
  44. package/dist/pi-extensions/canvas-bash-valve.js +6 -6
  45. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  46. package/dist/pi-extensions/canvas-stophook.js +1 -1
  47. package/docs/apps/concepts/runs.md +2 -0
  48. package/docs/apps/guides/stream-a-run.md +1 -1
  49. package/docs/apps/guides/test-your-app.md +1 -1
  50. package/docs/sdk/release-notes.md +12 -0
  51. package/docs/sdk/streaming.md +2 -0
  52. package/package.json +2 -2
  53. package/packages/crouter-identity/package.json +1 -1
  54. package/runtime.lock.json +162 -665
@@ -1,2 +1,2 @@
1
- var ce=Object.defineProperty;var u=(t,e)=>ce(t,"name",{value:e,configurable:!0});import{randomBytes as ue}from"node:crypto";import{claimNodeMail as le,acknowledgeNodeMail as fe}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as me}from"../../../core/feed/inbox.js";import{enqueueNodeMail as D,cancelPendingNodeMail as pe}from"../../../core/feed/messages.js";import{reviveNode as L}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as U}from"../../../core/runtime/broker-request.js";import{isBrokerLive as R}from"../../../core/runtime/model-swap.js";import{deliverLive as ye,interruptLive as he}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as we}from"../../../core/profiles/manifest.js";import{getNode as O,withFreshTerminalGuard as be}from"../../../core/canvas/canvas.js";import{getById as G,nodeObject as F,ownerForGrantee as ge}from"../../../core/graph/objects.js";import{recordActedOn as ve}from"../../../core/graph/edges.js";import{recordWatch as H}from"../../../core/graph/watches.js";import{publish as V}from"../../../core/graph/events.js";import{readerFor as K}from"../reader.js";import{canRead as _e}from"../../../core/graph/access.js";import{withCanvasWrite as k}from"../../../core/canvas/db.js";import{getPendingStructuredRequestForNode as Q}from"../../../core/canvas/structured-requests.js";import{consumeDeadlineOnWake as X}from"../../../core/feed/messages.js";import{assertNotFinalized as M,assertFinalizedForReopen as ke,commitReopenResident as P}from"../../../core/runtime/reopen.js";import{admitLegacyStructuredOutput as Se}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as $e}from"../../../core/runtime/structured-output.js";import{appendSituationalContext as E,formatSituationalProse as Ne}from"../../../core/runtime/situational-context.js";import{formatDataCard as Y}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as je}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as Ae}from"../../park-pending.js";import{wantsExecution as qe}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as Oe}from"../../../core/runtime/revive.js";import{CrtrError as Ce,notFound as C,usage as c}from"../../../core/errors.js";import{isStartRefusal as xe}from"../../../core/runtime/start-check.js";import{emitEvent as Re}from"../../../core/events/emit.js";import{assertScope as Fe}from"../../../core/scopes.js";import{InputError as I}from"../../../core/io.js";import{ApiError as Me}from"../../../api/index.js";import{describeObject as Pe,stubOf as Ee}from"../../../core/peer/stubs.js";import{machineNameOf as Z}from"../../../core/peer/names.js";import{callerNode as Ie,callerStub as Te,forwardVerb as ee,relayError as te,remoteStub as Be,unknownError as re,withMachine as ne}from"../../peer/forward.js";import{ownerOnly as ze}from"../router.js";import{personId as We}from"../../../core/canvas/person.js";const Je=["critical","urgent","normal","deferred"];function oe(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw c(`${e} must be an object { kind, facts?, body? }`);const a=t,n=a.kind;if(typeof n!="string"||n.trim()==="")throw c(`${e}.kind is required`);if(!n.includes(":"))throw c(`${e}.kind must be namespaced (contain ':'): ${n}`);const r={kind:n},o=a.facts;if(o!==void 0){if(typeof o!="object"||o===null||Array.isArray(o))throw c(`${e}.facts must be an object of string or number values`);const d={};for(const[l,m]of Object.entries(o)){if(typeof m!="string"&&typeof m!="number")throw c(`${e}.facts.${l} must be a string or number`);d[l]=m}r.facts=d}const s=a.body;if(s!==void 0){if(typeof s!="string")throw c(`${e}.body must be a string`);r.body=s}return r}u(oe,"parseCardRequest");function ae(t,e){try{return Y(t.kind,t.facts??{},t.body??"")}catch(a){throw c(`${e}: ${a instanceof Error?a.message:String(a)}`)}}u(ae,"renderCard");function De(t){if(typeof t!="object"||t===null)throw c("a message requires a JSON body { body, tier?, fresh? }");const e=t,a=e.body,n=e.fresh===!0,r=e.tier,o=e.situational_context,s=e.output_schema,d=typeof a=="string"&&a.trim()!=="",l=typeof o=="string"&&o.trim()!=="",m=typeof s=="string"&&s.trim()!=="",v=e.situational_card,S=e.context_cards,b=v===void 0?void 0:oe(v,"situational_card");if(S!==void 0&&!Array.isArray(S))throw c("context_cards must be an array of { kind, facts?, body? }");const p=S?.map((N,$)=>oe(N,`context_cards[${$}]`));if(b!==void 0&&typeof o=="string"&&o!=="")throw c("situational_card and situational_context are mutually exclusive");const w=b!==void 0||p!==void 0&&p.length>0;if(!n&&!d&&!l&&!m&&!w)throw c("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(n&&p!==void 0&&p.length>0)throw c("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(r!==void 0&&!Je.includes(r))throw c(`invalid tier: ${String(r)} (expected critical|urgent|normal|deferred)`);const f={body:typeof a=="string"?a:""};r!==void 0&&(f.tier=r),n&&(f.fresh=!0),e.reopen===!0&&(f.reopen=!0),typeof o=="string"&&(f.situational_context=o),b!==void 0&&(f.situational_card=b),p!==void 0&&(f.context_cards=p),typeof s=="string"&&(f.output_schema=s),typeof e.from=="string"&&(f.from=e.from);const y=e.delivery;if(y!==void 0&&y!=="interactive")throw c(`invalid delivery: ${String(y)} (expected interactive)`);if(y==="interactive"){if(n||f.situational_context!==void 0||f.output_schema!==void 0)throw c("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!d)throw c("interactive delivery requires a non-empty body");if(f.tier==="deferred")throw c("interactive delivery cannot be deferred");f.delivery="interactive"}return f}u(De,"parseSendBody");function Le(t){let e;try{e=JSON.parse(t)}catch{throw c("output_schema must be a JSON schema string")}if(typeof e!="object"||e===null||Array.isArray(e))throw c("output_schema must be a JSON schema object");return e}u(Le,"parseSchema");function Ue(t){return t.split(`
2
- `)[0].slice(0,120)}u(Ue,"label");function ie(t,e){return e===null?"":Y("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}u(ie,"previousFinalReportCard");async function Ge(t,e,a){if(a!==null&&a!=="human"&&(await G(t,a))?.type==="node"){const o=await F(t,a);return{actor:o,senderNode:o}}if(a==="human")return{actor:await ge(t,We()),senderNode:null};const n=await K(t,e);return{actor:n.class==="person"?n.person:n.class==="app"?n.app:n.node,senderNode:n.class==="node"?n.node:null}}u(Ge,"messageActor");async function se(t,e,a,n,r,o){const s=await F(t,a),{actor:d,senderNode:l}=await Ge(t,e,n),m=r===null?{}:{pointer:r};await ve(t,d,s),l!==null&&l.id!==s.id&&await H(t,l,s,"message",{endsOn:o&&r!==null?`result:${r}`:"final"}),await V(t,{event:"messaged",object:s,actor:d,attrs:{},...m}),l!==null&&await V(t,{event:"sent",object:l,actor:l,attrs:{to:s.id},...m})}u(se,"recordMessage");function He(t,e){return new I({error:"deferred_no_natural_cycle",message:`${t} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}u(He,"deferredNoNaturalCycle");async function Ve(t){if(!await Oe(t))throw new Me(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}u(Ve,"assertRecoverableForFresh");function Ke(t,e){return t instanceof I?{error:t.payload.error,message:t.payload.message,next:t.payload.next,message_id:e}:t instanceof Ce?{error:t.code,message:t.message,message_id:e}:xe(t)?{error:t.code,message:t.message,message_id:e}:{error:"wake_failed",message:"the target could not be woken; see the daemon log",message_id:e}}u(Ke,"wakeFailure");async function Qe(t,e){const a=typeof t.body=="object"&&t.body!==null&&!Array.isArray(t.body)?{...t.body}:t.body;typeof a=="object"&&a!==null&&delete a.from;const n=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/messages`,body:a});if(n.kind==="local")return null;if(n.kind==="unknown")throw re(e,n.unreachable);if(n.status>=400)throw te(n.status,n.body);return await k(async r=>{const o=await Ie(r,t);if(o===null)return;const s=n.body?.object,d=await Be(r,e,"node",n.machine.id,s);await H(r,o,d,"message",{endsOn:"final"})}),{status:n.status,body:ne(n.body,n.machine)}}u(Qe,"forwardMessage");async function Xe(t){const e=await Ye(t);if(t.principal.class!=="forwarded"||typeof e.body!="object"||e.body===null)return e;const a=await k(async n=>{const r=await F(n,t.params.id);return await _e(n,await K(n,t),r)?await Pe(n,r):{id:r.id,type:r.type,kind:null,name:r.id,owner:null}});return{...e,body:{...e.body,object:a}}}u(Xe,"handleMessage");async function Ye(t){const e=t.params.id,a=await Qe(t,e);if(a!==null)return a;const n=await O(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=De(t.body),o=r.tier??"normal",s=we(n.profile_id),d=t.principal.class==="forwarded"?await k(async i=>(await Te(i,t))?.id??null):r.from??null;if(d!==null){const i=await O(d);i!==null&&Fe(i,"crtr:act")}const l=d===null?null:await k(async i=>{const h=await G(i,d);return h===null?null:(await Ee(i,h))?.home_machine??null}),m=l===null?void 0:`${d} on ${Z(l)}`,v=t.principal.class==="broker"?t.principal.node:null,S=l===null?{}:{from_machine:Z(l)},b=r.body.trim()!=="",p=r.situational_card!==void 0?ae(r.situational_card,"situational_card"):r.situational_context!==void 0?Ne(r.situational_context.trim()):"",w=p!=="",f=(r.context_cards??[]).map((i,h)=>ae(i,`context_cards[${h}]`)),y=r.output_schema!==void 0&&r.output_schema.trim()!==""?Le(r.output_schema):null;y!==null&&await $e(y);let N=!1;const $=u(async i=>{if(!(y===null||N)){if(await Q(e)!==null)throw new I({error:"structured_request_conflict",message:`node ${e} already has a pending structured request`,next:"Wait for the current request to settle before requesting another structured result."});await Se(e,"oneoff",y,i),N=!0}},"ensureSchema");if(r.fresh){const i=r.reopen?await ke(e):null;r.reopen||await M(e),await Ve(e),await $(),w&&await E(e,p),r.reopen&&await P(e,i,v);const h=await L(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:h.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&await M(e);let T=!1,_="";if(r.delivery==="interactive"&&r.reopen&&(_=ie(e,await P(e,void 0,v)),T=!0),r.delivery==="interactive"&&await $(),r.delivery==="interactive"&&!s&&!n.run_id&&R(n))try{return w&&await E(e,p),await ye(e,r.body,{cards:[..._===""?[]:[_],...w?[p]:[],...f],origin:d==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...d===null?{}:{from:d},...m===void 0?{}:{fromName:m},kind:"message",tier:o}]}}),await k(async h=>await se(h,t,e,d,null,!1)),await X(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(i){if(!(i instanceof U))throw i}const B=u(async()=>{r.reopen||await M(e);const i=ue(16).toString("hex"),h=u(async q=>await se(q,t,e,d,i,y!==null),"withinEnqueue");await $(i),w&&await E(e,p),r.reopen&&!T&&(_=ie(e,await P(e,void 0,v)));const x=[..._===""?[]:[_],...f],J=x.length>0?{cards:x}:{};if(b||y!==null){const q=b?r.body:`A one-off structured-output request has been granted. Submit a result matching the requested schema with the \`submit_result\` tool (\`request_id: "${(await Q(e))?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:h,label:Ue(q),bodyJson:{body:q,...S,...w?{situational:!0}:{},...J}})}return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:h,label:w?"(ambient context updated)":"(context delivered)",bodyJson:{...w?{situational:!0}:{},situationalOnly:!0,...J}})},"deliverImmediate"),g=await u(async()=>{if(o==="deferred"){const i=await be(e,je,B);if(i.kind==="missing")throw C(`unknown node: ${e}`,{received:e});if(i.kind==="terminal")throw He(e,i.status);return i.result}return await B()},"deliver")();g.urgency!=="deferred"&&await k(async()=>Ae(e));const j=await O(e);if(j===null)throw C(`unknown node: ${e}`,{received:e});n.frozen_at!==null&&await X(e);let z=!1,W=!1,A;if((r.reopen||j.lifecycle==="terminal"||!await qe(j))&&g.urgency!=="deferred"&&!s&&!R(j))try{const i=await L(e,{resume:!0,capacity:"freeze"});z=i.launch!==void 0,W=i.outcome==="frozen"}catch(i){A=Ke(i,g.messageId),Re({level:"error",event:"message.wake_failed",node_id:e,error:i,fields:{message_id:g.messageId,error_code:A.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:z,...W?{not_revived_reason:"capacity_frozen"}:{},...A===void 0?{}:{wake_failed:A},delivered_at:g.createdAt,...g.urgency===o?{}:{delivered_tier:g.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}u(Ye,"handleMessageHere");async function Ze(t){const e=t.params.id,a=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/interrupt`,body:t.body});if(a.kind==="unknown")throw re(e,a.unreachable);if(a.kind==="remote"){if(a.status>=400)throw te(a.status,a.body);return{status:a.status,body:ne(a.body,a.machine)}}const n=await O(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=await pe(e,{senderNodeId:"human",kind:"message"});let o=!1;if(R(n))try{o=await he(e)!=="idle"}catch(d){if(!(d instanceof U))throw d}return{status:200,body:{node_id:e,outcome:o?"aborted_turn":r.length>0?"canceled_pending":"idle",aborted_turn:o,canceled_pending:r.length}}}u(Ze,"handleInterrupt");function de(t){if(typeof t.body!="object"||t.body===null||Array.isArray(t.body))throw c("mail requires an object body");const e=t.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw c("execution_id is required");return e}u(de,"mailBody");async function et(t){const e=de(t),a=e.channel;if(a!=="wake"&&a!=="passive"&&a!=="deferred_run")throw c("channel must be wake, passive, or deferred_run");const n=await le(t.params.id,e.execution_id,a);return{status:200,body:{action:n.action,deliveries:n.deliveries.map(o=>({delivery_id:o.deliveryId,attempts:o.attempts,handoff:o.handoff,entry:{...me(o),seq:o.message.seq}}))}}}u(et,"handleMailClaim");async function tt(t){const e=de(t);if(!Array.isArray(e.deliveries))throw c("deliveries must be an array");const a=e.deliveries.map(o=>{if(typeof o!="object"||o===null||Array.isArray(o))throw c("each delivery must be an object");const s=o;if(typeof s.delivery_id!="string"||s.delivery_id==="")throw c("delivery_id is required");if(!Number.isSafeInteger(s.attempts)||s.attempts<1)throw c("attempts must be a positive integer");if(s.disposition!=="acknowledged"&&s.disposition!=="released")throw c("disposition must be acknowledged or released");return{delivery_id:s.delivery_id,attempts:s.attempts,disposition:s.disposition}}),n=await fe(t.params.id,e.execution_id,a.map(o=>({deliveryId:o.delivery_id,attempts:o.attempts,disposition:o.disposition})));return{status:200,body:{action:n.action,results:n.results.map(o=>({delivery_id:o.deliveryId,outcome:o.outcome}))}}}u(tt,"handleMailAcknowledge");const Ut=ze([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:et},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:tt}]),Gt=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:Xe},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Ze}];export{Ut as brokerMailRoutes,Xe as handleMessage,Gt as messageRoutes};
1
+ var ce=Object.defineProperty;var u=(t,e)=>ce(t,"name",{value:e,configurable:!0});import{randomBytes as ue}from"node:crypto";import{claimNodeMail as le,acknowledgeNodeMail as fe}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as me}from"../../../core/feed/inbox.js";import{enqueueNodeMail as D,cancelPendingNodeMail as pe}from"../../../core/feed/messages.js";import{assertRecordedCwdExists as ye,reviveNode as L}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as U}from"../../../core/runtime/broker-request.js";import{isBrokerLive as O}from"../../../core/runtime/model-swap.js";import{deliverLive as we,interruptLive as he}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as be}from"../../../core/profiles/manifest.js";import{getNode as C,withFreshTerminalGuard as ge}from"../../../core/canvas/canvas.js";import{getById as G,nodeObject as F,ownerForGrantee as ve}from"../../../core/graph/objects.js";import{recordActedOn as _e}from"../../../core/graph/edges.js";import{recordWatch as H}from"../../../core/graph/watches.js";import{publish as V}from"../../../core/graph/events.js";import{readerFor as K}from"../reader.js";import{canRead as ke}from"../../../core/graph/access.js";import{withCanvasWrite as k}from"../../../core/canvas/db.js";import{getPendingStructuredRequestForNode as Q}from"../../../core/canvas/structured-requests.js";import{consumeDeadlineOnWake as X}from"../../../core/feed/messages.js";import{assertNotFinalized as M,assertFinalizedForReopen as Se,commitReopenResident as E}from"../../../core/runtime/reopen.js";import{admitLegacyStructuredOutput as $e}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as Ne}from"../../../core/runtime/structured-output.js";import{appendSituationalContext as P,formatSituationalProse as je}from"../../../core/runtime/situational-context.js";import{formatDataCard as Y}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as Ae}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as qe}from"../../park-pending.js";import{wantsExecution as Oe}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as Ce}from"../../../core/runtime/revive.js";import{CrtrError as xe,notFound as x,usage as c}from"../../../core/errors.js";import{isStartRefusal as Re}from"../../../core/runtime/start-check.js";import{emitEvent as Fe}from"../../../core/events/emit.js";import{assertScope as Me}from"../../../core/scopes.js";import{InputError as I}from"../../../core/io.js";import{ApiError as Ee}from"../../../api/index.js";import{describeObject as Pe,stubOf as Ie}from"../../../core/peer/stubs.js";import{machineNameOf as Z}from"../../../core/peer/names.js";import{callerNode as Te,callerStub as Be,forwardVerb as ee,relayError as te,remoteStub as ze,unknownError as re,withMachine as ne}from"../../peer/forward.js";import{ownerOnly as We}from"../router.js";import{personId as Je}from"../../../core/canvas/person.js";const De=["critical","urgent","normal","deferred"];function oe(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw c(`${e} must be an object { kind, facts?, body? }`);const a=t,n=a.kind;if(typeof n!="string"||n.trim()==="")throw c(`${e}.kind is required`);if(!n.includes(":"))throw c(`${e}.kind must be namespaced (contain ':'): ${n}`);const r={kind:n},o=a.facts;if(o!==void 0){if(typeof o!="object"||o===null||Array.isArray(o))throw c(`${e}.facts must be an object of string or number values`);const d={};for(const[l,m]of Object.entries(o)){if(typeof m!="string"&&typeof m!="number")throw c(`${e}.facts.${l} must be a string or number`);d[l]=m}r.facts=d}const s=a.body;if(s!==void 0){if(typeof s!="string")throw c(`${e}.body must be a string`);r.body=s}return r}u(oe,"parseCardRequest");function ae(t,e){try{return Y(t.kind,t.facts??{},t.body??"")}catch(a){throw c(`${e}: ${a instanceof Error?a.message:String(a)}`)}}u(ae,"renderCard");function Le(t){if(typeof t!="object"||t===null)throw c("a message requires a JSON body { body, tier?, fresh? }");const e=t,a=e.body,n=e.fresh===!0,r=e.tier,o=e.situational_context,s=e.output_schema,d=typeof a=="string"&&a.trim()!=="",l=typeof o=="string"&&o.trim()!=="",m=typeof s=="string"&&s.trim()!=="",v=e.situational_card,S=e.context_cards,b=v===void 0?void 0:oe(v,"situational_card");if(S!==void 0&&!Array.isArray(S))throw c("context_cards must be an array of { kind, facts?, body? }");const p=S?.map((N,$)=>oe(N,`context_cards[${$}]`));if(b!==void 0&&typeof o=="string"&&o!=="")throw c("situational_card and situational_context are mutually exclusive");const h=b!==void 0||p!==void 0&&p.length>0;if(!n&&!d&&!l&&!m&&!h)throw c("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(n&&p!==void 0&&p.length>0)throw c("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(r!==void 0&&!De.includes(r))throw c(`invalid tier: ${String(r)} (expected critical|urgent|normal|deferred)`);const f={body:typeof a=="string"?a:""};r!==void 0&&(f.tier=r),n&&(f.fresh=!0),e.reopen===!0&&(f.reopen=!0),typeof o=="string"&&(f.situational_context=o),b!==void 0&&(f.situational_card=b),p!==void 0&&(f.context_cards=p),typeof s=="string"&&(f.output_schema=s),typeof e.from=="string"&&(f.from=e.from);const y=e.delivery;if(y!==void 0&&y!=="interactive")throw c(`invalid delivery: ${String(y)} (expected interactive)`);if(y==="interactive"){if(n||f.situational_context!==void 0||f.output_schema!==void 0)throw c("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!d)throw c("interactive delivery requires a non-empty body");if(f.tier==="deferred")throw c("interactive delivery cannot be deferred");f.delivery="interactive"}return f}u(Le,"parseSendBody");function Ue(t){let e;try{e=JSON.parse(t)}catch{throw c("output_schema must be a JSON schema string")}if(typeof e!="object"||e===null||Array.isArray(e))throw c("output_schema must be a JSON schema object");return e}u(Ue,"parseSchema");function Ge(t){return t.split(`
2
+ `)[0].slice(0,120)}u(Ge,"label");function ie(t,e){return e===null?"":Y("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}u(ie,"previousFinalReportCard");async function He(t,e,a){if(a!==null&&a!=="human"&&(await G(t,a))?.type==="node"){const o=await F(t,a);return{actor:o,senderNode:o}}if(a==="human")return{actor:await ve(t,Je()),senderNode:null};const n=await K(t,e);return{actor:n.class==="person"?n.person:n.class==="app"?n.app:n.node,senderNode:n.class==="node"?n.node:null}}u(He,"messageActor");async function se(t,e,a,n,r,o){const s=await F(t,a),{actor:d,senderNode:l}=await He(t,e,n),m=r===null?{}:{pointer:r};await _e(t,d,s),l!==null&&l.id!==s.id&&await H(t,l,s,"message",{endsOn:o&&r!==null?`result:${r}`:"final"}),await V(t,{event:"messaged",object:s,actor:d,attrs:{},...m}),l!==null&&await V(t,{event:"sent",object:l,actor:l,attrs:{to:s.id},...m})}u(se,"recordMessage");function Ve(t,e){return new I({error:"deferred_no_natural_cycle",message:`${t} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}u(Ve,"deferredNoNaturalCycle");async function Ke(t){if(!await Ce(t))throw new Ee(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}u(Ke,"assertRecoverableForFresh");function Qe(t,e){return t instanceof I?{error:t.payload.error,message:t.payload.message,next:t.payload.next,message_id:e}:t instanceof xe?{error:t.code,message:t.message,message_id:e}:Re(t)?{error:t.code,message:t.message,message_id:e}:{error:"wake_failed",message:"the target could not be woken; see the daemon log",message_id:e}}u(Qe,"wakeFailure");async function Xe(t,e){const a=typeof t.body=="object"&&t.body!==null&&!Array.isArray(t.body)?{...t.body}:t.body;typeof a=="object"&&a!==null&&delete a.from;const n=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/messages`,body:a});if(n.kind==="local")return null;if(n.kind==="unknown")throw re(e,n.unreachable);if(n.status>=400)throw te(n.status,n.body);return await k(async r=>{const o=await Te(r,t);if(o===null)return;const s=n.body?.object,d=await ze(r,e,"node",n.machine.id,s);await H(r,o,d,"message",{endsOn:"final"})}),{status:n.status,body:ne(n.body,n.machine)}}u(Xe,"forwardMessage");async function Ye(t){const e=await Ze(t);if(t.principal.class!=="forwarded"||typeof e.body!="object"||e.body===null)return e;const a=await k(async n=>{const r=await F(n,t.params.id);return await ke(n,await K(n,t),r)?await Pe(n,r):{id:r.id,type:r.type,kind:null,name:r.id,owner:null}});return{...e,body:{...e.body,object:a}}}u(Ye,"handleMessage");async function Ze(t){const e=t.params.id,a=await Xe(t,e);if(a!==null)return a;const n=await C(e);if(n===null)throw x(`unknown node: ${e}`,{received:e});const r=Le(t.body),o=r.tier??"normal",s=be(n.profile_id);r.reopen&&!s&&!O(n)&&await ye(e,n);const d=t.principal.class==="forwarded"?await k(async i=>(await Be(i,t))?.id??null):r.from??null;if(d!==null){const i=await C(d);i!==null&&Me(i,"crtr:act")}const l=d===null?null:await k(async i=>{const w=await G(i,d);return w===null?null:(await Ie(i,w))?.home_machine??null}),m=l===null?void 0:`${d} on ${Z(l)}`,v=t.principal.class==="broker"?t.principal.node:null,S=l===null?{}:{from_machine:Z(l)},b=r.body.trim()!=="",p=r.situational_card!==void 0?ae(r.situational_card,"situational_card"):r.situational_context!==void 0?je(r.situational_context.trim()):"",h=p!=="",f=(r.context_cards??[]).map((i,w)=>ae(i,`context_cards[${w}]`)),y=r.output_schema!==void 0&&r.output_schema.trim()!==""?Ue(r.output_schema):null;y!==null&&await Ne(y);let N=!1;const $=u(async i=>{if(!(y===null||N)){if(await Q(e)!==null)throw new I({error:"structured_request_conflict",message:`node ${e} already has a pending structured request`,next:"Wait for the current request to settle before requesting another structured result."});await $e(e,"oneoff",y,i),N=!0}},"ensureSchema");if(r.fresh){const i=r.reopen?await Se(e):null;r.reopen||await M(e),await Ke(e),await $(),h&&await P(e,p),r.reopen&&await E(e,i,v);const w=await L(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:w.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&await M(e);let T=!1,_="";if(r.delivery==="interactive"&&r.reopen&&(_=ie(e,await E(e,void 0,v)),T=!0),r.delivery==="interactive"&&await $(),r.delivery==="interactive"&&!s&&!n.run_id&&O(n))try{return h&&await P(e,p),await we(e,r.body,{cards:[..._===""?[]:[_],...h?[p]:[],...f],origin:d==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...d===null?{}:{from:d},...m===void 0?{}:{fromName:m},kind:"message",tier:o}]}}),await k(async w=>await se(w,t,e,d,null,!1)),await X(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(i){if(!(i instanceof U))throw i}const B=u(async()=>{r.reopen||await M(e);const i=ue(16).toString("hex"),w=u(async q=>await se(q,t,e,d,i,y!==null),"withinEnqueue");await $(i),h&&await P(e,p),r.reopen&&!T&&(_=ie(e,await E(e,void 0,v)));const R=[..._===""?[]:[_],...f],J=R.length>0?{cards:R}:{};if(b||y!==null){const q=b?r.body:`A one-off structured-output request has been granted. Submit a result matching the requested schema with the \`submit_result\` tool (\`request_id: "${(await Q(e))?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:w,label:Ge(q),bodyJson:{body:q,...S,...h?{situational:!0}:{},...J}})}return await D(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:i,withinEnqueue:w,label:h?"(ambient context updated)":"(context delivered)",bodyJson:{...h?{situational:!0}:{},situationalOnly:!0,...J}})},"deliverImmediate"),g=await u(async()=>{if(o==="deferred"){const i=await ge(e,Ae,B);if(i.kind==="missing")throw x(`unknown node: ${e}`,{received:e});if(i.kind==="terminal")throw Ve(e,i.status);return i.result}return await B()},"deliver")();g.urgency!=="deferred"&&await k(async()=>qe(e));const j=await C(e);if(j===null)throw x(`unknown node: ${e}`,{received:e});n.frozen_at!==null&&await X(e);let z=!1,W=!1,A;if((r.reopen||j.lifecycle==="terminal"||!await Oe(j))&&g.urgency!=="deferred"&&!s&&!O(j))try{const i=await L(e,{resume:!0,capacity:"freeze"});z=i.launch!==void 0,W=i.outcome==="frozen"}catch(i){A=Qe(i,g.messageId),Fe({level:"error",event:"message.wake_failed",node_id:e,error:i,fields:{message_id:g.messageId,error_code:A.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:z,...W?{not_revived_reason:"capacity_frozen"}:{},...A===void 0?{}:{wake_failed:A},delivered_at:g.createdAt,...g.urgency===o?{}:{delivered_tier:g.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}u(Ze,"handleMessageHere");async function et(t){const e=t.params.id,a=await ee(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/interrupt`,body:t.body});if(a.kind==="unknown")throw re(e,a.unreachable);if(a.kind==="remote"){if(a.status>=400)throw te(a.status,a.body);return{status:a.status,body:ne(a.body,a.machine)}}const n=await C(e);if(n===null)throw x(`unknown node: ${e}`,{received:e});const r=await pe(e,{senderNodeId:"human",kind:"message"});let o=!1;if(O(n))try{o=await he(e)!=="idle"}catch(d){if(!(d instanceof U))throw d}return{status:200,body:{node_id:e,outcome:o?"aborted_turn":r.length>0?"canceled_pending":"idle",aborted_turn:o,canceled_pending:r.length}}}u(et,"handleInterrupt");function de(t){if(typeof t.body!="object"||t.body===null||Array.isArray(t.body))throw c("mail requires an object body");const e=t.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw c("execution_id is required");return e}u(de,"mailBody");async function tt(t){const e=de(t),a=e.channel;if(a!=="wake"&&a!=="passive"&&a!=="deferred_run")throw c("channel must be wake, passive, or deferred_run");const n=await le(t.params.id,e.execution_id,a);return{status:200,body:{action:n.action,deliveries:n.deliveries.map(o=>({delivery_id:o.deliveryId,attempts:o.attempts,handoff:o.handoff,entry:{...me(o),seq:o.message.seq}}))}}}u(tt,"handleMailClaim");async function rt(t){const e=de(t);if(!Array.isArray(e.deliveries))throw c("deliveries must be an array");const a=e.deliveries.map(o=>{if(typeof o!="object"||o===null||Array.isArray(o))throw c("each delivery must be an object");const s=o;if(typeof s.delivery_id!="string"||s.delivery_id==="")throw c("delivery_id is required");if(!Number.isSafeInteger(s.attempts)||s.attempts<1)throw c("attempts must be a positive integer");if(s.disposition!=="acknowledged"&&s.disposition!=="released")throw c("disposition must be acknowledged or released");return{delivery_id:s.delivery_id,attempts:s.attempts,disposition:s.disposition}}),n=await fe(t.params.id,e.execution_id,a.map(o=>({deliveryId:o.delivery_id,attempts:o.attempts,disposition:o.disposition})));return{status:200,body:{action:n.action,results:n.results.map(o=>({delivery_id:o.deliveryId,outcome:o.outcome}))}}}u(rt,"handleMailAcknowledge");const Gt=We([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:tt},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:rt}]),Ht=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:Ye},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:et}];export{Gt as brokerMailRoutes,Ye as handleMessage,Ht as messageRoutes};
@@ -1 +1 @@
1
- var $e=Object.defineProperty;var s=(e,n)=>$e(e,"name",{value:n,configurable:!0});import{envProfileId as Ne}from"../../../shared/env.js";import{pausedCanvasProfiles as Ce}from"../../../core/profiles/manifest.js";import{existsSync as P,realpathSync as ee,statSync as ne}from"node:fs";import{isAbsolute as K,resolve as D}from"node:path";import{appendSituationalContext as Ee,formatSituationalProse as Te}from"../../../core/runtime/situational-context.js";import{closeNode as Pe}from"../../../core/runtime/close.js";import{reviveNode as De}from"../../../core/runtime/revive.js";import{nowIso as x}from"../../../core/fs-utils.js";import{appPaidLaunch as Le,assertLaunchModelRegistered as V,forkNode as je,resolveForkSource as te,spawnChildPrepared as Me}from"../../../core/runtime/spawn.js";import{forkSourceNode as ie,newNodeId as re}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as oe,childrenOf as Ge,completeCreateRequest as ae,findCreateRequest as de,getNode as R,recordCreateRequestNode as Fe,reserveCreateRequest as se,reserveCreateRequestNode as Be,listNodes as Ke,recordRespawnAttempt as xe,subscribersOf as Ve,subscriptionsOf as le,updateNode as C}from"../../../core/canvas/canvas.js";import{armControllerWait as We}from"../../../core/canvas/waits.js";import{withCanvasWrite as W}from"../../../core/canvas/db.js";import{markNodeRead as ze}from"../../../core/canvas/recovery.js";import{nodeObject as Je}from"../../../core/graph/objects.js";import{recordActedOn as Ue}from"../../../core/graph/edges.js";import{publish as Ye}from"../../../core/graph/events.js";import{readerFor as He}from"../reader.js";import{relocateSessionCwd as Qe,unbindSession as Xe}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as Ze}from"../../../core/canvas/attention.js";import{isSafeNodeId as qe}from"../../../core/canvas/paths.js";import{contextDir as ce,nodeAgentDir as z}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as en,cronRefusalError as nn}from"../../cron/authority.js";import{cronBirthPlacement as tn}from"../../cron/armed-context.js";import{existsBeneath as rn,isAbsentOrRefused as on,isBeneathRefusal as an,readdirBeneath as dn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as sn,readNodeSession as ln,readNodeSnapshot as cn,transcriptMarkdown as un}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as fn}from"../../../core/substrate/subject.js";import{reviveAll as pn}from"../../../core/runtime/revive-all.js";import{promoteAsync as mn,requestYieldAsync as wn,reshapeNodeAsync as J}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{requireCurrentExecution as gn}from"./broker-recovery.js";import{readOutputRequest as bn}from"../../../core/runtime/output-result.js";import{writeYieldMessage as vn,readGoal as kn,captureGoalIfAbsent as Sn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as Rn,hasRoadmap as In}from"../../../core/runtime/roadmap.js";import{renameWindow as On}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as An,explicitModelIntent as $n,normalizeModel as Nn,readMergedLaunchConfigAsync as ue}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as Cn}from"../../../core/model-routes.js";import{persistDormantModel as En,setModelLive as Tn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as fe}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as Pn}from"../../../core/runtime/broker-request.js";import{boundFleet as L}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as Dn}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as Ln}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as pe}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as jn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Mn}from"../../../core/human-actions.js";import{parseDurationMs as Gn}from"../../../core/wake.js";import{claimWarmNode as Fn,refillWarmPool as me,resumeWarmClaim as Bn,warmPoolEnabled as Kn}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as U,isLaunchKind as xn,resolveLaunchTarget as Vn}from"../../../core/runtime/launch-target.js";import{fullName as Wn}from"../../../core/canvas/labels.js";import{reportsForNode as we}from"./reports.js";import{requireUsableProfile as zn}from"./profiles.js";import{assertProfileActive as Jn,loadExactProfileManifest as Un}from"../../../core/profiles/manifest.js";import{getCron as he}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Yn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as Hn}from"../../control.js";import{notFound as E,usage as w}from"../../../core/errors.js";import{assertScope as Qn,validateScopes as ye}from"../../../core/scopes.js";import{scopeAllowed as O}from"../../../shared/env.js";import{toCloseResultDTO as Xn,toNodeDetailDTO as Y,toNodeSummaryDTO as Zn,toReviveResultDTO as qn}from"../map.js";import{ApiError as p}from"../../../api/index.js";import{InputError as y}from"../../../core/io.js";import{actsAsPerson as j,canReadNode as $,mayOnNode as et,readableNodeIds as nt,resolvedScopes as tt}from"../router.js";import{forwardVerb as it,queryWithoutMachine as rt,relayError as ot,unknownError as at,withMachine as dt}from"../../peer/forward.js";import{fileRoot as st}from"../../../core/spaces/file-root.js";import{activeGrant as lt,payerOfGrant as ct}from"../../../core/grants/mirror.js";import{nodeTerminalGrant as ut}from"../../../core/grants/terminal.js";import{appRungForGrant as ft}from"../../../core/llm/app-rungs.js";import{APP_FAMILY as pt}from"../../../core/model-routes.js";import{listProfileEnvNames as mt}from"../../../core/profiles/env-store.js";import{hasConfiguredProviderCredential as wt,NO_PROVIDER_CREDENTIAL_MESSAGE as _e}from"../../../core/runtime/provider-credential-gate.js";import{filterAsync as ht,mapAsync as ge}from"../../../core/async-array.js";async function m(e){const n=await R(e);if(n===null)throw E(`unknown node: ${e}`,{received:e});return n}s(m,"requireMeta");async function H(e){return{subscribesTo:await le(e),subscribers:await Ve(e),children:await Ge(e)}}s(H,"edgesFor");async function b(e){const n=await m(e);return await Y(n,await H(e))}s(b,"detailOf");async function yt(e){let n=(await we(e)).length;try{n+=dn(await z(e),await ce(e)).length}catch(t){if(!on(t))throw t}return n}s(yt,"countFiles");function _t(e){if(typeof e!="object"||e===null)throw w("a node create requires a JSON body");const n=e;if(n.kind!==void 0&&(typeof n.kind!="string"||n.kind.trim()===""))throw w("kind must be a non-empty string when provided");if(n.description!==void 0&&(typeof n.description!="string"||n.description.trim()===""))throw w("description must be a non-empty string when provided");if(n.creator!==void 0&&(typeof n.creator!="string"||n.creator.trim()===""))throw w("creator must be a non-empty node id when provided");if(n.scopes!==void 0&&ye(n.scopes),n.isolated!==void 0&&typeof n.isolated!="boolean")throw new p(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const t=n.root_lifecycle;if(t!==void 0&&t!=="resident"&&t!=="terminal")throw w("root_lifecycle must be 'resident' or 'terminal'");if(n.request_key!==void 0&&(typeof n.request_key!="string"||n.request_key.trim()===""||n.request_key.length>128))throw w("request_key must be a non-empty string of at most 128 characters when provided");return n}s(_t,"parseCreateBody");function gt(e){if(e===void 0)return;const n=Gn(e),t=n===null?null:new Date(Date.now()+n);if(n===null||!Number.isFinite(n)||n<=0||t===null||!Number.isFinite(t.getTime()))throw new p(422,"invalid_deadline","`deadline` must be a positive representable duration");return t.toISOString()}s(gt,"parseDeadline");function bt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new p(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!jn.test(e.action))throw new p(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let n;try{n=JSON.stringify(e.payload)}catch{throw new p(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(n===void 0)throw new p(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(n,"utf8")>pe)throw new p(413,"payload_too_large",`serialized payload exceeds ${pe} bytes`)}return e}}s(bt,"parseOutcomeDelivery");function vt(e,n){const t=Mn(e.action,n);if(!("kind"in t))return{actionName:e.action,argv:t.argv,cwd:t.cwd,configOrigin:t.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw t.kind==="unknown_action"?new p(422,"unknown_action",`no action named ${e.action} is declared from ${n}`):new p(422,"invalid_action",`${e.action} is declared in ${t.configOrigin} but unusable: ${t.reason}`,{reason:t.reason,configOrigin:t.configOrigin})}s(vt,"resolveOutcomeDelivery");function kt(e,n,t){const r={kind:e.kind,cwd:t,prompt:e.prompt??""};return e.mode!==void 0&&(r.mode=e.mode),e.name!==void 0&&(r.name=e.name),e.description!==void 0&&(r.description=e.description),n!==void 0&&(r.parent=n),e.creator!==void 0&&(r.creator=e.creator),e.scopes!==void 0&&(r.scopes=e.scopes),e.isolated!==void 0&&(r.isolated=e.isolated),e.root===!0&&(r.root=!0),e.root_lifecycle!==void 0&&(r.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(r.worktree=!0),typeof e.worktree=="string"&&(r.worktreeBase=e.worktree),e.worktree!==void 0&&(r.worktreeCwd=D(e.pin_cwd??e.cwd??t)),e.fork_from!==void 0&&(r.forkFrom=e.fork_from),e.model!==void 0&&(r.model=e.model),e.profile!==void 0&&(r.profile=e.profile),e.situational_context!==void 0&&(r.situationalContext=e.situational_context),e.node_id!==void 0&&(r.nodeId=e.node_id),r}s(kt,"buildRecipe");function St(e,n,t){return!Kn()||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:n,profileId:t,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}s(St,"warmRequestFor");import{resolveCreateKind as Ar}from"../../../core/runtime/launch-target.js";function be(e){const n=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Cn(e.model,n,e.modelExact===!0)}s(be,"requestFromLaunch");function Rt(e,n){if(n===null)return e;if(e.scopes===void 0)return{...e,scopes:[...n]};const t=e.scopes.filter(r=>!O(n,r));if(t.length===0)return e;throw new p(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${t.join(", ")}`,{scopes:t,ceiling:n})}s(Rt,"withinCeiling");async function ve(e,n,t){const r=(await An(n.kind,n.mode,{lifecycle:n.lifecycle,hasManager:e.parent!==null,model:n.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await V(be(r),{cwd:e.cwd,profileId:e.profile_id??null},t)}s(ve,"assertNodeModelChangeRegistered");async function ke(e,n){const t=e.principal;if(t.class!=="broker"&&t.class!=="cron")return;const r=st({app:t.app,resolved:await tt(t),launched:t.scopes},n,"read");if("root"in r)return;const i="missing"in r?r.missing:null;throw new p(403,"scope_missing",i?`the child's directory ${n} needs missing scope ${i}`:`no permission of this run names the child's directory ${n}`,void 0,void 0,i?{scope:i}:void 0)}s(ke,"assertCallerReaches");const Q=new Map;async function It(e,n={},t={}){const r=Rt(_t(e.body),e.ceiling);if(e.principal.class==="broker"){const d=e.principal;if(r.prefer_warm===!0&&d.app!=="app:terminal"&&(r.prefer_warm=!1),r.parent!=null){const o=await m(r.parent);if(o.grantee!==d.app)throw new p(403,"other_app_run","cannot create a child under another app's node");if(!await $(d,o.grantee??"app:terminal",r.parent))throw E(`unknown node: ${r.parent}`,{received:r.parent})}if(r.creator!==void 0&&r.creator!==d.node)throw new p(403,"other_app_run","cannot create for another node");if(r.fork_from!==void 0){let o=null;try{o=await ie(await te(r.fork_from))}catch{}if(o?.grantee!==d.app||!await $(d,o.grantee,o.node_id))throw new p(403,"other_app_run","cannot fork another app's conversation")}r.creator=d.node}if(e.principal.class==="person"&&e.principal.sub!==void 0){const d=r.fork_from===void 0?null:await ie(await te(r.fork_from)).catch(()=>null);for(const o of[r.parent,r.creator,d?.node_id])if(o!=null&&await R(o)!==null&&!await et(e.principal,"edit",o))throw E(`unknown node: ${o}`,{received:o})}if(e.principal.class==="cron"){const d=e.principal;for(const l of["parent","creator","fork_from","node_id"])if(r[l]!=null)throw new p(403,"permission_error",`a cron cannot set ${l} on a node it starts`);r.prefer_warm=!1,r.node_id=await re(),d.isolated&&(r.isolated=!0,r.cwd=await z(r.node_id,d.app));const o=await en({grantee:d.app,sub:d.sub,grant_id:d.grant,scopes:d.scopes,from_exec:d.from_exec},{profile:r.profile,cwd:r.cwd,pin_cwd:r.pin_cwd,kind:r.kind,model:r.model,mode:r.mode});if(!o.allowed)throw nn(o);if(r.scopes!==void 0){const l=r.scopes.find(f=>!O(o.effectiveScopes,f)||!O(d.scopes,f));if(l!==void 0)throw new p(403,"scope_missing",`scope ${l} is not held by this cron`,void 0,void 0,{scope:l})}else d.scopes!==null&&(r.scopes=[...d.scopes])}r.creator!==void 0&&Qn(await m(r.creator),"crtr:act");const i=r.request_key?.trim();if(i===void 0||r.node_id!==void 0&&qe(r.node_id)&&await R(r.node_id)!==null&&(await de(i))?.nodeId!==r.node_id)return M(e,r,n,t);const a=Q.get(i);if(a!==void 0)return a;const c=At(e,r,i,n,t);Q.set(i,c);try{return await c}finally{Q.delete(i)}}s(It,"handleCreate");const Se="create_request_in_progress";async function Ot(e,n,t){const r=Date.now()+1e4;for(;t!==null;){const i=await R(t);if(i!==null){if(!j(e.principal)&&!await $(e.principal,i.grantee??"app:terminal",t))throw new p(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:await b(t)}}if(Date.now()>=r||(await de(n))?.nodeId!==t)break;await new Promise(a=>setTimeout(a,100))}throw new p(409,Se,"another create with this request_key is in progress; retry it")}s(Ot,"awaitForeignCreate");async function At(e,n,t,r,i){const a=await se(t);if(a.nodeId!==null&&await R(a.nodeId)!==null){if(a.state!=="warm_claimed"){const c=await R(a.nodeId);if(!j(e.principal)&&!await $(e.principal,c.grantee??"app:terminal",a.nodeId))throw new p(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:await b(a.nodeId)}}return M(e,n,r,i,a)}try{return await M(e,n,r,i,a)}catch(c){if(c instanceof p&&c.code===Se)throw c;const d=await se(t);throw(d.nodeId===null||await R(d.nodeId)===null)&&await oe(t,d.nodeId),c}}s(At,"handleKeyedCreateRequest");async function M(e,n,t,r,i=void 0){const a=r.deadlineAt??gt(n.deadline),c=bt(n.outcome_delivery),d=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:e.principal.kind==="exec"?null:(await he(e.principal.cron))?.created_by??null},n.node_id):null;d!==null&&(n.root=d.root===!0);const o=d?.parent??n.parent??void 0;if(o==null&&n.root!==!0)throw w("a node create requires a parent (or root: true for an independent root)");let l=null;if(n.output_schema!==void 0){try{l=JSON.parse(n.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 Ln(l)}const{profileId:f,kind:h,cwd:u,launch:S}=await Vn(n,{validateKind:Ae});await ke(e,u),n.worktree!==void 0&&await ke(e,D(n.pin_cwd??n.cwd??u));const _={...n,kind:h},v=c===void 0?void 0:vt(c,u),Z=("grant"in e.principal?e.principal.grant:null)??(o==null?null:(await R(o))?.grant_id??null);if(await V(be(await Le(S,Z,n.model)),{cwd:u,profileId:f},t.modelRegistry),await ct(Z)!=="app"&&!await wt(f===null?[]:await mt(f)))throw new p(412,"no_provider_credential",_e,{error:"no_provider_credential",message:_e,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let F=null;{const A=i===void 0||i.nodeId===null||i.state==="warm_claimed"?St(_,u,f):null,B=l===null&&r.beforeBrokerLaunch===void 0?void 0:async g=>{l!==null&&await Dn(g,"terminal",l),r.beforeBrokerLaunch?.(g)};if(i?.state==="warm_claimed"&&i.nodeId!==null){const g=A===null?null:await Bn(A,i.nodeId,B);if(g===null)throw await oe(i.requestKey,i.nodeId),new p(503,"create_resume_failed",`could not resume warm claim ${i.nodeId}; retry the create`);return await ae(i.requestKey,g),{status:201,body:await b(g)}}if(A!==null){const g=await Fn(A,{...a===void 0?{}:{deadlineAt:a},...v===void 0?{}:{outcomeDelivery:v},...i===void 0?{}:{requestKey:i.requestKey}},B);if(g!==null)return i!==void 0&&await ae(i.requestKey,g),me(A),{status:201,body:await b(g)};F=A}const T=i?.nodeId??n.node_id??(i===void 0?void 0:await re());if(i!==void 0&&i.nodeId===null){const g=await Be(i.requestKey,T);if(g!==T)return await Ot(e,i.requestKey,g)}const I=kt(T===void 0?_:{..._,node_id:T},o,u);d!==null&&(d.rootLifecycle!==void 0&&(I.rootLifecycle=d.rootLifecycle),d.scopes!==void 0&&_.scopes===void 0&&(I.scopes=d.scopes),d.run!==void 0&&(I.run=d.run),d.withinCreate!==void 0&&(I.withinCreate=d.withinCreate)),a!==void 0&&(I.deadlineAt=a),v!==void 0&&(I.outcomeDelivery=v),I.readiness=n.root===!0?"await":"launch";const q=await Me(I,B,()=>{F!==null&&me(F)});return i!==void 0&&await Fe(i.requestKey,q.node.node_id),{status:201,body:await b(q.node.node_id)}}}s(M,"handleCreateRequest");function k(e,n){const t=e.query.getAll(n);if(t.length>1)throw w(`${n} must appear at most once`);return t[0]}s(k,"singleQueryValue");function X(e,n){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw w(`${n} must be true or false`)}}s(X,"optionalBoolean");function G(e,n,t){if(e!==void 0){if(t.includes(e))return e;throw w(`${n} must be one of: ${t.join(", ")}`)}}s(G,"oneOf");function $t(e){const n=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","under_inclusive","hanging","include"]);for(const[_]of e.query)if(!n.has(_))throw w(`unknown nodes query parameter: ${_}`);const t=G(k(e,"status"),"status",["active","idle","done","dead","canceled"]),r=G(k(e,"lifecycle"),"lifecycle",["terminal","resident"]),i=k(e,"kind"),a=G(k(e,"mode"),"mode",["base","orchestrator"]),c=k(e,"profile_id"),d=k(e,"profile_prefix"),o=k(e,"parent"),l=X(k(e,"top_level"),"top_level"),f=k(e,"under"),h=X(k(e,"under_inclusive"),"under_inclusive"),u=X(k(e,"hanging"),"hanging"),S=G(k(e,"include"),"include",["activity"]);if(o!==void 0&&l===!0)throw w("parent and top_level=true cannot be combined");return{...t!==void 0?{status:t}:{},...r!==void 0?{lifecycle:r}:{},...i!==void 0?{kind:i}:{},...a!==void 0?{mode:a}:{},...c!==void 0?{profile_id:c}:{},...d!==void 0?{profile_prefix:d}:{},...o!==void 0?{parent:o}:{},...l!==void 0?{top_level:l}:{},...f!==void 0?{under:f}:{},...h!==void 0?{under_inclusive:h}:{},...u!==void 0?{hanging:u}:{},...S!==void 0?{include:S}:{}}}s($t,"parseListQuery");async function Nt(e){const n=$t(e);let t=await Ke({...n.status!==void 0?{status:n.status}:{},...n.lifecycle!==void 0?{lifecycle:n.lifecycle}:{},...n.kind!==void 0?{kind:n.kind}:{},...n.mode!==void 0?{mode:n.mode}:{},...n.profile_id!==void 0?{profileId:n.profile_id}:{},...n.profile_prefix!==void 0?{profilePrefix:n.profile_prefix}:{},...n.parent!==void 0?{parent:n.parent}:{},...n.top_level===!0?{topLevel:!0}:{},...n.under!==void 0?{under:n.under}:{},...n.under_inclusive===!0?{underInclusive:!0}:{},...n.hanging===!0?{hanging:!0}:{}});const r=await nt(e.principal);r!==null&&(t=t.filter(d=>r.has(d.node_id)));const i=n.include==="activity"?await Ze(t.map(d=>d.node_id)):null,a=t.length>0?Ce():new Set;return{status:200,body:await ge(t,async d=>{const o=await Zn(d,d.profile_id!==null&&a.has(d.profile_id));if(i!==null){const l=await we(d.node_id);o.activity={latest_report:l[0]??null,final_report:d.final_report===null?null:l.find(f=>f.name===d.final_report)??null,pending_human_count:i[d.node_id]??0}}return o})}}s(Nt,"handleList");async function Ct(e){const n=e.params.id,t=await it(e,n,{method:"GET",path:`/v1/nodes/${encodeURIComponent(n)}`,query:rt(e)});if(t.kind==="unknown")throw at(n,t.unreachable);if(t.kind==="remote"){if(t.status>=400)throw ot(t.status,t.body);return{status:t.status,body:dt(t.body,t.machine)}}return await m(n),{status:200,body:await b(n)}}s(Ct,"handleDetail");async function Et(e){const n=e.params.id;await m(n);const t=await cn(n);return{status:200,body:{node_id:n,snapshot:{messages:t.snapshot.messages,...t.snapshot.messageIds===void 0?{}:{messageIds:t.snapshot.messageIds},messageVisibility:t.snapshot.messageVisibility,turnVisibility:t.snapshot.turnVisibility,stats:t.snapshot.stats,state:t.snapshot.state,display:t.snapshot.display,...t.snapshot.queued===void 0?{}:{queued:t.snapshot.queued},...t.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:t.snapshot.toolGroupSummaries},...t.snapshot.turnReplies===void 0?{}:{turnReplies:t.snapshot.turnReplies},...t.snapshot.workingActivity===void 0?{}:{workingActivity:t.snapshot.workingActivity}},commands:t.commands.map(i=>({name:i.name,description:i.description,source:i.source})),captured_at:x()}}}s(Et,"handleSnapshot");async function Tt(e){const n=e.params.id,t=await fn(n);if(t===null)throw E(`unknown node: ${n}`,{received:n});return{status:200,body:t}}s(Tt,"handleSubject");function Pt(e){for(const[a]of e.query)if(a!=="cursor"&&a!=="limit")throw w(`unknown messages query parameter: ${a}`);const n=e.query.getAll("cursor"),t=e.query.getAll("limit");if(n.length>1)throw w("cursor must appear at most once");if(t.length>1)throw w("limit must appear at most once");if(t.length===0)return n.length===0?{}:{cursor:n[0]};const r=t[0],i=Number(r);if(!Number.isSafeInteger(i)||r==="")throw w("limit must be an integer from 1 through 500");return n.length===0?{limit:i}:{cursor:n[0],limit:i}}s(Pt,"parseMessagesQuery");async function Dt(e){const n=e.params.id,t=await sn(n,Pt(e));return{status:200,body:{node_id:n,messages:t.messages,...t.messageIds===void 0?{}:{message_ids:t.messageIds},message_visibility:t.messageVisibility,next_cursor:t.nextCursor,captured_at:x()}}}s(Dt,"handleMessages");async function Lt(e){const n=e.params.id;await m(n);const t=await ln(n);return{status:200,body:{node_id:n,session_file:t.sessionFile,session_jsonl:t.sessionJsonl,system_prompt:t.systemPrompt,captured_at:x()}}}s(Lt,"handleSession");async function jt(e){const n=e.params.id;return await m(n),{status:200,body:{node_id:n,markdown:await un(n)}}}s(jt,"handleTranscript");async function Mt(e){const n=e.params.id;await m(n);const t=s(async(i,a)=>({node_id:i,label:(await R(i))?.name??i,dir:await ce(i),self:a,files:await yt(i)}),"root"),r=await ht([await t(n,!0),...await ge(await le(n),async i=>await t(i.node_id,!1))],async i=>await Gt(i.node_id,i.dir)||i.files>0);return{status:200,body:{node_id:n,roots:r}}}s(Mt,"handleContext");async function Gt(e,n){try{return rn(await z(e),n)}catch(t){if(an(t))return!1;throw t}}s(Gt,"hasDir");async function Ft(e){const n=await m(e.params.id),t=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=t===null?void 0:n.scopes==null?[...t]:[...new Set([...n.scopes.filter(a=>O(t,a)),...t.filter(a=>O(n.scopes,a))])],i=await je(n.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:await b(i.node.node_id)}}s(Ft,"handleFork");const Bt=1e4;async function Kt(e){const n=e.params.id;await m(n);const t=e.body,r=t?.resume??!0,i=t?.reopen??!1;await _n(n,i,e.principal.class==="broker"?e.principal.node:null);const a=!r&&t?.cron_id!==void 0?await he(t.cron_id):null,c=await De(n,{resume:r,capacity:"refuse",...a!==null?{wakeReason:await Yn(a,"schedule_revive")}:{}});c.outcome!=="already-live"&&await xe(n,{failures:0,notBefore:null});const d=(await R(n))?.status??"active",o=(c.launch??L().get(n)?.handle)?.exited,l=c.outcome!=="frozen"&&await fe(n,o,Bt);return{status:200,body:qn(n,c,d,l)}}s(Kt,"handleRevive");async function xt(e){const n=e.params.id;return{status:200,body:{newNodeId:(await yn(n))?.newNodeId??null}}}s(xt,"handleRelaunchRoot");async function Vt(e){const n=e.params.id;await m(n);const t=e.body;if(t?.caller_pid!==void 0&&(!Number.isInteger(t.caller_pid)||t.caller_pid<=0))throw w("caller_pid must be a positive integer when provided");const r=Hn(),i=new Promise(c=>{e.res.once("close",()=>c())}),a=await Pe(n,{teardownAfter:i,rootEvent:t?.finish===!0?"finish":"cancel",callerPid:t?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:Xn(a)}}s(Vt,"handleClose");async function Wt(e){if(!j(e.principal))throw new p(403,"permission_error","only the person marks a conversation read");const n=e.params.id;return await m(n),await ze(n),{status:204}}s(Wt,"handleMarkRead");async function zt(e){const n=e.params.id;await m(n);const t=await hn(n);return{status:200,body:{recycled:t.recycled,finalized:t.finalized,new_root:t.newRoot,delivered:t.delivered}}}s(zt,"handleRecycle");async function Jt(e){const n=e.params.id;return await m(n),await J(n,{lifecycle:"terminal"}),await N(e,n,["lifecycle"]),{status:200,body:await b(n)}}s(Jt,"handleDemote");async function Ut(e,n={}){const t=e.params.id,r=await m(t),i=e.body??{};i.kind!==void 0&&await U(i.kind,r.cwd,r.profile_id??null),i.model!==void 0&&await ve(r,{kind:i.kind??r.kind,mode:"orchestrator",lifecycle:i.resident===!0?"resident":r.lifecycle,model:i.model},n.modelRegistry);const a=await mn(t,{...i.kind!==void 0?{kind:i.kind}:{},...i.resident===!0?{resident:!0}:{},...i.model!==void 0?{model:i.model}:{}});await N(e,t,["mode",...i.kind!==void 0?["kind"]:[],...i.resident===!0?["lifecycle"]:[],...i.model!==void 0?["model"]:[]]);const c=await Y(a.meta,await H(t));return c.roadmap_written=a.roadmapWritten,c.roadmap_ref=a.roadmapRef,c.goal_path=a.goalPath,{status:200,body:c}}s(Ut,"handlePromote");async function Yt(e){const n=e.params.id;return await m(n),{status:200,body:{request:await bn(n)}}}s(Yt,"handleBrokerStructuredRequest");async function Ht(e){const n=e.params.id,t=e.body??{};if(await gn(n,t.expected_execution_id),typeof t.text!="string")throw new p(400,"invalid_request","text must be a string");return await m(n),{status:200,body:{captured:await Sn(n,t.text)}}}s(Ht,"handleBrokerGoal");async function Qt(e,n={}){const t=e.params.id,r=await m(t),i=e.body??{};i.kind!==void 0&&await U(i.kind,r.cwd,r.profile_id??null),i.model!==void 0&&await ve(r,{kind:i.kind??r.kind,mode:i.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:i.model},n.modelRegistry);const a=i.note??"Refresh: continue against your roadmap or goal.";await vn(t,a);const c=await wn(t,{...i.promote===!0?{promote:!0}:{},...i.kind!==void 0?{kind:i.kind}:{},...i.model!==void 0?{model:i.model}:{}});return{status:200,body:await Y(c.meta,await H(t))}}s(Qt,"handleYield");async function Xt(e){const n=e.params.id;await m(n);const t=e.body;if(t===void 0||typeof t.controller!="string"||t.controller.trim()==="")throw w("a wait requires a controller node id");const r=await R(t.controller);if(r===null)throw E(`unknown controller: ${t.controller}`,{received:t.controller});if(r.status!=="active"&&r.status!=="idle")throw new p(422,"unprocessable",`controller ${t.controller} is ${r.status}`);return await We(n,t.controller),{status:200,body:await b(n)}}s(Xt,"handleWait");async function Zt(e){const n=e.principal,t=await pn(n.class==="broker"?async i=>i.grantee===n.app&&await $(n,i.grantee,i.node_id):n.class==="person"&&!j(n)?async i=>await $(n,i.grantee??"app:terminal",i.node_id):void 0);return{status:200,body:{revived:[...t.revived],failed:[...t.failed],frozen:[...t.frozen]}}}s(Zt,"handleReviveAll");const qt=new Set(["interrupt","steer","after-turn","next-turn"]);function ei(e){if(e===null)return null;const n=s(r=>{throw new y({error:"invalid_listen",message:r,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 n("listen must be an object or null");const t=Object.entries(e);if(t.length===0)return n("listen must name at least one level");for(const[r,i]of t)/^(?:[1-9]|10)$/.test(r)||n(`listen level must be 1..10: ${r}`),(typeof i!="string"||!qt.has(i))&&n(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(i)}`);return JSON.stringify(Object.fromEntries(t))}s(ei,"listenJson");async function N(e,n,t,r){t.length===0&&r===void 0||await W(async i=>{if(r?.(i),t.length===0)return;const a=await Je(i,n),c=await He(i,e),d=c.class==="person"?c.person:c.class==="app"?c.app:c.node;await Ue(i,d,a),await Ye(i,{event:"configured",object:a,actor:d,attrs:{changed:t.join(",")}})})}s(N,"recordConfigured");function Re(e){const n=L().get(e);if(n===void 0)return!1;try{return process.kill(n.pid,"SIGTERM"),!0}catch{return!1}}s(Re,"restartLiveBroker");function Ie(e,n){try{return ee(e)===ee(n)}catch{return!1}}s(Ie,"sameDirectory");async function ni(e,n={}){const t=e.params.id,r=e.body;let i;if(r===void 0)i={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))i=r;else throw new y({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:r,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(h=>h!=="profile"&&h!=="restart"&&i[h]!==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 o=await m(t),l=await zn(e,i.profile);Jn(l.profileId);const f=Un(l.profileId).manifest.grantee??"app:terminal";if(f!==(o.grantee??"app:terminal"))throw new y({error:"profile_grantee_mismatch",message:`profile ${l.profileId} belongs to ${f}, node ${t} to ${o.grantee}`,received:i.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(o.profile_id??null)!==l.profileId&&(xn(o.kind)?(await U(o.kind,o.cwd,l.profileId),await J(t,{profileId:l.profileId})):await C(t,{profile_id:l.profileId}),await N(e,t,["profile"])),i.restart===!0&&Re(t),{status:200,body:await b(t)}}if(Object.prototype.hasOwnProperty.call(i,"cwd")){const o=i.cwd;if(typeof o!="string"||o==="")throw new y({error:"cwd_invalid",message:"cwd must be a non-empty string",received:o,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(i).some(u=>u!=="cwd"&&u!=="keep_session"&&u!=="restart"&&i[u]!==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 m(t),f=P(l.cwd);if(i.keep_session===!0||f&&K(o)&&P(o)&&Ie(l.cwd,o)){if(!K(o))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${o}`,received:o,field:"cwd",next:"Send an absolute path."});const u=D(o);let S=!1;try{S=ne(u).isDirectory()}catch{}if(!S)throw new y({error:"cwd_missing",message:`cwd is not an existing directory: ${u}`,received:o,field:"cwd",next:"Send an existing absolute directory."});if(f&&!Ie(l.cwd,u))throw new y({error:"cwd_not_same_directory",message:`${u} is not the same directory as the recorded ${l.cwd}; --keep-session only relocates an alias`,received:o,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:`${t} owns an open managed worktree and cannot relocate its cwd`,received:o,field:"cwd",next:"Reconcile the managed worktree first."});const _=l.cwd;return _!==u&&(await W(async v=>{await C(t,{cwd:u}),await v.prepare("UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(u,t,_),await Qe(t,_,u)}),await N(e,t,["cwd"])),i.restart===!0&&Re(t),{status:200,body:await b(t)}}if(await L().has(t)){const u=`${t} cannot repair its cwd while its broker is live`;throw new p(409,"cwd_node_live",u,{error:"cwd_node_live",message:u,received:o,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:`${t} is a fork and cannot repair its cwd; recorded cwd: ${l.cwd}`,received:o,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:`${t} owns an open managed worktree and cannot repair its cwd`,received:o,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(P(l.cwd))throw new y({error:"cwd_still_present",message:`${t} recorded cwd still exists: ${l.cwd}; cwd repair is not a relocation command`,received:o,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!K(o))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${o}`,received:o,field:"cwd",next:"Send an absolute path."});const h=D(o);if(!P(h))throw new y({error:"cwd_missing",message:`cwd does not exist: ${h}`,received:o,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!ne(h).isDirectory())throw new y({error:"cwd_not_a_directory",message:`cwd is not a directory: ${h}`,received:o,field:"cwd",next:"Send an existing absolute directory."})}catch(u){throw u instanceof y?u:new y({error:"cwd_missing",message:`cwd does not exist: ${h}`,received:o,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return await W(async()=>{await C(t,{cwd:h}),await Xe(t)}),await N(e,t,["cwd"]),{status:200,body:await b(t)}}let a=await m(t);const c=i.listen===void 0?void 0:ei(i.listen);if(i.scopes!==void 0){const o=ye(i.scopes),l=a.grantee==="app:terminal"?await ut(a):a.grant_id?await lt(a.grant_id):null;if(!o.every(f=>O(a.scopes,f)&&l!==null&&O(l.resolved,f)))throw new y({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:o,field:"scopes",next:"Send only scopes the node currently holds."});if(o.includes("crtr:act")&&!O(o,"crtr:llm"))throw new p(400,"invalid_scope","crtr:act requires crtr:llm");a=await C(t,{scopes:o})}if(i.situational_context!==void 0&&await Ee(t,Te(i.situational_context)),i.model!==void 0){const o=(await ue(a.cwd,a.profile_id??null)).modelLadders,l=$n(i.model,o),f=await ft(a.grant_id,i.model,l===void 0),h=f?{family:pt,strength:f.strength}:l,u=f?f.model:Nn(i.model,o);await V({kind:"concrete",spec:u},{cwd:a.cwd,profileId:a.profile_id??null},n.modelRegistry);const S=L();let _=!1;if(await S.isClaimed(t)&&await fe(t,S.get(t)?.handle.exited)&&(_=await Tn(t,u,h).then(()=>!0,v=>{if(v instanceof Pn)return!1;throw v})),!_){if(await S.isClaimed(t)){const v=`${t}'s broker did not accept the model switch; the model was not changed`;throw new p(409,"broker_not_ready",v,{error:"broker_not_ready",message:v,received:i.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!u.includes("/"))throw w(`model must resolve to a provider/id spec: ${i.model}`);await En(t,u,h)}a=await m(t)}if(i.kind!==void 0||i.mode!==void 0||i.lifecycle!==void 0){i.kind!==void 0&&await Ae(i.kind);const o=i.kind??a.kind,l=i.mode??a.mode,f=i.lifecycle??a.lifecycle;let h;l==="orchestrator"&&!await In(t)&&(h=s(async()=>{const u=await kn(t);await Rn(t,u!==null&&u.trim()!==""?{goal:u.trim()}:{})},"beforePersist")),a=await J(t,{...i.kind!==void 0?{kind:o}:{},...i.mode!==void 0?{mode:l}:{},...i.lifecycle!==void 0?{lifecycle:f}:{}},h)}i.name!==void 0&&(a=await C(t,{name:i.name}),a.window&&On(a.window,Wn(a)));const d=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(o=>i[o]!==void 0);return await N(e,t,d,c===void 0?void 0:async o=>{await o.prepare("UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(c,t)}),{status:200,body:await b(t)}}s(ni,"handleConfig");async function Oe(){return(await ue(process.cwd(),Ne()||null)).kinds}s(Oe,"daemonKinds");async function Ae(e){const n=Object.keys(await Oe());if(!n.includes(e))throw w(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${n.sort().join(", ")}.`})}s(Ae,"assertKindServer");async function ti(){const e=await Oe();return{status:200,body:{kinds:Object.keys(e).sort().map(t=>({kind:t,when_to_use:e[t]?.whenToUse??null,available_to:e[t]?.availableTo??null}))}}}s(ti,"handleListKinds");const Rr=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:It},{method:"GET",pattern:"/v1/nodes",handler:Nt},{method:"GET",pattern:"/v1/kinds",handler:s(()=>ti(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:Zt},{method:"GET",pattern:"/v1/nodes/:id",handler:Ct},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:Et},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:Tt},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:Dt},{method:"GET",pattern:"/v1/nodes/:id/session",handler:Lt},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:jt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:Mt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:Ft},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Kt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:xt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:Vt},{method:"POST",pattern:"/v1/nodes/:id/read",handler:Wt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:zt},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Jt},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Ut},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Qt},{method:"GET",pattern:"/v1/nodes/:id/broker/structured-request",handler:Yt},{method:"POST",pattern:"/v1/nodes/:id/broker/goal",handler:Ht},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Xt},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:ni}];export{ni as handleConfig,It as handleCreate,Ft as handleFork,Nt as handleList,Ut as handlePromote,Qt as handleYield,Rr as nodeRoutes,Ar as resolveCreateKind};
1
+ var $e=Object.defineProperty;var s=(e,n)=>$e(e,"name",{value:n,configurable:!0});import{envProfileId as Ne}from"../../../shared/env.js";import{pausedCanvasProfiles as Ce}from"../../../core/profiles/manifest.js";import{existsSync as C,realpathSync as ee,statSync as ne}from"node:fs";import{isAbsolute as x,resolve as D}from"node:path";import{appendSituationalContext as Ee,formatSituationalProse as Te}from"../../../core/runtime/situational-context.js";import{closeNode as Pe}from"../../../core/runtime/close.js";import{reviveNode as De}from"../../../core/runtime/revive.js";import{nowIso as K}from"../../../core/fs-utils.js";import{appPaidLaunch as Le,assertLaunchModelRegistered as V,forkNode as je,resolveForkSource as te,spawnChildPrepared as Me}from"../../../core/runtime/spawn.js";import{forkSourceNode as ie,newNodeId as re}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as oe,childrenOf as Ge,completeCreateRequest as ae,findCreateRequest as de,getNode as R,recordCreateRequestNode as Fe,reserveCreateRequest as se,reserveCreateRequestNode as Be,listNodes as xe,recordRespawnAttempt as Ke,subscribersOf as Ve,subscriptionsOf as le,updateNode as E}from"../../../core/canvas/canvas.js";import{armControllerWait as We}from"../../../core/canvas/waits.js";import{withCanvasWrite as W}from"../../../core/canvas/db.js";import{markNodeRead as ze}from"../../../core/canvas/recovery.js";import{nodeObject as Je}from"../../../core/graph/objects.js";import{recordActedOn as Ue}from"../../../core/graph/edges.js";import{publish as Ye}from"../../../core/graph/events.js";import{readerFor as He}from"../reader.js";import{relocateSessionCwd as Qe,unbindSession as Xe}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as Ze}from"../../../core/canvas/attention.js";import{isSafeNodeId as qe}from"../../../core/canvas/paths.js";import{contextDir as ce,nodeAgentDir as z}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as en,cronRefusalError as nn}from"../../cron/authority.js";import{cronBirthPlacement as tn}from"../../cron/armed-context.js";import{existsBeneath as rn,isAbsentOrRefused as on,isBeneathRefusal as an,readdirBeneath as dn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as sn,readNodeSession as ln,readNodeSnapshot as cn,transcriptMarkdown as un}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as fn}from"../../../core/substrate/subject.js";import{reviveAll as pn}from"../../../core/runtime/revive-all.js";import{promoteAsync as mn,requestYieldAsync as wn,reshapeNodeAsync as J}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{requireCurrentExecution as gn}from"./broker-recovery.js";import{readOutputRequest as bn}from"../../../core/runtime/output-result.js";import{writeYieldMessage as vn,readGoal as kn,captureGoalIfAbsent as Sn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as Rn,hasRoadmap as In}from"../../../core/runtime/roadmap.js";import{renameWindow as On}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as An,explicitModelIntent as $n,normalizeModel as Nn,readMergedLaunchConfigAsync as ue}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as Cn}from"../../../core/model-routes.js";import{persistDormantModel as En,setModelLive as Tn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as fe}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as Pn}from"../../../core/runtime/broker-request.js";import{boundFleet as L}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as Dn}from"../../structured-requests/sidecar.js";import{assertOutputSchemaAccepted as Ln}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as pe}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as jn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Mn}from"../../../core/human-actions.js";import{parseDurationMs as Gn}from"../../../core/wake.js";import{claimWarmNode as Fn,refillWarmPool as me,resumeWarmClaim as Bn,warmPoolEnabled as xn}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as U,isLaunchKind as Kn,resolveLaunchTarget as Vn}from"../../../core/runtime/launch-target.js";import{fullName as Wn}from"../../../core/canvas/labels.js";import{reportsForNode as we}from"./reports.js";import{requireUsableProfile as zn}from"./profiles.js";import{assertProfileActive as Jn,loadExactProfileManifest as Un}from"../../../core/profiles/manifest.js";import{getCron as he}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Yn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as Hn}from"../../control.js";import{notFound as T,usage as w}from"../../../core/errors.js";import{assertScope as Qn,validateScopes as ye}from"../../../core/scopes.js";import{scopeAllowed as O}from"../../../shared/env.js";import{toCloseResultDTO as Xn,toNodeDetailDTO as Y,toNodeSummaryDTO as Zn,toReviveResultDTO as qn}from"../map.js";import{ApiError as p}from"../../../api/index.js";import{InputError as y}from"../../../core/io.js";import{runsOnBlaxel as et}from"../environment-of.js";import{actsAsPerson as j,canReadNode as $,mayOnNode as nt,readableNodeIds as tt,resolvedScopes as it}from"../router.js";import{forwardVerb as rt,queryWithoutMachine as ot,relayError as at,unknownError as dt,withMachine as st}from"../../peer/forward.js";import{fileRoot as lt}from"../../../core/spaces/file-root.js";import{activeGrant as ct,payerOfGrant as ut}from"../../../core/grants/mirror.js";import{nodeTerminalGrant as ft}from"../../../core/grants/terminal.js";import{appRungForGrant as pt}from"../../../core/llm/app-rungs.js";import{APP_FAMILY as mt}from"../../../core/model-routes.js";import{listProfileEnvNames as wt}from"../../../core/profiles/env-store.js";import{hasConfiguredProviderCredential as ht,NO_PROVIDER_CREDENTIAL_MESSAGE as _e}from"../../../core/runtime/provider-credential-gate.js";import{filterAsync as yt,mapAsync as ge}from"../../../core/async-array.js";async function m(e){const n=await R(e);if(n===null)throw T(`unknown node: ${e}`,{received:e});return n}s(m,"requireMeta");async function H(e){return{subscribesTo:await le(e),subscribers:await Ve(e),children:await Ge(e)}}s(H,"edgesFor");async function b(e){const n=await m(e);return await Y(n,await H(e))}s(b,"detailOf");async function _t(e){let n=(await we(e)).length;try{n+=dn(await z(e),await ce(e)).length}catch(t){if(!on(t))throw t}return n}s(_t,"countFiles");function gt(e){if(typeof e!="object"||e===null)throw w("a node create requires a JSON body");const n=e;if(n.kind!==void 0&&(typeof n.kind!="string"||n.kind.trim()===""))throw w("kind must be a non-empty string when provided");if(n.description!==void 0&&(typeof n.description!="string"||n.description.trim()===""))throw w("description must be a non-empty string when provided");if(n.creator!==void 0&&(typeof n.creator!="string"||n.creator.trim()===""))throw w("creator must be a non-empty node id when provided");if(n.scopes!==void 0&&ye(n.scopes),n.isolated!==void 0&&typeof n.isolated!="boolean")throw new p(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const t=n.root_lifecycle;if(t!==void 0&&t!=="resident"&&t!=="terminal")throw w("root_lifecycle must be 'resident' or 'terminal'");if(n.request_key!==void 0&&(typeof n.request_key!="string"||n.request_key.trim()===""||n.request_key.length>128))throw w("request_key must be a non-empty string of at most 128 characters when provided");return n}s(gt,"parseCreateBody");function bt(e){if(e===void 0)return;const n=Gn(e),t=n===null?null:new Date(Date.now()+n);if(n===null||!Number.isFinite(n)||n<=0||t===null||!Number.isFinite(t.getTime()))throw new p(422,"invalid_deadline","`deadline` must be a positive representable duration");return t.toISOString()}s(bt,"parseDeadline");function vt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new p(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!jn.test(e.action))throw new p(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let n;try{n=JSON.stringify(e.payload)}catch{throw new p(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(n===void 0)throw new p(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(n,"utf8")>pe)throw new p(413,"payload_too_large",`serialized payload exceeds ${pe} bytes`)}return e}}s(vt,"parseOutcomeDelivery");function kt(e,n){const t=Mn(e.action,n);if(!("kind"in t))return{actionName:e.action,argv:t.argv,cwd:t.cwd,configOrigin:t.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw t.kind==="unknown_action"?new p(422,"unknown_action",`no action named ${e.action} is declared from ${n}`):new p(422,"invalid_action",`${e.action} is declared in ${t.configOrigin} but unusable: ${t.reason}`,{reason:t.reason,configOrigin:t.configOrigin})}s(kt,"resolveOutcomeDelivery");function St(e,n,t){const r={kind:e.kind,cwd:t,prompt:e.prompt??""};return e.mode!==void 0&&(r.mode=e.mode),e.name!==void 0&&(r.name=e.name),e.description!==void 0&&(r.description=e.description),n!==void 0&&(r.parent=n),e.creator!==void 0&&(r.creator=e.creator),e.scopes!==void 0&&(r.scopes=e.scopes),e.isolated!==void 0&&(r.isolated=e.isolated),e.root===!0&&(r.root=!0),e.root_lifecycle!==void 0&&(r.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(r.worktree=!0),typeof e.worktree=="string"&&(r.worktreeBase=e.worktree),e.worktree!==void 0&&(r.worktreeCwd=D(e.pin_cwd??e.cwd??t)),e.fork_from!==void 0&&(r.forkFrom=e.fork_from),e.model!==void 0&&(r.model=e.model),e.profile!==void 0&&(r.profile=e.profile),e.situational_context!==void 0&&(r.situationalContext=e.situational_context),e.node_id!==void 0&&(r.nodeId=e.node_id),r}s(St,"buildRecipe");function Rt(e,n,t){return!xn()||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:n,profileId:t,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}s(Rt,"warmRequestFor");import{resolveCreateKind as Nr}from"../../../core/runtime/launch-target.js";function be(e){const n=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Cn(e.model,n,e.modelExact===!0)}s(be,"requestFromLaunch");function It(e,n){if(n===null)return e;if(e.scopes===void 0)return{...e,scopes:[...n]};const t=e.scopes.filter(r=>!O(n,r));if(t.length===0)return e;throw new p(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${t.join(", ")}`,{scopes:t,ceiling:n})}s(It,"withinCeiling");async function ve(e,n,t){const r=(await An(n.kind,n.mode,{lifecycle:n.lifecycle,hasManager:e.parent!==null,model:n.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await V(be(r),{cwd:e.cwd,profileId:e.profile_id??null},t)}s(ve,"assertNodeModelChangeRegistered");async function ke(e,n){const t=e.principal;if(t.class!=="broker"&&t.class!=="cron")return;const r=lt({app:t.app,resolved:await it(t),launched:t.scopes},n,"read");if("root"in r)return;const i="missing"in r?r.missing:null;throw new p(403,"scope_missing",i?`the child's directory ${n} needs missing scope ${i}`:`no permission of this run names the child's directory ${n}`,void 0,void 0,i?{scope:i}:void 0)}s(ke,"assertCallerReaches");const Q=new Map;async function Ot(e,n={},t={}){const r=It(gt(e.body),e.ceiling);if(e.principal.class==="broker"){const d=e.principal;if(r.prefer_warm===!0&&d.app!=="app:terminal"&&(r.prefer_warm=!1),r.parent!=null){const o=await m(r.parent);if(o.grantee!==d.app)throw new p(403,"other_app_run","cannot create a child under another app's node");if(!await $(d,o.grantee??"app:terminal",r.parent))throw T(`unknown node: ${r.parent}`,{received:r.parent})}if(r.creator!==void 0&&r.creator!==d.node)throw new p(403,"other_app_run","cannot create for another node");if(r.fork_from!==void 0){let o=null;try{o=await ie(await te(r.fork_from))}catch{}if(o?.grantee!==d.app||!await $(d,o.grantee,o.node_id))throw new p(403,"other_app_run","cannot fork another app's conversation")}r.creator=d.node}if(e.principal.class==="person"&&e.principal.sub!==void 0){const d=r.fork_from===void 0?null:await ie(await te(r.fork_from)).catch(()=>null);for(const o of[r.parent,r.creator,d?.node_id])if(o!=null&&await R(o)!==null&&!await nt(e.principal,"edit",o))throw T(`unknown node: ${o}`,{received:o})}if(e.principal.class==="cron"){const d=e.principal;for(const l of["parent","creator","fork_from","node_id"])if(r[l]!=null)throw new p(403,"permission_error",`a cron cannot set ${l} on a node it starts`);r.prefer_warm=!1,r.node_id=await re(),d.isolated&&(r.isolated=!0,r.cwd=await z(r.node_id,d.app));const o=await en({grantee:d.app,sub:d.sub,grant_id:d.grant,scopes:d.scopes,from_exec:d.from_exec},{profile:r.profile,cwd:r.cwd,pin_cwd:r.pin_cwd,kind:r.kind,model:r.model,mode:r.mode});if(!o.allowed)throw nn(o);if(r.scopes!==void 0){const l=r.scopes.find(f=>!O(o.effectiveScopes,f)||!O(d.scopes,f));if(l!==void 0)throw new p(403,"scope_missing",`scope ${l} is not held by this cron`,void 0,void 0,{scope:l})}else d.scopes!==null&&(r.scopes=[...d.scopes])}r.creator!==void 0&&Qn(await m(r.creator),"crtr:act");const i=r.request_key?.trim();if(i===void 0||r.node_id!==void 0&&qe(r.node_id)&&await R(r.node_id)!==null&&(await de(i))?.nodeId!==r.node_id)return M(e,r,n,t);const a=Q.get(i);if(a!==void 0)return a;const u=$t(e,r,i,n,t);Q.set(i,u);try{return await u}finally{Q.delete(i)}}s(Ot,"handleCreate");const Se="create_request_in_progress";async function At(e,n,t){const r=Date.now()+1e4;for(;t!==null;){const i=await R(t);if(i!==null){if(!j(e.principal)&&!await $(e.principal,i.grantee??"app:terminal",t))throw new p(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:await b(t)}}if(Date.now()>=r||(await de(n))?.nodeId!==t)break;await new Promise(a=>setTimeout(a,100))}throw new p(409,Se,"another create with this request_key is in progress; retry it")}s(At,"awaitForeignCreate");async function $t(e,n,t,r,i){const a=await se(t);if(a.nodeId!==null&&await R(a.nodeId)!==null){if(a.state!=="warm_claimed"){const u=await R(a.nodeId);if(!j(e.principal)&&!await $(e.principal,u.grantee??"app:terminal",a.nodeId))throw new p(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:await b(a.nodeId)}}return M(e,n,r,i,a)}try{return await M(e,n,r,i,a)}catch(u){if(u instanceof p&&u.code===Se)throw u;const d=await se(t);throw(d.nodeId===null||await R(d.nodeId)===null)&&await oe(t,d.nodeId),u}}s($t,"handleKeyedCreateRequest");async function M(e,n,t,r,i=void 0){const a=r.deadlineAt??bt(n.deadline),u=vt(n.outcome_delivery),d=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:e.principal.kind==="exec"?null:(await he(e.principal.cron))?.created_by??null},n.node_id):null;d!==null&&(n.root=d.root===!0);const o=d?.parent??n.parent??void 0;if(o==null&&n.root!==!0)throw w("a node create requires a parent (or root: true for an independent root)");let l=null;if(n.output_schema!==void 0){try{l=JSON.parse(n.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 Ln(l)}const{profileId:f,kind:h,cwd:c,launch:S}=await Vn(n,{validateKind:Ae});if(n.pin_cwd!==void 0&&n.pin_cwd!==""&&n.worktree===void 0&&n.isolated!==!0&&!C(c)&&!await et(f))throw new y({error:"cwd_missing",message:`cwd is not an existing directory: ${c}`,received:c,field:"cwd",next:"Pass an existing directory with --cwd."});await ke(e,c),n.worktree!==void 0&&await ke(e,D(n.pin_cwd??n.cwd??c));const _={...n,kind:h},v=u===void 0?void 0:kt(u,c),Z=("grant"in e.principal?e.principal.grant:null)??(o==null?null:(await R(o))?.grant_id??null);if(await V(be(await Le(S,Z,n.model)),{cwd:c,profileId:f},t.modelRegistry),await ut(Z)!=="app"&&!await ht(f===null?[]:await wt(f)))throw new p(412,"no_provider_credential",_e,{error:"no_provider_credential",message:_e,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let F=null;{const A=i===void 0||i.nodeId===null||i.state==="warm_claimed"?Rt(_,c,f):null,B=l===null&&r.beforeBrokerLaunch===void 0?void 0:async g=>{l!==null&&await Dn(g,"terminal",l),r.beforeBrokerLaunch?.(g)};if(i?.state==="warm_claimed"&&i.nodeId!==null){const g=A===null?null:await Bn(A,i.nodeId,B);if(g===null)throw await oe(i.requestKey,i.nodeId),new p(503,"create_resume_failed",`could not resume warm claim ${i.nodeId}; retry the create`);return await ae(i.requestKey,g),{status:201,body:await b(g)}}if(A!==null){const g=await Fn(A,{...a===void 0?{}:{deadlineAt:a},...v===void 0?{}:{outcomeDelivery:v},...i===void 0?{}:{requestKey:i.requestKey}},B);if(g!==null)return i!==void 0&&await ae(i.requestKey,g),me(A),{status:201,body:await b(g)};F=A}const P=i?.nodeId??n.node_id??(i===void 0?void 0:await re());if(i!==void 0&&i.nodeId===null){const g=await Be(i.requestKey,P);if(g!==P)return await At(e,i.requestKey,g)}const I=St(P===void 0?_:{..._,node_id:P},o,c);d!==null&&(d.rootLifecycle!==void 0&&(I.rootLifecycle=d.rootLifecycle),d.scopes!==void 0&&_.scopes===void 0&&(I.scopes=d.scopes),d.run!==void 0&&(I.run=d.run),d.withinCreate!==void 0&&(I.withinCreate=d.withinCreate)),a!==void 0&&(I.deadlineAt=a),v!==void 0&&(I.outcomeDelivery=v),I.readiness=n.root===!0?"await":"launch";const q=await Me(I,B,()=>{F!==null&&me(F)});return i!==void 0&&await Fe(i.requestKey,q.node.node_id),{status:201,body:await b(q.node.node_id)}}}s(M,"handleCreateRequest");function k(e,n){const t=e.query.getAll(n);if(t.length>1)throw w(`${n} must appear at most once`);return t[0]}s(k,"singleQueryValue");function X(e,n){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw w(`${n} must be true or false`)}}s(X,"optionalBoolean");function G(e,n,t){if(e!==void 0){if(t.includes(e))return e;throw w(`${n} must be one of: ${t.join(", ")}`)}}s(G,"oneOf");function Nt(e){const n=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","under_inclusive","hanging","include"]);for(const[_]of e.query)if(!n.has(_))throw w(`unknown nodes query parameter: ${_}`);const t=G(k(e,"status"),"status",["active","idle","done","dead","canceled"]),r=G(k(e,"lifecycle"),"lifecycle",["terminal","resident"]),i=k(e,"kind"),a=G(k(e,"mode"),"mode",["base","orchestrator"]),u=k(e,"profile_id"),d=k(e,"profile_prefix"),o=k(e,"parent"),l=X(k(e,"top_level"),"top_level"),f=k(e,"under"),h=X(k(e,"under_inclusive"),"under_inclusive"),c=X(k(e,"hanging"),"hanging"),S=G(k(e,"include"),"include",["activity"]);if(o!==void 0&&l===!0)throw w("parent and top_level=true cannot be combined");return{...t!==void 0?{status:t}:{},...r!==void 0?{lifecycle:r}:{},...i!==void 0?{kind:i}:{},...a!==void 0?{mode:a}:{},...u!==void 0?{profile_id:u}:{},...d!==void 0?{profile_prefix:d}:{},...o!==void 0?{parent:o}:{},...l!==void 0?{top_level:l}:{},...f!==void 0?{under:f}:{},...h!==void 0?{under_inclusive:h}:{},...c!==void 0?{hanging:c}:{},...S!==void 0?{include:S}:{}}}s(Nt,"parseListQuery");async function Ct(e){const n=Nt(e);let t=await xe({...n.status!==void 0?{status:n.status}:{},...n.lifecycle!==void 0?{lifecycle:n.lifecycle}:{},...n.kind!==void 0?{kind:n.kind}:{},...n.mode!==void 0?{mode:n.mode}:{},...n.profile_id!==void 0?{profileId:n.profile_id}:{},...n.profile_prefix!==void 0?{profilePrefix:n.profile_prefix}:{},...n.parent!==void 0?{parent:n.parent}:{},...n.top_level===!0?{topLevel:!0}:{},...n.under!==void 0?{under:n.under}:{},...n.under_inclusive===!0?{underInclusive:!0}:{},...n.hanging===!0?{hanging:!0}:{}});const r=await tt(e.principal);r!==null&&(t=t.filter(d=>r.has(d.node_id)));const i=n.include==="activity"?await Ze(t.map(d=>d.node_id)):null,a=t.length>0?Ce():new Set;return{status:200,body:await ge(t,async d=>{const o=await Zn(d,d.profile_id!==null&&a.has(d.profile_id));if(i!==null){const l=await we(d.node_id);o.activity={latest_report:l[0]??null,final_report:d.final_report===null?null:l.find(f=>f.name===d.final_report)??null,pending_human_count:i[d.node_id]??0}}return o})}}s(Ct,"handleList");async function Et(e){const n=e.params.id,t=await rt(e,n,{method:"GET",path:`/v1/nodes/${encodeURIComponent(n)}`,query:ot(e)});if(t.kind==="unknown")throw dt(n,t.unreachable);if(t.kind==="remote"){if(t.status>=400)throw at(t.status,t.body);return{status:t.status,body:st(t.body,t.machine)}}return await m(n),{status:200,body:await b(n)}}s(Et,"handleDetail");async function Tt(e){const n=e.params.id;await m(n);const t=await cn(n);return{status:200,body:{node_id:n,snapshot:{messages:t.snapshot.messages,...t.snapshot.messageIds===void 0?{}:{messageIds:t.snapshot.messageIds},messageVisibility:t.snapshot.messageVisibility,turnVisibility:t.snapshot.turnVisibility,stats:t.snapshot.stats,state:t.snapshot.state,display:t.snapshot.display,...t.snapshot.queued===void 0?{}:{queued:t.snapshot.queued},...t.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:t.snapshot.toolGroupSummaries},...t.snapshot.turnReplies===void 0?{}:{turnReplies:t.snapshot.turnReplies},...t.snapshot.workingActivity===void 0?{}:{workingActivity:t.snapshot.workingActivity}},commands:t.commands.map(i=>({name:i.name,description:i.description,source:i.source})),captured_at:K()}}}s(Tt,"handleSnapshot");async function Pt(e){const n=e.params.id,t=await fn(n);if(t===null)throw T(`unknown node: ${n}`,{received:n});return{status:200,body:t}}s(Pt,"handleSubject");function Dt(e){for(const[a]of e.query)if(a!=="cursor"&&a!=="limit")throw w(`unknown messages query parameter: ${a}`);const n=e.query.getAll("cursor"),t=e.query.getAll("limit");if(n.length>1)throw w("cursor must appear at most once");if(t.length>1)throw w("limit must appear at most once");if(t.length===0)return n.length===0?{}:{cursor:n[0]};const r=t[0],i=Number(r);if(!Number.isSafeInteger(i)||r==="")throw w("limit must be an integer from 1 through 500");return n.length===0?{limit:i}:{cursor:n[0],limit:i}}s(Dt,"parseMessagesQuery");async function Lt(e){const n=e.params.id,t=await sn(n,Dt(e));return{status:200,body:{node_id:n,messages:t.messages,...t.messageIds===void 0?{}:{message_ids:t.messageIds},message_visibility:t.messageVisibility,next_cursor:t.nextCursor,captured_at:K()}}}s(Lt,"handleMessages");async function jt(e){const n=e.params.id;await m(n);const t=await ln(n);return{status:200,body:{node_id:n,session_file:t.sessionFile,session_jsonl:t.sessionJsonl,system_prompt:t.systemPrompt,captured_at:K()}}}s(jt,"handleSession");async function Mt(e){const n=e.params.id;return await m(n),{status:200,body:{node_id:n,markdown:await un(n)}}}s(Mt,"handleTranscript");async function Gt(e){const n=e.params.id;await m(n);const t=s(async(i,a)=>({node_id:i,label:(await R(i))?.name??i,dir:await ce(i),self:a,files:await _t(i)}),"root"),r=await yt([await t(n,!0),...await ge(await le(n),async i=>await t(i.node_id,!1))],async i=>await Ft(i.node_id,i.dir)||i.files>0);return{status:200,body:{node_id:n,roots:r}}}s(Gt,"handleContext");async function Ft(e,n){try{return rn(await z(e),n)}catch(t){if(an(t))return!1;throw t}}s(Ft,"hasDir");async function Bt(e){const n=await m(e.params.id),t=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=t===null?void 0:n.scopes==null?[...t]:[...new Set([...n.scopes.filter(a=>O(t,a)),...t.filter(a=>O(n.scopes,a))])],i=await je(n.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:await b(i.node.node_id)}}s(Bt,"handleFork");const xt=1e4;async function Kt(e){const n=e.params.id;await m(n);const t=e.body,r=t?.resume??!0,i=t?.reopen??!1;await _n(n,i,e.principal.class==="broker"?e.principal.node:null);const a=!r&&t?.cron_id!==void 0?await he(t.cron_id):null,u=await De(n,{resume:r,capacity:"refuse",...a!==null?{wakeReason:await Yn(a,"schedule_revive")}:{}});u.outcome!=="already-live"&&await Ke(n,{failures:0,notBefore:null});const d=(await R(n))?.status??"active",o=(u.launch??L().get(n)?.handle)?.exited,l=u.outcome!=="frozen"&&await fe(n,o,xt);return{status:200,body:qn(n,u,d,l)}}s(Kt,"handleRevive");async function Vt(e){const n=e.params.id;return{status:200,body:{newNodeId:(await yn(n))?.newNodeId??null}}}s(Vt,"handleRelaunchRoot");async function Wt(e){const n=e.params.id;await m(n);const t=e.body;if(t?.caller_pid!==void 0&&(!Number.isInteger(t.caller_pid)||t.caller_pid<=0))throw w("caller_pid must be a positive integer when provided");const r=Hn(),i=new Promise(u=>{e.res.once("close",()=>u())}),a=await Pe(n,{teardownAfter:i,rootEvent:t?.finish===!0?"finish":"cancel",callerPid:t?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:Xn(a)}}s(Wt,"handleClose");async function zt(e){if(!j(e.principal))throw new p(403,"permission_error","only the person marks a conversation read");const n=e.params.id;return await m(n),await ze(n),{status:204}}s(zt,"handleMarkRead");async function Jt(e){const n=e.params.id;await m(n);const t=await hn(n);return{status:200,body:{recycled:t.recycled,finalized:t.finalized,new_root:t.newRoot,delivered:t.delivered}}}s(Jt,"handleRecycle");async function Ut(e){const n=e.params.id;return await m(n),await J(n,{lifecycle:"terminal"}),await N(e,n,["lifecycle"]),{status:200,body:await b(n)}}s(Ut,"handleDemote");async function Yt(e,n={}){const t=e.params.id,r=await m(t),i=e.body??{};i.kind!==void 0&&await U(i.kind,r.cwd,r.profile_id??null),i.model!==void 0&&await ve(r,{kind:i.kind??r.kind,mode:"orchestrator",lifecycle:i.resident===!0?"resident":r.lifecycle,model:i.model},n.modelRegistry);const a=await mn(t,{...i.kind!==void 0?{kind:i.kind}:{},...i.resident===!0?{resident:!0}:{},...i.model!==void 0?{model:i.model}:{}});await N(e,t,["mode",...i.kind!==void 0?["kind"]:[],...i.resident===!0?["lifecycle"]:[],...i.model!==void 0?["model"]:[]]);const u=await Y(a.meta,await H(t));return u.roadmap_written=a.roadmapWritten,u.roadmap_ref=a.roadmapRef,u.goal_path=a.goalPath,{status:200,body:u}}s(Yt,"handlePromote");async function Ht(e){const n=e.params.id;return await m(n),{status:200,body:{request:await bn(n)}}}s(Ht,"handleBrokerStructuredRequest");async function Qt(e){const n=e.params.id,t=e.body??{};if(await gn(n,t.expected_execution_id),typeof t.text!="string")throw new p(400,"invalid_request","text must be a string");return await m(n),{status:200,body:{captured:await Sn(n,t.text)}}}s(Qt,"handleBrokerGoal");async function Xt(e,n={}){const t=e.params.id,r=await m(t),i=e.body??{};i.kind!==void 0&&await U(i.kind,r.cwd,r.profile_id??null),i.model!==void 0&&await ve(r,{kind:i.kind??r.kind,mode:i.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:i.model},n.modelRegistry);const a=i.note??"Refresh: continue against your roadmap or goal.";await vn(t,a);const u=await wn(t,{...i.promote===!0?{promote:!0}:{},...i.kind!==void 0?{kind:i.kind}:{},...i.model!==void 0?{model:i.model}:{}});return{status:200,body:await Y(u.meta,await H(t))}}s(Xt,"handleYield");async function Zt(e){const n=e.params.id;await m(n);const t=e.body;if(t===void 0||typeof t.controller!="string"||t.controller.trim()==="")throw w("a wait requires a controller node id");const r=await R(t.controller);if(r===null)throw T(`unknown controller: ${t.controller}`,{received:t.controller});if(r.status!=="active"&&r.status!=="idle")throw new p(422,"unprocessable",`controller ${t.controller} is ${r.status}`);return await We(n,t.controller),{status:200,body:await b(n)}}s(Zt,"handleWait");async function qt(e){const n=e.principal,t=await pn(n.class==="broker"?async i=>i.grantee===n.app&&await $(n,i.grantee,i.node_id):n.class==="person"&&!j(n)?async i=>await $(n,i.grantee??"app:terminal",i.node_id):void 0);return{status:200,body:{revived:[...t.revived],failed:[...t.failed],frozen:[...t.frozen]}}}s(qt,"handleReviveAll");const ei=new Set(["interrupt","steer","after-turn","next-turn"]);function ni(e){if(e===null)return null;const n=s(r=>{throw new y({error:"invalid_listen",message:r,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 n("listen must be an object or null");const t=Object.entries(e);if(t.length===0)return n("listen must name at least one level");for(const[r,i]of t)/^(?:[1-9]|10)$/.test(r)||n(`listen level must be 1..10: ${r}`),(typeof i!="string"||!ei.has(i))&&n(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(i)}`);return JSON.stringify(Object.fromEntries(t))}s(ni,"listenJson");async function N(e,n,t,r){t.length===0&&r===void 0||await W(async i=>{if(r?.(i),t.length===0)return;const a=await Je(i,n),u=await He(i,e),d=u.class==="person"?u.person:u.class==="app"?u.app:u.node;await Ue(i,d,a),await Ye(i,{event:"configured",object:a,actor:d,attrs:{changed:t.join(",")}})})}s(N,"recordConfigured");function Re(e){const n=L().get(e);if(n===void 0)return!1;try{return process.kill(n.pid,"SIGTERM"),!0}catch{return!1}}s(Re,"restartLiveBroker");function Ie(e,n){try{return ee(e)===ee(n)}catch{return!1}}s(Ie,"sameDirectory");async function ti(e,n={}){const t=e.params.id,r=e.body;let i;if(r===void 0)i={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))i=r;else throw new y({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:r,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(h=>h!=="profile"&&h!=="restart"&&i[h]!==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 o=await m(t),l=await zn(e,i.profile);Jn(l.profileId);const f=Un(l.profileId).manifest.grantee??"app:terminal";if(f!==(o.grantee??"app:terminal"))throw new y({error:"profile_grantee_mismatch",message:`profile ${l.profileId} belongs to ${f}, node ${t} to ${o.grantee}`,received:i.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(o.profile_id??null)!==l.profileId&&(Kn(o.kind)?(await U(o.kind,o.cwd,l.profileId),await J(t,{profileId:l.profileId})):await E(t,{profile_id:l.profileId}),await N(e,t,["profile"])),i.restart===!0&&Re(t),{status:200,body:await b(t)}}if(Object.prototype.hasOwnProperty.call(i,"cwd")){const o=i.cwd;if(typeof o!="string"||o==="")throw new y({error:"cwd_invalid",message:"cwd must be a non-empty string",received:o,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(i).some(c=>c!=="cwd"&&c!=="keep_session"&&c!=="restart"&&i[c]!==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 m(t),f=C(l.cwd);if(i.keep_session===!0||f&&x(o)&&C(o)&&Ie(l.cwd,o)){if(!x(o))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${o}`,received:o,field:"cwd",next:"Send an absolute path."});const c=D(o);let S=!1;try{S=ne(c).isDirectory()}catch{}if(!S)throw new y({error:"cwd_missing",message:`cwd is not an existing directory: ${c}`,received:o,field:"cwd",next:"Send an existing absolute directory."});if(f&&!Ie(l.cwd,c))throw new y({error:"cwd_not_same_directory",message:`${c} is not the same directory as the recorded ${l.cwd}; --keep-session only relocates an alias`,received:o,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:`${t} owns an open managed worktree and cannot relocate its cwd`,received:o,field:"cwd",next:"Reconcile the managed worktree first."});const _=l.cwd;return _!==c&&(await W(async v=>{await E(t,{cwd:c}),await v.prepare("UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(c,t,_),await Qe(t,_,c)}),await N(e,t,["cwd"])),i.restart===!0&&Re(t),{status:200,body:await b(t)}}if(await L().has(t)){const c=`${t} cannot repair its cwd while its broker is live`;throw new p(409,"cwd_node_live",c,{error:"cwd_node_live",message:c,received:o,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:`${t} is a fork and cannot repair its cwd; recorded cwd: ${l.cwd}`,received:o,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:`${t} owns an open managed worktree and cannot repair its cwd`,received:o,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(C(l.cwd))throw new y({error:"cwd_still_present",message:`${t} recorded cwd still exists: ${l.cwd}; cwd repair is not a relocation command`,received:o,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!x(o))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${o}`,received:o,field:"cwd",next:"Send an absolute path."});const h=D(o);if(!C(h))throw new y({error:"cwd_missing",message:`cwd does not exist: ${h}`,received:o,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!ne(h).isDirectory())throw new y({error:"cwd_not_a_directory",message:`cwd is not a directory: ${h}`,received:o,field:"cwd",next:"Send an existing absolute directory."})}catch(c){throw c instanceof y?c:new y({error:"cwd_missing",message:`cwd does not exist: ${h}`,received:o,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return await W(async()=>{await E(t,{cwd:h}),await Xe(t)}),await N(e,t,["cwd"]),{status:200,body:await b(t)}}let a=await m(t);const u=i.listen===void 0?void 0:ni(i.listen);if(i.scopes!==void 0){const o=ye(i.scopes),l=a.grantee==="app:terminal"?await ft(a):a.grant_id?await ct(a.grant_id):null;if(!o.every(f=>O(a.scopes,f)&&l!==null&&O(l.resolved,f)))throw new y({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:o,field:"scopes",next:"Send only scopes the node currently holds."});if(o.includes("crtr:act")&&!O(o,"crtr:llm"))throw new p(400,"invalid_scope","crtr:act requires crtr:llm");a=await E(t,{scopes:o})}if(i.situational_context!==void 0&&await Ee(t,Te(i.situational_context)),i.model!==void 0){const o=(await ue(a.cwd,a.profile_id??null)).modelLadders,l=$n(i.model,o),f=await pt(a.grant_id,i.model,l===void 0),h=f?{family:mt,strength:f.strength}:l,c=f?f.model:Nn(i.model,o);await V({kind:"concrete",spec:c},{cwd:a.cwd,profileId:a.profile_id??null},n.modelRegistry);const S=L();let _=!1;if(await S.isClaimed(t)&&await fe(t,S.get(t)?.handle.exited)&&(_=await Tn(t,c,h).then(()=>!0,v=>{if(v instanceof Pn)return!1;throw v})),!_){if(await S.isClaimed(t)){const v=`${t}'s broker did not accept the model switch; the model was not changed`;throw new p(409,"broker_not_ready",v,{error:"broker_not_ready",message:v,received:i.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!c.includes("/"))throw w(`model must resolve to a provider/id spec: ${i.model}`);await En(t,c,h)}a=await m(t)}if(i.kind!==void 0||i.mode!==void 0||i.lifecycle!==void 0){i.kind!==void 0&&await Ae(i.kind);const o=i.kind??a.kind,l=i.mode??a.mode,f=i.lifecycle??a.lifecycle;let h;l==="orchestrator"&&!await In(t)&&(h=s(async()=>{const c=await kn(t);await Rn(t,c!==null&&c.trim()!==""?{goal:c.trim()}:{})},"beforePersist")),a=await J(t,{...i.kind!==void 0?{kind:o}:{},...i.mode!==void 0?{mode:l}:{},...i.lifecycle!==void 0?{lifecycle:f}:{}},h)}i.name!==void 0&&(a=await E(t,{name:i.name}),a.window&&On(a.window,Wn(a)));const d=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(o=>i[o]!==void 0);return await N(e,t,d,u===void 0?void 0:async o=>{await o.prepare("UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(u,t)}),{status:200,body:await b(t)}}s(ti,"handleConfig");async function Oe(){return(await ue(process.cwd(),Ne()||null)).kinds}s(Oe,"daemonKinds");async function Ae(e){const n=Object.keys(await Oe());if(!n.includes(e))throw w(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${n.sort().join(", ")}.`})}s(Ae,"assertKindServer");async function ii(){const e=await Oe();return{status:200,body:{kinds:Object.keys(e).sort().map(t=>({kind:t,when_to_use:e[t]?.whenToUse??null,available_to:e[t]?.availableTo??null}))}}}s(ii,"handleListKinds");const Or=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:Ot},{method:"GET",pattern:"/v1/nodes",handler:Ct},{method:"GET",pattern:"/v1/kinds",handler:s(()=>ii(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:qt},{method:"GET",pattern:"/v1/nodes/:id",handler:Et},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:Tt},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:Pt},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:Lt},{method:"GET",pattern:"/v1/nodes/:id/session",handler:jt},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:Mt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:Gt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:Bt},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Kt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:Vt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:Wt},{method:"POST",pattern:"/v1/nodes/:id/read",handler:zt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:Jt},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Ut},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Yt},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Xt},{method:"GET",pattern:"/v1/nodes/:id/broker/structured-request",handler:Ht},{method:"POST",pattern:"/v1/nodes/:id/broker/goal",handler:Qt},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Zt},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:ti}];export{ti as handleConfig,Ot as handleCreate,Bt as handleFork,Ct as handleList,Yt as handlePromote,Xt as handleYield,Or as nodeRoutes,Nr as resolveCreateKind};
@@ -1 +1 @@
1
- var S=Object.defineProperty;var c=(a,t)=>S(a,"name",{value:t,configurable:!0});import{callerGrant as g}from"../principal.js";import{grantVersion as b,payerOfGrant as O}from"../../../core/grants/mirror.js";import{holdGrant as $}from"../../../core/grants/watch.js";import{RunError as n,idempotencyKeyOf as v,cancelRun as N,cloudPersonScope as A,deleteRun as j,interruptRun as x,listRuns as B,messageRun as J,renameRun as z,requestedScopes as D,startRun as E,traceRun as G,waitRun as K}from"../../../core/runs/operations.js";import{canReadRun as y,requireRun as w,runCallerApp as M}from"../router.js";import{waitSeconds as q}from"../long-poll-wait.js";import{outputSchemaProblem as P}from"../../../core/runtime/structured-output.js";function m(a){if(!a||typeof a!="object"||Array.isArray(a))throw new n(400,"invalid_request","a JSON object is required");return a}c(m,"object");function k(a,t,i,u,l){if(a===null)return l;if(!/^(0|[1-9]\d*)$/.test(a)||!Number.isSafeInteger(Number(a))||Number(a)<i||Number(a)>u)throw new n(400,"invalid_request",`invalid ${t}`,t);return Number(a)}c(k,"integer");const T=256*1024;async function Y(a,t,i,u,l,_,h){switch(a.name){case"grant.get":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=q("grant.get",u),s=u.get("since");if(s!==null&&!/^[A-Za-z0-9_-]{1,64}$/.test(s))throw new n(400,"invalid_request","invalid since","since");const d=e&&s!==null?$(t.grant):void 0;let o;try{if(o=await g(t),d){const f=Date.now()+e*1e3;for(;b(o)===s&&Date.now()<f;)await d.changed(Math.max(0,(f-Date.now())/1e3)),o=await g(t)}}finally{d?.release()}return{status:200,body:{sub:t.sub,grantee:t.grantee,client_id:t.client_id,grant:t.grant,rev:o.rev,resolved_scopes:o.resolved_scopes,spend_cap:o.spend_cap,exp:t.exp,payer:await O(t.grant),dependencies:o.dependencies??{},version:b(o)}}}case"run.start":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=m(l),s=["mode","parent","fork_from","node_id","env","tools","system_prompt"];for(const r of s)if(e[r]!==void 0)throw new n(403,"owner_only",`${r} is owner-only`,r);const d=["payer","model_policy","kind"];for(const r of d)if(e[r]!==void 0)throw new n(400,"invalid_request",`${r} is not available`,r);for(const r of Object.keys(e))if(!["prompt","scopes","metadata","profile","isolated","cwd","worktree","output_schema","message","model","deadline"].includes(r))throw new n(400,"invalid_request",`unknown field ${r}`,r);if(e.model!==void 0&&(typeof e.model!="string"||!e.model.trim()))throw new n(400,"invalid_request","model must be a non-empty string","model");if(e.deadline!==void 0&&(typeof e.deadline!="string"||!e.deadline.trim()))throw new n(400,"invalid_request","deadline must be a duration string such as 10m","deadline");if(e.profile!==void 0&&(typeof e.profile!="string"||!e.profile))throw new n(400,"invalid_request","profile must be a profile id","profile");if(e.isolated!==void 0&&typeof e.isolated!="boolean")throw new n(400,"invalid_request","isolated must be a boolean","isolated");if(e.cwd!==void 0&&(e.isolated!==!0||typeof e.cwd!="string"||!e.cwd))throw new n(400,"invalid_request","cwd is available only for an isolated run and must be an absolute path inside its root folder","cwd");if(e.worktree!==void 0&&e.isolated!==!0)throw new n(400,"invalid_request","worktree is not available","worktree");if(e.isolated===!0&&e.worktree!==void 0)throw new n(400,"invalid_request","worktree is unavailable for an isolated run","worktree");if(typeof e.prompt!="string"||!e.prompt.trim())throw new n(400,"invalid_request","prompt is required","prompt");if(e.message!==void 0&&(typeof e.message!="string"||!e.message.trim()))throw new n(400,"invalid_request","message must be a non-empty string","message");const o=e.metadata===void 0?{}:m(e.metadata);if(Buffer.byteLength(JSON.stringify(o))>4096)throw new n(400,"invalid_request","metadata exceeds 4 KB","metadata");let f;if(e.output_schema!==void 0){const r=e.output_schema;if(!r||typeof r!="object"||Array.isArray(r))throw new n(400,"invalid_request","output_schema must be a JSON Schema object","output_schema");if(Buffer.byteLength(JSON.stringify(r))>T)throw new n(400,"invalid_request","output_schema exceeds 256 KB","output_schema");const p=await P(r);if(p!==null)throw new n(400,"invalid_request",`output_schema is not usable: ${p}`,"output_schema");f=r}const R=D(t.resolved,e.scopes,t.grantee);return{status:201,body:await E(t,{prompt:e.prompt,scopes:R,metadata:o,profile:e.profile,isolated:e.isolated,cwd:e.cwd,...e.model===void 0?{}:{model:e.model},...e.deadline===void 0?{}:{deadline:e.deadline},...f===void 0?{}:{output_schema:f},...e.message===void 0?{}:{message:e.message},...h===void 0?{}:{causedBy:h}},v(_))}}case"run.list":{const e=u.get("status")??void 0;if(e&&!["running","waiting_on_user","idle","settled"].includes(e))throw new n(400,"invalid_request","invalid status","status");const s=u.get("app");if(s!==null&&!/^(?:app:)?[a-z0-9][a-z0-9-]*$/.test(s))throw new n(400,"invalid_request","invalid app","app");const d=s===null?M(t):s.startsWith("app:")?s:`app:${s}`;if(d!==null&&!await y(t,d))throw new n(404,"not_found","run not found");const o=A(t.sub);return{status:200,body:await B(d,{status:e,...o===void 0?{}:{sub:o},after:u.get("after")??void 0,limit:k(u.get("limit"),"limit",1,100,50),..."class"in t&&(t.class==="broker"||t.class==="cron")&&d!==null?{visible:c(async f=>await y(t,d,f),"visible")}:{}})}}case"run.get":{const e=q("run.get",u),s=await w(t,i),d=await K(i,s.grantee,e);return await w(t,i),{status:200,body:d}}case"run.message":{const e=m(l);if(typeof e.message!="string"||!e.message.trim())throw new n(400,"invalid_request","message is required","message");if(e.start_turn!==void 0&&typeof e.start_turn!="boolean")throw new n(400,"invalid_request","start_turn must be a boolean","start_turn");return{status:202,body:await J(await w(t,i,!0),e.message,void 0,e.start_turn,v(_))}}case"run.interrupt":{const e=m(l===void 0?{}:l);if(e.children!==void 0&&e.children!=="stop"&&e.children!=="continue")throw new n(400,"invalid_request","invalid children","children");return{status:200,body:await x(await w(t,i,!0),e.children)}}case"run.cancel":{const e=m(l===void 0?{}:l);if(e.keep_schedules!==void 0&&typeof e.keep_schedules!="boolean")throw new n(400,"invalid_request","invalid keep_schedules","keep_schedules");return{status:200,body:await N(await w(t,i,!0),{keepSchedules:e.keep_schedules})}}case"run.rename":{const e=m(l);for(const s of Object.keys(e))if(s!=="name")throw new n(400,"invalid_request",`unknown field ${s}`,s);return{status:200,body:await z(await w(t,i,!0),e.name)}}case"run.delete":{const{uploads_pending:e}=await j(await w(t,i,!0,!0));return{status:200,body:{run_id:i,uploads_pending:e}}}case"trace.get":{const e=u.get("format")??void 0;if(e&&e!=="entries")throw new n(400,"invalid_request","unknown trace format","format");const s=await w(t,i);return{status:200,body:await G(i,s.grantee,e)}}default:throw new n(404,"not_found","unknown operation")}}c(Y,"handleRunOperation");export{Y as handleRunOperation,k as integer};
1
+ var S=Object.defineProperty;var c=(a,t)=>S(a,"name",{value:t,configurable:!0});import{callerGrant as g}from"../principal.js";import{grantVersion as b,payerOfGrant as O}from"../../../core/grants/mirror.js";import{holdGrant as $}from"../../../core/grants/watch.js";import{RunError as n,idempotencyKeyOf as v,cancelRun as N,cloudPersonScope as A,deleteRun as j,interruptRun as x,listRuns as B,messageRun as J,renameRun as z,requestedScopes as D,startRun as E,traceRun as G,waitRun as K}from"../../../core/runs/operations.js";import{canReadRun as y,requireRun as w,runCallerApp as M}from"../router.js";import{waitSeconds as q}from"../long-poll-wait.js";import{outputSchemaProblem as P}from"../../../core/runtime/structured-output.js";function m(a){if(!a||typeof a!="object"||Array.isArray(a))throw new n(400,"invalid_request","a JSON object is required");return a}c(m,"object");function k(a,t,i,u,l){if(a===null)return l;if(!/^(0|[1-9]\d*)$/.test(a)||!Number.isSafeInteger(Number(a))||Number(a)<i||Number(a)>u)throw new n(400,"invalid_request",`invalid ${t}`,t);return Number(a)}c(k,"integer");const T=256*1024;async function Y(a,t,i,u,l,_,h){switch(a.name){case"grant.get":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=q("grant.get",u),s=u.get("since");if(s!==null&&!/^[A-Za-z0-9_-]{1,64}$/.test(s))throw new n(400,"invalid_request","invalid since","since");const d=e&&s!==null?$(t.grant):void 0;let o;try{if(o=await g(t),d){const f=Date.now()+e*1e3;for(;b(o)===s&&Date.now()<f;)await d.changed(Math.max(0,(f-Date.now())/1e3)),o=await g(t)}}finally{d?.release()}return{status:200,body:{sub:t.sub,grantee:t.grantee,client_id:t.client_id,grant:t.grant,rev:o.rev,resolved_scopes:o.resolved_scopes,spend_cap:o.spend_cap,exp:t.exp,payer:await O(t.grant),dependencies:o.dependencies??{},version:b(o)}}}case"run.start":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=m(l),s=["mode","parent","fork_from","node_id","env","tools","system_prompt"];for(const r of s)if(e[r]!==void 0)throw new n(403,"owner_only",`${r} is owner-only`,r);const d=["payer","model_policy","kind"];for(const r of d)if(e[r]!==void 0)throw new n(400,"invalid_request",`${r} is not available`,r);for(const r of Object.keys(e))if(!["prompt","scopes","metadata","profile","isolated","cwd","worktree","output_schema","message","model","deadline"].includes(r))throw new n(400,"invalid_request",`unknown field ${r}`,r);if(e.model!==void 0&&(typeof e.model!="string"||!e.model.trim()))throw new n(400,"invalid_request","model must be a non-empty string","model");if(e.deadline!==void 0&&(typeof e.deadline!="string"||!e.deadline.trim()))throw new n(400,"invalid_request","deadline must be a duration string such as 10m","deadline");if(e.profile!==void 0&&(typeof e.profile!="string"||!e.profile))throw new n(400,"invalid_request","profile must be a profile id","profile");if(e.isolated!==void 0&&typeof e.isolated!="boolean")throw new n(400,"invalid_request","isolated must be a boolean","isolated");if(e.cwd!==void 0&&(e.isolated!==!0||typeof e.cwd!="string"||!e.cwd))throw new n(400,"invalid_request","cwd is available only for an isolated run and must be an absolute path inside its root folder","cwd");if(e.worktree!==void 0&&e.isolated!==!0)throw new n(400,"invalid_request","worktree is not available","worktree");if(e.isolated===!0&&e.worktree!==void 0)throw new n(400,"invalid_request","worktree is unavailable for an isolated run","worktree");if(typeof e.prompt!="string"||!e.prompt.trim())throw new n(400,"invalid_request","prompt is required","prompt");if(e.message!==void 0&&(typeof e.message!="string"||!e.message.trim()))throw new n(400,"invalid_request","message must be a non-empty string","message");const o=e.metadata===void 0?{}:m(e.metadata);if(Buffer.byteLength(JSON.stringify(o))>4096)throw new n(400,"invalid_request","metadata exceeds 4 KB","metadata");let f;if(e.output_schema!==void 0){const r=e.output_schema;if(!r||typeof r!="object"||Array.isArray(r))throw new n(400,"invalid_request","output_schema must be a JSON Schema object","output_schema");if(Buffer.byteLength(JSON.stringify(r))>T)throw new n(400,"invalid_request","output_schema exceeds 256 KB","output_schema");const p=await P(r);if(p!==null)throw new n(400,"invalid_request",`output_schema is not usable: ${p}`,"output_schema");f=r}const R=D(t.resolved,e.scopes,t.grantee);return{status:201,body:await E(t,{prompt:e.prompt,scopes:R,metadata:o,profile:e.profile,isolated:e.isolated,cwd:e.cwd,...e.model===void 0?{}:{model:e.model},...e.deadline===void 0?{}:{deadline:e.deadline},...f===void 0?{}:{output_schema:f},...e.message===void 0?{}:{message:e.message},...h===void 0?{}:{causedBy:h}},v(_))}}case"run.list":{const e=u.get("status")??void 0;if(e&&!["running","waiting_on_user","idle","settled"].includes(e))throw new n(400,"invalid_request","invalid status","status");const s=u.get("app");if(s!==null&&!/^(?:app:)?[a-z0-9][a-z0-9-]*$/.test(s))throw new n(400,"invalid_request","invalid app","app");const d=s===null?M(t):s.startsWith("app:")?s:`app:${s}`;if(d!==null&&!await y(t,d))throw new n(404,"not_found","run not found");const o=A(t.sub);return{status:200,body:await B(d,{status:e,...o===void 0?{}:{sub:o},after:u.get("after")??void 0,limit:k(u.get("limit"),"limit",1,100,50),..."class"in t&&(t.class==="broker"||t.class==="cron")&&d!==null?{visible:c(async f=>await y(t,d,f),"visible")}:{}})}}case"run.get":{const e=q("run.get",u),s=await w(t,i),d=await K(i,s.grantee,e);return await w(t,i),{status:200,body:d}}case"run.message":{const e=m(l);if(typeof e.message!="string"||!e.message.trim())throw new n(400,"invalid_request","message is required","message");if(e.start_turn!==void 0&&typeof e.start_turn!="boolean")throw new n(400,"invalid_request","start_turn must be a boolean","start_turn");if(e.steer!==void 0&&typeof e.steer!="boolean")throw new n(400,"invalid_request","steer must be a boolean","steer");if(e.start_turn===!1&&e.steer===!0)throw new n(400,"invalid_request","steer requires start_turn","steer");return{status:202,body:await J(await w(t,i,!0),e.message,void 0,e.start_turn,v(_),e.steer)}}case"run.interrupt":{const e=m(l===void 0?{}:l);if(e.children!==void 0&&e.children!=="stop"&&e.children!=="continue")throw new n(400,"invalid_request","invalid children","children");return{status:200,body:await x(await w(t,i,!0),e.children)}}case"run.cancel":{const e=m(l===void 0?{}:l);if(e.keep_schedules!==void 0&&typeof e.keep_schedules!="boolean")throw new n(400,"invalid_request","invalid keep_schedules","keep_schedules");return{status:200,body:await N(await w(t,i,!0),{keepSchedules:e.keep_schedules})}}case"run.rename":{const e=m(l);for(const s of Object.keys(e))if(s!=="name")throw new n(400,"invalid_request",`unknown field ${s}`,s);return{status:200,body:await z(await w(t,i,!0),e.name)}}case"run.delete":{const{uploads_pending:e}=await j(await w(t,i,!0,!0));return{status:200,body:{run_id:i,uploads_pending:e}}}case"trace.get":{const e=u.get("format")??void 0;if(e&&e!=="entries")throw new n(400,"invalid_request","unknown trace format","format");const s=await w(t,i);return{status:200,body:await G(i,s.grantee,e)}}default:throw new n(404,"not_found","unknown operation")}}c(Y,"handleRunOperation");export{Y as handleRunOperation,k as integer};
@@ -1 +1 @@
1
- var $=Object.defineProperty;var i=(e,n)=>$(e,"name",{value:n,configurable:!0});import{ApiError as m}from"../../api/errors.js";import{openDb as g}from"../../core/canvas/db.js";import{getById as A,nodeObject as D}from"../../core/graph/objects.js";import{envelopeFor as j}from"../../core/peer/envelope.js";import{isUnreachable as w}from"../../core/peer/client.js";import{machineReach as E}from"../../core/peer/directory.js";import{defaultHomeDeps as O,homeOf as S,peersToAsk as F,relocate as N}from"../../core/peer/home.js";import{ensureStub as y,rehomeStub as q,stubOf as C}from"../../core/peer/stubs.js";import{peerCall as M}from"../../core/peer/client.js";const T={...O,call:i((e,n,o,t)=>M(e,n,{...o===void 0?{}:{envelope:o},...t===void 0?{}:{signal:t}}),"call"),envelope:i(async e=>await j(e),"envelope"),label:i(async e=>{try{const n=await E(e);return{id:e,name:n?.name??e}}catch{return{id:e,name:e}}},"label")},_={current:T},v=i(e=>e.class==="person"||e.class==="broker"||e.class==="cron","originates"),W=i(e=>e?.error?.details?.deleted===!0,"isDeletedAnswer"),k=i(e=>{const n=e?.error;return typeof n=="object"&&n!==null&&typeof n.code=="string"?n.code:null},"errorCode");function L(e,n){const o=n?.error;return new m(e,o?.code??"error",o?.message??`the home machine answered ${e}`,o?.details)}i(L,"relayError");function Q(e,n){return new m(503,"runtime_unreachable",`No machine of yours answers for ${e} (unreachable: ${n.join(", ")}).`,{id:e,unreachable:n})}i(Q,"unknownError");const X=i((e,n)=>e!==null&&typeof e=="object"&&!Array.isArray(e)?{...e,machine:n}:e,"withMachine");async function Y(e,n,o){const t=_.current,a=await g(),c=await A(a,n),u=c===null?null:await C(a,c),p=e.principal;if(!v(p)){if(u!==null)throw new m(404,"not_here",`${n} is not homed on this machine (it is a stub of ${u.home_machine})`,{id:n,home_machine:u.home_machine});return{kind:"local"}}if(c!==null&&u===null)return{kind:"local"};const h={...t,call:i((r,d)=>t.call(r,d),"call")};let s=await S(a,n,{hint:e.query.get("machine"),deps:h});for(let r=0;r<2;r++){if(s.where==="nowhere"||s.where==="here"){if(u!==null)throw new m(404,"not_found",`${n} is no longer on any machine of yours`,{id:n});return{kind:"local"}}if(s.where==="unknown")return{kind:"unknown",unreachable:s.unreachable};const d=s.machine,l=await t.call(d,o,await t.envelope(p)),b=await t.label(d);if(w(l))return{kind:"unknown",unreachable:[`${b.name} (${l.unreachable.reason})`]};const x=s.source!=="locate";if(l.status===404&&r===0&&!W(l.body)&&(k(l.body)==="not_here"||x&&k(l.body)==="not_found")){const f=await N(a,n,d,h);if(f.where==="machine"){s=f;continue}if(f.where==="unknown")return{kind:"unknown",unreachable:f.unreachable};if(k(l.body)==="not_found")return{kind:"remote",status:l.status,body:l.body,machine:b};if(u!==null)throw new m(404,"not_found",`${n} is no longer on any machine of yours`,{id:n});return{kind:"local"}}return{kind:"remote",status:l.status,body:l.body,machine:b}}return{kind:"unknown",unreachable:[]}}i(Y,"forwardVerb");async function Z(e,n,o){const t=_.current,a=e.principal;if(!v(a))return{kind:"local"};const c=await F(t);if("where"in c)return{kind:"unknown",unreachable:c.unreachable};if(c.length===0)return{kind:"local"};const u=await t.envelope(a),p=await Promise.all(c.map(async r=>({m:r,out:await t.call(r.machine_id,o,u)}))),h=p.find(r=>!w(r.out)&&r.out.status<400);if(h){const r=n.method==="GET"?h.out:await t.call(h.m.machine_id,n,u),d=await t.label(h.m.machine_id);return w(r)?{kind:"unknown",unreachable:[`${d.name} (${r.unreachable.reason})`]}:{kind:"remote",status:r.status,body:r.body,machine:d}}const s=p.filter(r=>w(r.out)||r.out.status!==404).map(r=>r.m.name||r.m.machine_id);return s.length>0?{kind:"unknown",unreachable:s}:{kind:"local"}}i(Z,"forwardNamed");function B(e){if(e.actor.kind==="person")return{sub:e.sub,act:{sub:e.via}};const{app:n,node:o,node_scopes:t,place:a}=e.actor;return{sub:e.sub,act:{sub:e.via,act:{sub:n,node:o,node_scopes:t,place:a}}}}i(B,"envelopeOfForwarded");function ee(e){const n={};for(const[o,t]of e.query)o!=="machine"&&(n[o]=t);return n}i(ee,"queryWithoutMachine");async function ne(e,n){const o=n.principal;return o.class!=="forwarded"||o.actor.kind!=="app"||o.actor.node===null?null:await y(e,o.actor.node,"node",o.via,B(o))}i(ne,"callerStub");async function oe(e,n){return n.principal.class==="broker"?await D(e,n.principal.node):null}i(oe,"callerNode");async function re(e,n,o,t,a){await q(e,n,t);const c=a?.owner,u=c&&c.type==="app"?{id:"",type:"app",scheme:"app",external_id:c.external_id??(c.handle.startsWith("app:")?c.handle:`app:${c.handle}`),handle:c.handle}:null;return await y(e,n,o,t,void 0,a===void 0?void 0:{id:n,type:o,kind:a.kind??null,name:a.name??n,...a.preview===void 0?{}:{preview:a.preview},owner:u,...a.kind_decl===void 0?{}:{kind_decl:a.kind_decl},...a.privacy===void 0?{}:{privacy:a.privacy}})}i(re,"remoteStub");export{oe as callerNode,ne as callerStub,T as defaultForwardDeps,B as envelopeOfForwarded,Z as forwardNamed,Y as forwardVerb,_ as forwarding,v as originates,ee as queryWithoutMachine,L as relayError,re as remoteStub,Q as unknownError,X as withMachine};
1
+ var $=Object.defineProperty;var i=(e,n)=>$(e,"name",{value:n,configurable:!0});import{ApiError as p}from"../../api/errors.js";import{openDb as g}from"../../core/canvas/db.js";import{getById as E,nodeObject as A}from"../../core/graph/objects.js";import{envelopeFor as D,EnvelopeError as j}from"../../core/peer/envelope.js";import{isUnreachable as f}from"../../core/peer/client.js";import{machineReach as O}from"../../core/peer/directory.js";import{defaultHomeDeps as S,homeOf as q,peersToAsk as F,relocate as N}from"../../core/peer/home.js";import{ensureStub as y,rehomeStub as C,stubOf as M}from"../../core/peer/stubs.js";import{peerCall as T}from"../../core/peer/client.js";const W={...S,call:i((e,n,r,t)=>T(e,n,{...r===void 0?{}:{envelope:r},...t===void 0?{}:{signal:t}}),"call"),envelope:i(async e=>{try{return await D(e)}catch(n){throw n instanceof j?new p(400,"invalid_request",n.message):n}},"envelope"),label:i(async e=>{try{const n=await O(e);return{id:e,name:n?.name??e}}catch{return{id:e,name:e}}},"label")},_={current:W},v=i(e=>e.class==="person"||e.class==="broker"||e.class==="cron","originates"),B=i(e=>e?.error?.details?.deleted===!0,"isDeletedAnswer"),k=i(e=>{const n=e?.error;return typeof n=="object"&&n!==null&&typeof n.code=="string"?n.code:null},"errorCode");function Q(e,n){const r=n?.error;return new p(e,r?.code??"error",r?.message??`the home machine answered ${e}`,r?.details)}i(Q,"relayError");function X(e,n){return new p(503,"runtime_unreachable",`No machine of yours answers for ${e} (unreachable: ${n.join(", ")}).`,{id:e,unreachable:n})}i(X,"unknownError");const Y=i((e,n)=>e!==null&&typeof e=="object"&&!Array.isArray(e)?{...e,machine:n}:e,"withMachine");async function Z(e,n,r){const t=_.current,a=await g(),c=await E(a,n),u=c===null?null:await M(a,c),m=e.principal;if(!v(m)){if(u!==null)throw new p(404,"not_here",`${n} is not homed on this machine (it is a stub of ${u.home_machine})`,{id:n,home_machine:u.home_machine});return{kind:"local"}}if(c!==null&&u===null)return{kind:"local"};const h={...t,call:i((o,d)=>t.call(o,d),"call")};let s=await q(a,n,{hint:e.query.get("machine"),deps:h});for(let o=0;o<2;o++){if(s.where==="nowhere"||s.where==="here"){if(u!==null)throw new p(404,"not_found",`${n} is no longer on any machine of yours`,{id:n});return{kind:"local"}}if(s.where==="unknown")return{kind:"unknown",unreachable:s.unreachable};const d=s.machine,l=await t.call(d,r,await t.envelope(m)),b=await t.label(d);if(f(l))return{kind:"unknown",unreachable:[`${b.name} (${l.unreachable.reason})`]};const x=s.source!=="locate";if(l.status===404&&o===0&&!B(l.body)&&(k(l.body)==="not_here"||x&&k(l.body)==="not_found")){const w=await N(a,n,d,h);if(w.where==="machine"){s=w;continue}if(w.where==="unknown")return{kind:"unknown",unreachable:w.unreachable};if(k(l.body)==="not_found")return{kind:"remote",status:l.status,body:l.body,machine:b};if(u!==null)throw new p(404,"not_found",`${n} is no longer on any machine of yours`,{id:n});return{kind:"local"}}return{kind:"remote",status:l.status,body:l.body,machine:b}}return{kind:"unknown",unreachable:[]}}i(Z,"forwardVerb");async function ee(e,n,r){const t=_.current,a=e.principal;if(!v(a))return{kind:"local"};const c=await F(t);if("where"in c)return{kind:"unknown",unreachable:c.unreachable};if(c.length===0)return{kind:"local"};const u=await t.envelope(a),m=await Promise.all(c.map(async o=>({m:o,out:await t.call(o.machine_id,r,u)}))),h=m.find(o=>!f(o.out)&&o.out.status<400);if(h){const o=n.method==="GET"?h.out:await t.call(h.m.machine_id,n,u),d=await t.label(h.m.machine_id);return f(o)?{kind:"unknown",unreachable:[`${d.name} (${o.unreachable.reason})`]}:{kind:"remote",status:o.status,body:o.body,machine:d}}const s=m.filter(o=>f(o.out)||o.out.status!==404).map(o=>o.m.name||o.m.machine_id);return s.length>0?{kind:"unknown",unreachable:s}:{kind:"local"}}i(ee,"forwardNamed");function G(e){if(e.actor.kind==="person")return{sub:e.sub,act:{sub:e.via}};const{app:n,node:r,node_scopes:t,place:a}=e.actor;return{sub:e.sub,act:{sub:e.via,act:{sub:n,node:r,node_scopes:t,place:a}}}}i(G,"envelopeOfForwarded");function ne(e){const n={};for(const[r,t]of e.query)r!=="machine"&&(n[r]=t);return n}i(ne,"queryWithoutMachine");async function re(e,n){const r=n.principal;return r.class!=="forwarded"||r.actor.kind!=="app"||r.actor.node===null?null:await y(e,r.actor.node,"node",r.via,G(r))}i(re,"callerStub");async function oe(e,n){return n.principal.class==="broker"?await A(e,n.principal.node):null}i(oe,"callerNode");async function te(e,n,r,t,a){await C(e,n,t);const c=a?.owner,u=c&&c.type==="app"?{id:"",type:"app",scheme:"app",external_id:c.external_id??(c.handle.startsWith("app:")?c.handle:`app:${c.handle}`),handle:c.handle}:null;return await y(e,n,r,t,void 0,a===void 0?void 0:{id:n,type:r,kind:a.kind??null,name:a.name??n,...a.preview===void 0?{}:{preview:a.preview},owner:u,...a.kind_decl===void 0?{}:{kind_decl:a.kind_decl},...a.privacy===void 0?{}:{privacy:a.privacy}})}i(te,"remoteStub");export{oe as callerNode,re as callerStub,W as defaultForwardDeps,G as envelopeOfForwarded,ee as forwardNamed,Z as forwardVerb,_ as forwarding,v as originates,ne as queryWithoutMachine,Q as relayError,te as remoteStub,X as unknownError,Y as withMachine};
@@ -1,2 +1,2 @@
1
- var T=Object.defineProperty;var _=(t,e)=>T(t,"name",{value:e,configurable:!0});import{appendRunEvent as c}from"../../core/runs/events.js";import{openQuestionIds as x}from"../../core/runs/questions.js";import{getNode as N}from"../../core/canvas/canvas.js";import{payerOfGrant as h}from"../../core/grants/mirror.js";import{runSchemaRepromptPending as S}from"../../core/runtime/stop-guard.js";const k="crtr-turn-input",D="crtr-system-prompt",g="crtr-turn-end",w=_(()=>({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),"zero");function O(t){return typeof t=="string"?t:Array.isArray(t)?t.filter(e=>typeof e?.text=="string").map(e=>e.text).join(`
2
- `):""}_(O,"text");function j(t){if(t==null)return;const{code:e,message:n}=t;if(e!=="content_refused"&&e!=="model_error"||typeof n!="string")throw new Error("invalid crtr-turn-end error");return{code:e,message:n}}_(j,"turnEndError");function A(t){return{input_tokens:t.input??0,output_tokens:t.output??0,cache_read_tokens:t.cacheRead??0,cache_write_tokens:t.cacheWrite??0,cost_usd:t.cost?.total??0}}_(A,"usageParts");async function v(t,e,n){if(e!==t||!n.some(f=>f.type==="custom"&&f.customType===g))return!1;const m=await N(t);return m!==null&&await S(m)}_(v,"rootRepromptPending");async function Y(t,e,n,m,f,R){let d=f;for(const r of m){if(r.type==="custom"&&r.customType===k){const o=r.data?.message_ids;if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error("invalid crtr-turn-input message_ids");d=[...new Set([...d,...o])]}if(r.type==="custom"&&r.customType===D){const o=r.data?.text;if(typeof o!="string")throw new Error("invalid crtr-system-prompt text");await c(t,e,n,"node.system_prompt.set",{entry_id:r.id,text:o})}if(r.type==="custom"&&r.customType===g){const o=r.data,i=o?.stop_reason;if(typeof i!="string")throw new Error("invalid crtr-turn-end stop_reason");const a=j(o?.error),s=await t.prepare("SELECT body_json FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'node.turn.started' ORDER BY sequence_number DESC LIMIT 1").get(e,n);if(!s)throw new Error("crtr-turn-end without node.turn.started");const{input:p}=JSON.parse(s.body_json),y=await t.prepare("SELECT status, pi_pid FROM node_rows WHERE run_id = ? AND node_id != ?").all(e,n),u=R??await v(e,n,[r]),l=y.some(E=>E.pi_pid!==null&&E.status==="active")||u?"running":(await x(e,t)).length?"waiting_on_user":"idle";await c(t,e,n,"node.turn.completed",{entry_id:r.id,message_ids:p.message_ids,run_status:l,stop_reason:i,...a?{error:a}:{}}),n===e&&await t.prepare("UPDATE nodes SET last_turn_error_json = ? WHERE node_id = ?").run(a?JSON.stringify(a):null,e)}if(r.type==="message"){const o=r.message;if(o.role==="user"){const i=await t.prepare("SELECT type, body_json FROM run_events WHERE run_id = ? AND node_id = ? AND type IN ('node.turn.started', 'node.turn.completed') ORDER BY sequence_number DESC LIMIT 1").get(e,n),a=i?.type==="node.turn.started"?JSON.parse(i.body_json).input.message_ids:[];await c(t,e,n,"node.turn.started",{entry_id:r.id,input:{text:O(o.content),message_ids:[...new Set([...a,...d])]}}),d=[]}if(o.role==="assistant"){let i=!1;const a=_(async()=>{if(i)return;i=!0;const s=o.content.filter(p=>p.type==="text").map(p=>p.text).join("");await c(t,e,n,"node.output_text.done",{entry_id:r.id,text:s,stop_reason:o.stopReason})},"doneText");for(const s of o.content)s.type==="thinking"&&await c(t,e,n,"node.thinking.done",{entry_id:r.id,text:s.thinking}),s.type==="text"&&await a(),s.type==="toolCall"&&(await a(),await c(t,e,n,"node.tool_call.started",{entry_id:r.id,tool_call_id:s.id,name:s.name,arguments:s.arguments}));if(await a(),o.usage){const s=A(o.usage),p=await t.prepare("SELECT usage_json, grant_id FROM nodes WHERE node_id = ?").get(e),y=p.usage_json?JSON.parse(p.usage_json):w(),u=w();for(const l of Object.keys(u))u[l]=y[l]+s[l];await t.prepare("UPDATE nodes SET usage_json = ? WHERE node_id = ?").run(JSON.stringify(u),e),await c(t,e,n,"usage",{entry_id:r.id,served_model:o.model,payer:await h(p.grant_id),...s,usage:u})}await t.prepare("DELETE FROM run_events WHERE run_id = ? AND node_id = ? AND type IN ('node.thinking.delta', 'node.output_text.delta')").run(e,n)}o.role==="toolResult"&&await c(t,e,n,"node.tool_call.completed",{entry_id:r.id,tool_call_id:o.toolCallId,name:o.toolName,result:o.content,status:o.isError?"error":"ok"})}}return d}_(Y,"appendConversationEvents");export{D as SYSTEM_PROMPT_TYPE,g as TURN_END_TYPE,k as TURN_INPUT_TYPE,Y as appendConversationEvents,v as rootRepromptPending};
1
+ var T=Object.defineProperty;var _=(t,e)=>T(t,"name",{value:e,configurable:!0});import{appendRunEvent as c}from"../../core/runs/events.js";import{openQuestionIds as x}from"../../core/runs/questions.js";import{getNode as h}from"../../core/canvas/canvas.js";import{payerOfGrant as N}from"../../core/grants/mirror.js";import{runSchemaRepromptPending as S}from"../../core/runtime/stop-guard.js";const k="crtr-turn-input",D="crtr-system-prompt",g="crtr-turn-end",w=_(()=>({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),"zero");function O(t){return typeof t=="string"?t:Array.isArray(t)?t.filter(e=>typeof e?.text=="string").map(e=>e.text).join(`
2
+ `):""}_(O,"text");function j(t){if(t==null)return;const{code:e,message:o,retry_at:u}=t;if(e!=="content_refused"&&e!=="model_error"&&e!=="rate_limited"||typeof o!="string")throw new Error("invalid crtr-turn-end error");if(e==="rate_limited"){if(typeof u!="string")throw new Error("invalid crtr-turn-end error");return{code:e,message:o,retry_at:u}}return{code:e,message:o}}_(j,"turnEndError");function v(t){return{input_tokens:t.input??0,output_tokens:t.output??0,cache_read_tokens:t.cacheRead??0,cache_write_tokens:t.cacheWrite??0,cost_usd:t.cost?.total??0}}_(v,"usageParts");async function A(t,e,o){if(e!==t||!o.some(f=>f.type==="custom"&&f.customType===g))return!1;const u=await h(t);return u!==null&&await S(u)}_(A,"rootRepromptPending");async function Y(t,e,o,u,f,R){let l=f;for(const n of u){if(n.type==="custom"&&n.customType===k){const r=n.data?.message_ids;if(!Array.isArray(r)||!r.every(i=>typeof i=="string"))throw new Error("invalid crtr-turn-input message_ids");l=[...new Set([...l,...r])]}if(n.type==="custom"&&n.customType===D){const r=n.data?.text;if(typeof r!="string")throw new Error("invalid crtr-system-prompt text");await c(t,e,o,"node.system_prompt.set",{entry_id:n.id,text:r})}if(n.type==="custom"&&n.customType===g){const r=n.data,i=r?.stop_reason;if(typeof i!="string")throw new Error("invalid crtr-turn-end stop_reason");const a=j(r?.error),s=await t.prepare("SELECT body_json FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'node.turn.started' ORDER BY sequence_number DESC LIMIT 1").get(e,o);if(!s)throw new Error("crtr-turn-end without node.turn.started");const{input:p}=JSON.parse(s.body_json),y=await t.prepare("SELECT status, pi_pid FROM node_rows WHERE run_id = ? AND node_id != ?").all(e,o),d=R??await A(e,o,[n]),m=y.some(E=>E.pi_pid!==null&&E.status==="active")||d?"running":(await x(e,t)).length?"waiting_on_user":"idle";await c(t,e,o,"node.turn.completed",{entry_id:n.id,message_ids:p.message_ids,run_status:m,stop_reason:i,...a?{error:a}:{}}),o===e&&await t.prepare("UPDATE nodes SET last_turn_error_json = ? WHERE node_id = ?").run(a?JSON.stringify(a):null,e)}if(n.type==="message"){const r=n.message;if(r.role==="user"){const i=await t.prepare("SELECT type, body_json FROM run_events WHERE run_id = ? AND node_id = ? AND type IN ('node.turn.started', 'node.turn.completed') ORDER BY sequence_number DESC LIMIT 1").get(e,o),a=i?.type==="node.turn.started"?JSON.parse(i.body_json).input.message_ids:[];await c(t,e,o,"node.turn.started",{entry_id:n.id,input:{text:O(r.content),message_ids:[...new Set([...a,...l])]}}),l=[]}if(r.role==="assistant"){let i=!1;const a=_(async()=>{if(i)return;i=!0;const s=r.content.filter(p=>p.type==="text").map(p=>p.text).join("");await c(t,e,o,"node.output_text.done",{entry_id:n.id,text:s,stop_reason:r.stopReason})},"doneText");for(const s of r.content)s.type==="thinking"&&await c(t,e,o,"node.thinking.done",{entry_id:n.id,text:s.thinking}),s.type==="text"&&await a(),s.type==="toolCall"&&(await a(),await c(t,e,o,"node.tool_call.started",{entry_id:n.id,tool_call_id:s.id,name:s.name,arguments:s.arguments}));if(await a(),r.usage){const s=v(r.usage),p=await t.prepare("SELECT usage_json, grant_id FROM nodes WHERE node_id = ?").get(e),y=p.usage_json?JSON.parse(p.usage_json):w(),d=w();for(const m of Object.keys(d))d[m]=y[m]+s[m];await t.prepare("UPDATE nodes SET usage_json = ? WHERE node_id = ?").run(JSON.stringify(d),e),await c(t,e,o,"usage",{entry_id:n.id,served_model:r.model,payer:await N(p.grant_id),...s,usage:d})}await t.prepare("DELETE FROM run_events WHERE run_id = ? AND node_id = ? AND type IN ('node.thinking.delta', 'node.output_text.delta')").run(e,o)}r.role==="toolResult"&&await c(t,e,o,"node.tool_call.completed",{entry_id:n.id,tool_call_id:r.toolCallId,name:r.toolName,result:r.content,status:r.isError?"error":"ok"})}}return l}_(Y,"appendConversationEvents");export{D as SYSTEM_PROMPT_TYPE,g as TURN_END_TYPE,k as TURN_INPUT_TYPE,Y as appendConversationEvents,A as rootRepromptPending};
@@ -1,7 +1,7 @@
1
- var ce=Object.defineProperty;var o=(e,n)=>ce(e,"name",{value:n,configurable:!0});import{envBashAutoBgDeadlineMs as z,envBashValveMs as ue,envNodeId as de}from"../shared/env.js";import{closeSync as le,existsSync as v,mkdirSync as K,openSync as fe,readFileSync as W,readSync as he,rmSync as q,statSync as X,writeFileSync as $}from"node:fs";import{homedir as be}from"node:os";import{dirname as me}from"node:path";import{performance as N}from"node:perf_hooks";import{backgroundBashJob as Y,bashJobPaths as pe,clearJobDeadlineFile as ge,writeJobDeadlineFile as we,cancelBashJobProcessTree as ye,countJobLogLines as ve,formatBashElapsed as Q,newBashJobId as Ee,normalizeBashJobPurpose as je,tailJobLog as Ie}from"../core/bash-jobs.js";import{MAX_BACKGROUND_BASH_LOG_BYTES as ht,BACKGROUND_BASH_LOG_TRUNCATION_MARKER as bt}from"../core/bash-job-supervisor.js";import{brokerApiUrl as _e,recordBackgroundedJob as Be,reportBrokerJob as Se,stopBrokerBashJob as ke}from"../core/runtime/broker/daemon-ops.js";import{bashJobsUseLauncher as Le,launchBashJobSupervisor as Ae}from"../core/runtime/broker/bash-job-launch.js";import{JobReporter as xe}from"../core/runtime/broker/job-reporter.js";import{bashCommandRefusal as Oe}from"../core/bash-guard.js";import{readConfig as Je}from"../core/config.js";import{PREVIEW_RESULT_PATH_ENV as Re,previewResultPath as Te}from"../core/preview-result-path.js";import{Type as _}from"typebox";import{createBashToolDefinition as Z}from"@earendil-works/pi-coding-agent";const $e=200;function Ne(){return ue()}o(Ne,"resolveValveMs");function Ce(e){return pe(e,Ee())}o(Ce,"makeJobPaths");const B=new Set;let ee=!1;function te(){for(const e of[...B])try{Y(e),B.delete(e)}catch(n){process.stderr.write(`crtr: failed to background bash job ${e.jobId} during broker termination: ${n.message}
2
- `)}}o(te,"backgroundLiveJobsForTermination");function Me(){ee||(ee=!0,process.prependListener("SIGTERM",te),process.platform!=="win32"&&process.prependListener("SIGHUP",te))}o(Me,"installTerminationHandoff");const De=64*1024;function C(e,n,i){let s;try{s=X(e)}catch{return n}if(s.size<=n)return n;const c=fe(e,"r");try{for(;n<s.size;){const b=Math.min(De,s.size-n),m=Buffer.allocUnsafe(b),u=he(c,m,0,b,n);if(u===0)break;i(m.subarray(0,u)),n+=u}return n}finally{le(c)}}o(C,"tailOnce");function E(e){try{q(e,{recursive:!0,force:!0})}catch{}}o(E,"cleanupJobDir");function Pe(e){try{const n=W(e,"utf8").trim(),i=Number(n);return Number.isFinite(i)?i:null}catch{return null}}o(Pe,"readExitCode");function Ue(e){try{if(X(e).isDirectory())return{cwd:e}}catch{}const n=be();return{cwd:n,warning:`[working directory no longer exists: ${e}; running from ${n}]
3
- `}}o(Ue,"resolveExecutionCwd");function ne(e,n,i=()=>null,s,c=()=>{}){return{exec:o(async(b,m,{onData:u,signal:f,timeout:p,env:S})=>new Promise((j,d)=>{const w=i();if(f?.aborted){d(new Error("aborted"));return}const k=Oe(b,m);if(k!==null){d(new Error(k));return}const t=Ce(n);K(t.dir,{recursive:!0}),$(t.cmdSh,b),$(t.jobLog,""),$(t.jobRun,"");let l=0,g=!1,I,L,A,M=!1;const oe=Le(),D=N.now(),re=Ne();let y;const ie=o(()=>{y&&clearInterval(y),f&&f.removeEventListener("abort",G),B.delete(t)},"teardown"),h=o(r=>{g||(g=!0,ie(),r())},"finish");let P=!1;function x(r=!1){if(g||P)return;P=!0,y&&clearInterval(y);const a=r?Date.now()+z():void 0;a!==void 0&&we(t,a),Be(e,t.jobId,{command:W(t.cmdSh,"utf8"),...w===null?{}:{purpose:w},...a===void 0?{}:{deadline_at_ms:a}}).then(()=>{try{ge(t)}catch{}U(r,"")},T=>U(r,`
4
- [crtr could not record job ${t.jobId} (${T.message}); it will NOT message you when it exits. Watch its log.]`))}o(x,"finishBackground");function U(r,a){const T=Q(N.now()-D);let H="";if(r){const ae=z();H=`It will be CANCELED in ${Q(ae)} unless you claim it: crtr node bash extend ${t.jobId} --for <duration> (or --keep to run to completion). `}const V=`
5
- [backgrounded as job ${t.jobId} after ${T} in the foreground${r?" (auto)":""}. `+H+(a===""?"It will interrupt you with a message when it exits. ":"")+`Watch: tail -f ${t.jobLog} ; stop: crtr node bash kill ${t.jobId}]`;u(Buffer.from(V+a)),c({jobId:t.jobId,logPath:t.jobLog,notice:V+a}),h(()=>j({exitCode:0}))}o(U,"handOff");function F(){l=C(t.jobLog,l,u);const r=Pe(t.jobExit);h(()=>j({exitCode:r})),E(t.dir)}o(F,"finishForeground");function se(r=!1){const a=Y(t);if(a==="backgrounded"||a==="already-backgrounded"){x(r);return}if(a==="finished"){F();return}h(()=>d(new Error(`bash job ${t.jobId} disappeared before it could be backgrounded`))),E(t.dir)}o(se,"requestBackground");function O(r){if(!(g||M)){if(l=C(t.jobLog,l,u),v(t.jobBg)){x();return}if(!v(t.jobExit)){if(I===void 0){A??=r;return}if(oe){M=!0,ke(e,t.jobId).then(()=>{h(()=>d(r)),E(t.dir)},a=>h(()=>d(a)));return}I!==void 0&&L!==void 0&&ye(I,L),h(()=>d(r)),E(t.dir)}}}o(O,"requestStop");function G(){O(new Error("aborted"))}o(G,"onAbort"),f&&f.addEventListener("abort",G,{once:!0});const J=Ue(m);J.warning&&u(Buffer.from(J.warning));let R=S??process.env;s!==void 0&&(K(me(s),{recursive:!0}),q(s,{force:!0}),R={...R,[Re]:s}),Ae(e,t,n,J.cwd,R).then(r=>{I=r.pgid,L=r.identity,B.add(t),A!==void 0&&O(A)},r=>{h(()=>d(r)),E(t.dir)}),y=setInterval(()=>{if(l=C(t.jobLog,l,u),v(t.jobDone)){F();return}if(v(t.jobBg)){x();return}if(v(t.jobExit))return;const r=N.now()-D;if(p!==void 0&&p>0){r>=p*1e3&&O(new Error(`timeout:${p}`));return}r>=re&&se(!0)},$e)}),"exec")}}o(ne,"createValveOperations");const Fe=["One short clause naming what this step is FOR, in the words of the person you",'are working for \u2014 "Reading the Acme thread", not "Fetching emails" and never','"Running GMAIL_FETCH_EMAILS". A person reads this while the command runs; it',"is the only thing they see of this step. Under about eight words. Omit it for","steps that only touch your own scratch work."].join(" "),Ge=3;function He(e){const n=Ie(e.logPath,Ge),i=Math.max(0,ve(e.logPath)-n.length),s=n.length===0?"(no output yet)":n.join(`
1
+ var fe=Object.defineProperty;var o=(e,n)=>fe(e,"name",{value:n,configurable:!0});import{envBashAutoBgDeadlineMs as q,envBashValveMs as he,envNodeId as be}from"../shared/env.js";import{closeSync as me,existsSync as v,mkdirSync as X,openSync as pe,readFileSync as Y,readSync as ge,rmSync as Q,statSync as Z,writeFileSync as M}from"node:fs";import{homedir as we}from"node:os";import{dirname as ye}from"node:path";import{performance as N}from"node:perf_hooks";import{backgroundBashJob as ee,bashJobPaths as ve,clearJobDeadlineFile as Ee,writeJobDeadlineFile as _e,cancelBashJobProcessTree as je,countJobLogLines as Se,formatBashElapsed as te,newBashJobId as ke,normalizeBashJobPurpose as Ie,tailJobLog as Ae}from"../core/bash-jobs.js";import{MAX_BACKGROUND_BASH_LOG_BYTES as gt,BACKGROUND_BASH_LOG_TRUNCATION_MARKER as wt}from"../core/bash-job-supervisor.js";import{brokerApiUrl as Be,recordBackgroundedJob as Le,reportBrokerJob as xe,stopBrokerBashJob as Oe}from"../core/runtime/broker/daemon-ops.js";import{bashJobsUseLauncher as Te,launchBashJobSupervisor as Je}from"../core/runtime/broker/bash-job-launch.js";import{JobReporter as Re}from"../core/runtime/broker/job-reporter.js";import{bashCommandRefusal as $e}from"../core/bash-guard.js";import{readConfig as Me}from"../core/config.js";import{PREVIEW_RESULT_PATH_ENV as Ne,previewResultPath as Ce}from"../core/preview-result-path.js";import{Type as S}from"typebox";import{createBashToolDefinition as ne}from"@earendil-works/pi-coding-agent";const oe=200,De=5e3;function Pe(){return he()}o(Pe,"resolveValveMs");function Ue(e){return ve(e,ke())}o(Ue,"makeJobPaths");const k=new Set;let re=!1;function ie(){for(const e of[...k])try{ee(e),k.delete(e)}catch(n){process.stderr.write(`crtr: failed to background bash job ${e.jobId} during broker termination: ${n.message}
2
+ `)}}o(ie,"backgroundLiveJobsForTermination");function Fe(){re||(re=!0,process.prependListener("SIGTERM",ie),process.platform!=="win32"&&process.prependListener("SIGHUP",ie))}o(Fe,"installTerminationHandoff");const Ge=64*1024;function C(e,n,i){let s;try{s=Z(e)}catch{return n}if(s.size<=n)return n;const c=pe(e,"r");try{for(;n<s.size;){const b=Math.min(Ge,s.size-n),m=Buffer.allocUnsafe(b),u=ge(c,m,0,b,n);if(u===0)break;i(m.subarray(0,u)),n+=u}return n}finally{me(c)}}o(C,"tailOnce");function E(e){try{Q(e,{recursive:!0,force:!0})}catch{}}o(E,"cleanupJobDir");function He(e){try{const n=Y(e,"utf8").trim(),i=Number(n);return Number.isFinite(i)?i:null}catch{return null}}o(He,"readExitCode");function Ve(e){try{if(Z(e).isDirectory())return{cwd:e}}catch{}const n=we();return{cwd:n,warning:`[working directory no longer exists: ${e}; running from ${n}]
3
+ `}}o(Ve,"resolveExecutionCwd");function se(e,n,i=()=>null,s,c=()=>{}){return{exec:o(async(b,m,{onData:u,signal:f,timeout:p,env:I})=>new Promise((_,d)=>{const w=i();if(f?.aborted){d(new Error("aborted"));return}const A=$e(b,m);if(A!==null){d(new Error(A));return}const t=Ue(n);X(t.dir,{recursive:!0}),M(t.cmdSh,b),M(t.jobLog,""),M(t.jobRun,"");let l=0,g=!1,j,B,L,D=!1;const ae=Te(),P=N.now();let U=0,x=P;const F=o(()=>N.now()-P-U,"foregroundMs"),ce=Pe();let y;const ue=o(()=>{y&&clearInterval(y),f&&f.removeEventListener("abort",z),k.delete(t)},"teardown"),h=o(r=>{g||(g=!0,ue(),r())},"finish");let G=!1;function O(r=!1){if(g||G)return;G=!0,y&&clearInterval(y);const a=r?Date.now()+q():void 0;a!==void 0&&_e(t,a),Le(e,t.jobId,{command:Y(t.cmdSh,"utf8"),...w===null?{}:{purpose:w},...a===void 0?{}:{deadline_at_ms:a}}).then(()=>{try{Ee(t)}catch{}H(r,"")},$=>H(r,`
4
+ [crtr could not record job ${t.jobId} (${$.message}); it will NOT message you when it exits. Watch its log.]`))}o(O,"finishBackground");function H(r,a){const $=te(F());let K="";if(r){const le=q();K=`It will be CANCELED in ${te(le)} unless you claim it: crtr node bash extend ${t.jobId} --for <duration> (or --keep to run to completion). `}const W=`
5
+ [backgrounded as job ${t.jobId} after ${$} in the foreground${r?" (auto)":""}. `+K+(a===""?"It will interrupt you with a message when it exits. ":"")+`Watch: tail -f ${t.jobLog} ; stop: crtr node bash kill ${t.jobId}]`;u(Buffer.from(W+a)),c({jobId:t.jobId,logPath:t.jobLog,notice:W+a}),h(()=>_({exitCode:0}))}o(H,"handOff");function V(){l=C(t.jobLog,l,u);const r=He(t.jobExit);h(()=>_({exitCode:r})),E(t.dir)}o(V,"finishForeground");function de(r=!1){const a=ee(t);if(a==="backgrounded"||a==="already-backgrounded"){O(r);return}if(a==="finished"){V();return}h(()=>d(new Error(`bash job ${t.jobId} disappeared before it could be backgrounded`))),E(t.dir)}o(de,"requestBackground");function T(r){if(!(g||D)){if(l=C(t.jobLog,l,u),v(t.jobBg)){O();return}if(!v(t.jobExit)){if(j===void 0){L??=r;return}if(ae){D=!0,Oe(e,t.jobId).then(()=>{h(()=>d(r)),E(t.dir)},a=>h(()=>d(a)));return}j!==void 0&&B!==void 0&&je(j,B),h(()=>d(r)),E(t.dir)}}}o(T,"requestStop");function z(){T(new Error("aborted"))}o(z,"onAbort"),f&&f.addEventListener("abort",z,{once:!0});const J=Ve(m);J.warning&&u(Buffer.from(J.warning));let R=I??process.env;s!==void 0&&(X(ye(s),{recursive:!0}),Q(s,{force:!0}),R={...R,[Ne]:s}),Je(e,t,n,J.cwd,R).then(r=>{j=r.pgid,B=r.identity,k.add(t),L!==void 0&&T(L)},r=>{h(()=>d(r)),E(t.dir)}),y=setInterval(()=>{const r=N.now();if(r-x>De&&(U+=r-x-oe),x=r,l=C(t.jobLog,l,u),v(t.jobDone)){V();return}if(v(t.jobBg)){O();return}if(v(t.jobExit))return;const a=F();if(p!==void 0&&p>0){a>=p*1e3&&T(new Error(`timeout:${p}`));return}a>=ce&&de(!0)},oe)}),"exec")}}o(se,"createValveOperations");const ze=["One short clause naming what this step is FOR, in the words of the person you",'are working for \u2014 "Reading the Acme thread", not "Fetching emails" and never','"Running GMAIL_FETCH_EMAILS". A person reads this while the command runs; it',"is the only thing they see of this step. Under about eight words. Omit it for","steps that only touch your own scratch work."].join(" "),Ke=3;function We(e){const n=Ae(e.logPath,Ke),i=Math.max(0,Se(e.logPath)-n.length),s=n.length===0?"(no output yet)":n.join(`
6
6
  `),c=i===0?"":`
7
- [${i} earlier output line${i===1?"":"s"} are in the job log only]`;return{content:[{type:"text",text:`${s}${c}${e.notice}`}],details:void 0}}o(He,"handoffResult");function Ve(e){return{...e,parameters:_.Object({purpose:_.Optional(_.String({description:Fe})),...e.parameters.properties})}}o(Ve,"withPurpose");const ze=["A command that needs longer than one call \u2014 a test lane, a build, a soak \u2014 is started with","`crtr node bash run '<command>'`, which returns at once and wakes you with the exit code; the job is a canvas","object others can watch. Do not use `&`, `nohup`, `setsid`, or a cron that polls a log. A foreground command","past 5 minutes is moved to a job automatically; a `timeout` kills it and everything it started."].join(" ");function Ke(e){const{command:n,...i}=e.parameters.properties;return{...e,parameters:_.Object({command:{...n,description:`${n.description??""} ${ze}`.trim()},...i})}}o(Ke,"withJobGuidance");function We(e,n,i,s){const c=Ke(Z(i,{operations:ne(e,n)}));return{...s?Ve(c):c,execute:o(async(u,f,p,S,j)=>{const d=s?je(f.purpose):null;let w=null;const t=await Z(i,{operations:ne(e,n,()=>d,Te(u),g=>{w=g})}).execute(u,f,p,S,j),l=w;return l===null?t:He(l)},"execute")}}o(We,"createValveToolDefinition");function qe(e){const n=de();if(n===void 0||n.trim()==="")return;const i=process.env.CRTR_CONTEXT_DIR;i===void 0||i.trim()===""||(Me(),_e()!==void 0&&new xe(i,(s,c)=>Se(n,s,c)).start(),e.on("session_start",(s,c)=>{e.registerTool(We(n,i,c.cwd,Je("user").bash_tool_purpose))}))}o(qe,"default");export{bt as BACKGROUND_BASH_LOG_TRUNCATION_MARKER,ht as MAX_BACKGROUND_BASH_LOG_BYTES,ne as createValveOperations,We as createValveToolDefinition,qe as default};
7
+ [${i} earlier output line${i===1?"":"s"} are in the job log only]`;return{content:[{type:"text",text:`${s}${c}${e.notice}`}],details:void 0}}o(We,"handoffResult");function qe(e){return{...e,parameters:S.Object({purpose:S.Optional(S.String({description:ze})),...e.parameters.properties})}}o(qe,"withPurpose");const Xe=["A command that needs longer than one call \u2014 a test lane, a build, a soak \u2014 is started with","`crtr node bash run '<command>'`, which returns at once and wakes you with the exit code; the job is a canvas","object others can watch. Do not use `&`, `nohup`, `setsid`, or a cron that polls a log. A foreground command","past 5 minutes is moved to a job automatically; a `timeout` kills it and everything it started."].join(" ");function Ye(e){const{command:n,...i}=e.parameters.properties;return{...e,parameters:S.Object({command:{...n,description:`${n.description??""} ${Xe}`.trim()},...i})}}o(Ye,"withJobGuidance");function Qe(e,n,i,s){const c=Ye(ne(i,{operations:se(e,n)}));return{...s?qe(c):c,execute:o(async(u,f,p,I,_)=>{const d=s?Ie(f.purpose):null;let w=null;const t=await ne(i,{operations:se(e,n,()=>d,Ce(u),g=>{w=g})}).execute(u,f,p,I,_),l=w;return l===null?t:We(l)},"execute")}}o(Qe,"createValveToolDefinition");function Ze(e){const n=be();if(n===void 0||n.trim()==="")return;const i=process.env.CRTR_CONTEXT_DIR;i===void 0||i.trim()===""||(Fe(),Be()!==void 0&&new Re(i,(s,c)=>xe(n,s,c)).start(),e.on("session_start",(s,c)=>{e.registerTool(Qe(n,i,c.cwd,Me("user").bash_tool_purpose))}))}o(Ze,"default");export{wt as BACKGROUND_BASH_LOG_TRUNCATION_MARKER,gt as MAX_BACKGROUND_BASH_LOG_BYTES,se as createValveOperations,Qe as createValveToolDefinition,Ze as default};