@north-light/cli 0.3.447 → 0.3.448
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/nodes.d.ts +5 -0
- package/dist/api/dto/objects.d.ts +33 -2
- package/dist/api/error-codes.d.ts +15 -0
- package/dist/api/error-codes.js +1 -1
- package/dist/clients/attach/viewer.js +513 -513
- package/dist/commands/canvas/list.js +3 -3
- package/dist/commands/canvas/read.js +4 -4
- package/dist/commands/node/inspect.js +8 -8
- package/dist/commands/sys/sync-shared.js +1 -1
- package/dist/commands/sys/update.js +1 -1
- package/dist/core/feed/inbox.js +1 -1
- package/dist/core/graph/events.js +8 -8
- package/dist/core/peer/client.d.ts +2 -0
- package/dist/core/peer/client.js +1 -1
- package/dist/core/peer/directory.js +1 -1
- package/dist/core/peer/home.d.ts +40 -0
- package/dist/core/peer/home.js +2 -0
- package/dist/core/peer/names.d.ts +3 -0
- package/dist/core/peer/names.js +1 -0
- package/dist/core/peer/stubs.d.ts +2 -0
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/peer/version.d.ts +2 -2
- package/dist/core/peer/version.js +1 -1
- package/dist/core/runtime/broker/inbox.js +1 -1
- package/dist/core/scoped-state/settings.js +1 -1
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.d.ts +4 -0
- package/dist/daemon/api/handlers/objects.js +2 -2
- package/dist/daemon/peer/forward.d.ts +69 -0
- package/dist/daemon/peer/forward.js +1 -0
- package/dist/daemon/peer/handlers.d.ts +2 -0
- package/dist/daemon/peer/handlers.js +1 -1
- package/dist/shared/generated-context.d.ts +8 -0
- package/dist/shared/generated-context.js +4 -4
- package/dist/shared/inbox-entry-body.js +5 -5
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/tree-cache.json +0 -728
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)[0].slice(0,120)}
|
|
1
|
+
var de=Object.defineProperty;var u=(t,e)=>de(t,"name",{value:e,configurable:!0});import{randomBytes as ce}from"node:crypto";import{claimNodeMail as ue,acknowledgeNodeMail as le}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as fe}from"../../../core/feed/inbox.js";import{enqueueNodeMail as J,cancelPendingNodeMail as me}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 pe,interruptLive as ye}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as he}from"../../../core/profiles/manifest.js";import{getNode as A,withFreshTerminalGuard as be}from"../../../core/canvas/canvas.js";import{getById as D,nodeObject as F,ownerForGrantee as we}from"../../../core/graph/objects.js";import{recordActedOn as ge}from"../../../core/graph/edges.js";import{recordWatch as G}from"../../../core/graph/watches.js";import{publish as H}from"../../../core/graph/events.js";import{readerFor as V}from"../reader.js";import{canRead as ve}from"../../../core/graph/access.js";import{withCanvasWrite as _}from"../../../core/canvas/db.js";import{getPendingStructuredRequestForNode as K}from"../../../core/canvas/structured-requests.js";import{cancelCronsOnWake as Q}from"../../../core/canvas/crons.js";import{assertNotFinalized as M,assertFinalizedForReopen as _e,commitReopenResident as P}from"../../../core/runtime/reopen.js";import{admitLegacyStructuredOutput as ke}from"../../structured-requests/sidecar.js";import{appendSituationalContext as E,formatSituationalProse as Se}from"../../../core/runtime/situational-context.js";import{formatDataCard as X}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as $e}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as Ne}from"../../park-pending.js";import{wantsExecution as je}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as qe}from"../../../core/runtime/revive.js";import{CrtrError as xe,notFound as C,usage as c}from"../../../core/errors.js";import{emitEvent as Ae}from"../../../core/events/emit.js";import{assertScope as Ce}from"../../../core/scopes.js";import{InputError as I}from"../../../core/io.js";import{ApiError as Oe}from"../../../api/index.js";import{describeObject as Re,stubOf as Fe}from"../../../core/peer/stubs.js";import{machineNameOf as Y}from"../../../core/peer/names.js";import{callerNode as Me,callerStub as Pe,forwardVerb as Z,relayError as ee,remoteStub as Ee,unknownError as te,withMachine as re}from"../../peer/forward.js";import{ownerOnly as Ie}from"../router.js";const Te=["critical","urgent","normal","deferred"];function ne(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw c(`${e} must be an object { kind, facts?, body? }`);const i=t,n=i.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=i.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[f,m]of Object.entries(o)){if(typeof m!="string"&&typeof m!="number")throw c(`${e}.facts.${f} must be a string or number`);d[f]=m}r.facts=d}const s=i.body;if(s!==void 0){if(typeof s!="string")throw c(`${e}.body must be a string`);r.body=s}return r}u(ne,"parseCardRequest");function oe(t,e){try{return X(t.kind,t.facts??{},t.body??"")}catch(i){throw c(`${e}: ${i instanceof Error?i.message:String(i)}`)}}u(oe,"renderCard");function Be(t){if(typeof t!="object"||t===null)throw c("a message requires a JSON body { body, tier?, fresh? }");const e=t,i=e.body,n=e.fresh===!0,r=e.tier,o=e.situational_context,s=e.output_schema,d=typeof i=="string"&&i.trim()!=="",f=typeof o=="string"&&o.trim()!=="",m=typeof s=="string"&&s.trim()!=="",S=e.situational_card,g=e.context_cards,h=S===void 0?void 0:ne(S,"situational_card");if(g!==void 0&&!Array.isArray(g))throw c("context_cards must be an array of { kind, facts?, body? }");const p=g?.map((k,N)=>ne(k,`context_cards[${N}]`));if(h!==void 0&&typeof o=="string"&&o!=="")throw c("situational_card and situational_context are mutually exclusive");const $=h!==void 0||p!==void 0&&p.length>0;if(!n&&!d&&!f&&!m&&!$)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&&!Te.includes(r))throw c(`invalid tier: ${String(r)} (expected critical|urgent|normal|deferred)`);const l={body:typeof i=="string"?i:""};r!==void 0&&(l.tier=r),n&&(l.fresh=!0),e.reopen===!0&&(l.reopen=!0),typeof o=="string"&&(l.situational_context=o),h!==void 0&&(l.situational_card=h),p!==void 0&&(l.context_cards=p),typeof s=="string"&&(l.output_schema=s),typeof e.from=="string"&&(l.from=e.from);const b=e.delivery;if(b!==void 0&&b!=="interactive")throw c(`invalid delivery: ${String(b)} (expected interactive)`);if(b==="interactive"){if(n||l.situational_context!==void 0||l.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(l.tier==="deferred")throw c("interactive delivery cannot be deferred");l.delivery="interactive"}return l}u(Be,"parseSendBody");function ze(t){try{return JSON.parse(t)}catch{throw c("output_schema must be a JSON schema string")}}u(ze,"parseSchema");function We(t){return t.split(`
|
|
2
|
+
`)[0].slice(0,120)}u(We,"label");function ie(t,e){return e===null?"":X("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}u(ie,"previousFinalReportCard");function Je(t,e,i){if(i!==null&&i!=="human"&&D(t,i)?.type==="node"){const o=F(t,i);return{actor:o,senderNode:o}}if(i==="human")return{actor:we(t,"user:local"),senderNode:null};const n=V(t,e);return{actor:n.class==="person"?n.person:n.class==="app"?n.app:n.node,senderNode:n.class==="node"?n.node:null}}u(Je,"messageActor");function ae(t,e,i,n,r,o){const s=F(t,i),{actor:d,senderNode:f}=Je(t,e,n),m=r===null?{}:{pointer:r};ge(t,d,s),f!==null&&f.rowid!==s.rowid&&G(t,f,s,"message",{endsOn:o&&r!==null?`result:${r}`:"final"}),H(t,{event:"messaged",object:s,actor:d,attrs:{},...m}),f!==null&&H(t,{event:"sent",object:f,actor:f,attrs:{to:s.id},...m})}u(ae,"recordMessage");function Le(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(Le,"deferredNoNaturalCycle");function Ue(t){if(!qe(t))throw new Oe(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}u(Ue,"assertRecoverableForFresh");function De(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}:{error:"wake_failed",message:"the target could not be woken; see the daemon log",message_id:e}}u(De,"wakeFailure");async function Ge(t,e){const i=typeof t.body=="object"&&t.body!==null&&!Array.isArray(t.body)?{...t.body}:t.body;typeof i=="object"&&i!==null&&delete i.from;const n=await Z(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/messages`,body:i});if(n.kind==="local")return null;if(n.kind==="unknown")throw te(e,n.unreachable);if(n.status>=400)throw ee(n.status,n.body);return _(r=>{const o=Me(r,t);if(o===null)return;const s=n.body?.object,d=Ee(r,e,"node",n.machine.id,s);G(r,o,d,"message",{endsOn:"final"})}),{status:n.status,body:re(n.body,n.machine)}}u(Ge,"forwardMessage");async function He(t){const e=await Ve(t);if(t.principal.class!=="forwarded"||typeof e.body!="object"||e.body===null)return e;const i=_(n=>{const r=F(n,t.params.id);return ve(n,V(n,t),r)?Re(n,r):{id:r.id,type:r.type,kind:null,name:r.id,owner:null}});return{...e,body:{...e.body,object:i}}}u(He,"handleMessage");async function Ve(t){const e=t.params.id,i=await Ge(t,e);if(i!==null)return i;const n=A(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=Be(t.body),o=r.tier??"normal",s=he(n.profile_id),d=t.principal.class==="forwarded"?_(a=>Pe(a,t)?.id??null):r.from??null;if(d!==null){const a=A(d);a!==null&&Ce(a,"crtr:act")}const f=d===null?null:_(a=>{const y=D(a,d);return y===null?null:Fe(a,y)?.home_machine??null}),m=f===null?void 0:`${d} on ${Y(f)}`,S=f===null?{}:{from_machine:Y(f)},g=r.body.trim()!=="",h=r.situational_card!==void 0?oe(r.situational_card,"situational_card"):r.situational_context!==void 0?Se(r.situational_context.trim()):"",p=h!=="",$=(r.context_cards??[]).map((a,y)=>oe(a,`context_cards[${y}]`)),l=r.output_schema!==void 0&&r.output_schema.trim()!==""?ze(r.output_schema):null;let b=!1;const k=u(a=>{if(!(l===null||b)){if(K(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."});ke(e,"oneoff",l,a),b=!0}},"ensureSchema");if(r.fresh){const a=r.reopen?_e(e):null;r.reopen||M(e),Ue(e),k(),p&&E(e,h),r.reopen&&P(e,a);const y=await L(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:y.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&M(e);let N=!1,v="";if(r.delivery==="interactive"&&r.reopen&&(v=ie(e,P(e)),N=!0),r.delivery==="interactive"&&k(),r.delivery==="interactive"&&!s&&!n.run_id&&R(n))try{return p&&E(e,h),await pe(e,r.body,{cards:[...v===""?[]:[v],...p?[h]:[],...$],origin:d==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...d===null?{}:{from:d},...m===void 0?{}:{fromName:m},kind:"message",tier:o}]}}),_(y=>ae(y,t,e,d,null,!1)),Q(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(a){if(!(a instanceof U))throw a}const T=u(()=>{r.reopen||M(e);const a=ce(16).toString("hex"),y=u(x=>ae(x,t,e,d,a,l!==null),"withinEnqueue");k(a),p&&E(e,h),r.reopen&&!N&&(v=ie(e,P(e)));const O=[...v===""?[]:[v],...$],W=O.length>0?{cards:O}:{};if(g||l!==null){const x=g?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: "${K(e)?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return J(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:a,withinEnqueue:y,label:We(x),bodyJson:{body:x,...S,...p?{situational:!0}:{},...W}})}return J(e,{senderNodeId:d,...m===void 0?{}:{senderName:m},urgency:o,wake:1,kind:"message",messageId:a,withinEnqueue:y,label:p?"(ambient context updated)":"(context delivered)",bodyJson:{...p?{situational:!0}:{},situationalOnly:!0,...W}})},"deliverImmediate"),w=u(()=>{if(o==="deferred"){const a=be(e,$e,T);if(a.kind==="missing")throw C(`unknown node: ${e}`,{received:e});if(a.kind==="terminal")throw Le(e,a.status);return a.result}return T()},"deliver")();w.urgency!=="deferred"&&_(()=>Ne(e));const j=A(e);if(j===null)throw C(`unknown node: ${e}`,{received:e});n.frozen_at!==null&&Q(e);let B=!1,z=!1,q;if((r.reopen||j.lifecycle==="terminal"||!je(j))&&w.urgency!=="deferred"&&!s&&!R(j))try{const a=await L(e,{resume:!0,capacity:"freeze"});B=a.launch!==void 0,z=a.outcome==="frozen"}catch(a){q=De(a,w.messageId),Ae({level:"error",event:"message.wake_failed",node_id:e,error:a,fields:{message_id:w.messageId,error_code:q.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:B,...z?{not_revived_reason:"capacity_frozen"}:{},...q===void 0?{}:{wake_failed:q},delivered_at:w.createdAt,...w.urgency===o?{}:{delivered_tier:w.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}u(Ve,"handleMessageHere");async function Ke(t){const e=t.params.id,i=await Z(t,e,{method:"POST",path:`/v1/nodes/${encodeURIComponent(e)}/interrupt`,body:t.body});if(i.kind==="unknown")throw te(e,i.unreachable);if(i.kind==="remote"){if(i.status>=400)throw ee(i.status,i.body);return{status:i.status,body:re(i.body,i.machine)}}const n=A(e);if(n===null)throw C(`unknown node: ${e}`,{received:e});const r=me(e,{senderNodeId:"human",kind:"message"});let o=!1;if(R(n))try{o=await ye(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(Ke,"handleInterrupt");function se(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(se,"mailBody");function Qe(t){const e=se(t),i=e.channel;if(i!=="wake"&&i!=="passive"&&i!=="deferred_run")throw c("channel must be wake, passive, or deferred_run");const n=ue(t.params.id,e.execution_id,i);return{status:200,body:{action:n.action,deliveries:n.deliveries.map(o=>({delivery_id:o.deliveryId,attempts:o.attempts,handoff:o.handoff,entry:{...fe(o),seq:o.message.seq}}))}}}u(Qe,"handleMailClaim");function Xe(t){const e=se(t);if(!Array.isArray(e.deliveries))throw c("deliveries must be an array");const i=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=le(t.params.id,e.execution_id,i.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(Xe,"handleMailAcknowledge");const Tt=Ie([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:Qe},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:Xe}]),Bt=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:He},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Ke}];export{Tt as brokerMailRoutes,He as handleMessage,Bt as messageRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var Se=Object.defineProperty;var a=(e,t)=>Se(e,"name",{value:t,configurable:!0});import{prepared as X}from"../../../core/sqlite-statements.js";import{envProfileId as Re}from"../../../shared/env.js";import{pausedCanvasProfiles as Oe}from"../../../core/profiles/manifest.js";import{existsSync as A,realpathSync as Z,statSync as q}from"node:fs";import{isAbsolute as F,resolve as T}from"node:path";import{appendSituationalContext as Ie,formatSituationalProse as $e}from"../../../core/runtime/situational-context.js";import{closeNode as Ce}from"../../../core/runtime/close.js";import{reviveNode as Ne}from"../../../core/runtime/revive.js";import{nowIso as G}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as B,forkNode as Ae,resolveForkSource as Te,spawnChildPrepared as Pe}from"../../../core/runtime/spawn.js";import{forkSourceNode as Ee,newNodeId as ee}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as ne,childrenOf as De,completeCreateRequest as te,findCreateRequest as Le,getNode as k,recordCreateRequestNode as je,reserveCreateRequest as oe,reserveCreateRequestNode as Me,listNodes as re,recordRespawnAttempt as Fe,subscribersOf as Ge,subscriptionsOf as ie,setMessageWait as Be,updateNode as N}from"../../../core/canvas/canvas.js";import{subtreeIds as xe}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as x}from"../../../core/canvas/db.js";import{nodeObject as Ke}from"../../../core/graph/objects.js";import{recordActedOn as We}from"../../../core/graph/edges.js";import{publish as Ve}from"../../../core/graph/events.js";import{readerFor as ze}from"../reader.js";import{relocateSessionCwd as Je,unbindSession as Ue}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as He}from"../../../core/canvas/attention.js";import{isSafeNodeId as Ye}from"../../../core/canvas/paths.js";import{contextDir as de,nodeAgentDir as K}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as Qe}from"../../cron/authority.js";import{cronBirthPlacement as Xe}from"../../cron/armed-context.js";import{existsBeneath as Ze,isAbsentOrRefused as qe,isBeneathRefusal as en,readdirBeneath as nn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as tn,readNodeSession as on,readNodeSnapshot as rn,transcriptMarkdown as dn}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as sn}from"../../../core/substrate/subject.js";import{reviveAll as an}from"../../../core/runtime/revive-all.js";import{promoteAsync as ln,requestYieldAsync as cn,reshapeNodeAsync as W}from"../../../core/runtime/promote.js";import{recycleNode as fn}from"../../../core/runtime/recycle.js";import{relaunchRoot as un}from"../../../core/runtime/reset.js";import{assertReopenGate as pn}from"../../../core/runtime/reopen.js";import{writeYieldMessage as mn,readGoal as hn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as wn,hasRoadmap as yn}from"../../../core/runtime/roadmap.js";import{renameWindow as _n}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as gn,explicitModelIntent as bn,normalizeModel as vn,readMergedLaunchConfigAsync as se}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as kn}from"../../../core/model-routes.js";import{persistDormantModel as Sn,setModelLive as Rn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as On}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as In}from"../../../core/runtime/broker-request.js";import{boundFleet as V}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as $n}from"../../structured-requests/sidecar.js";import{OUTCOME_PAYLOAD_MAX_BYTES as ae}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as Cn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Nn}from"../../../core/human-actions.js";import{parseDurationMs as An}from"../../../core/wake.js";import{claimWarmNode as Tn,refillWarmPool as le,resumeWarmClaim as Pn,warmPoolEnabled as En}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as z,isLaunchKind as Dn,resolveLaunchTarget as Ln}from"../../../core/runtime/launch-target.js";import{fullName as jn}from"../../../core/canvas/labels.js";import{reportsForNode as ce}from"./reports.js";import{requireUsableProfile as Mn}from"./profiles.js";import{assertProfileActive as Fn,loadExactProfileManifest as Gn}from"../../../core/profiles/manifest.js";import{getCron as fe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Bn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as xn}from"../../control.js";import{notFound as P,usage as h}from"../../../core/errors.js";import{assertScope as Kn,validateScopes as ue}from"../../../core/scopes.js";import{scopeAllowed as O}from"../../../shared/env.js";import{toCloseResultDTO as Wn,toNodeDetailDTO as J,toNodeSummaryDTO as Vn,toReviveResultDTO as zn}from"../map.js";import{ApiError as m}from"../../../api/index.js";import{InputError as w}from"../../../core/io.js";import{brokerMayReach as U,canReadNode as pe,resolvedScopes as Jn}from"../router.js";import{fileRoot as Un}from"../../../core/spaces/file-root.js";import{activeGrant as Hn,terminalGrant as Yn}from"../../../core/grants/mirror.js";import{readConfig as Qn}from"../../../core/config.js";import{hasConfiguredProviderCredential as Xn,NO_PROVIDER_CREDENTIAL_MESSAGE as me}from"../../../core/runtime/provider-credential-gate.js";function y(e){const t=k(e);if(t===null)throw P(`unknown node: ${e}`,{received:e});return t}a(y,"requireMeta");function H(e){return{subscribesTo:ie(e),subscribers:Ge(e),children:De(e)}}a(H,"edgesFor");function g(e){const t=y(e);return J(t,H(e))}a(g,"detailOf");function Zn(e){let t=ce(e).length;try{t+=nn(K(e),de(e)).length}catch(n){if(!qe(n))throw n}return t}a(Zn,"countFiles");function qn(e){if(typeof e!="object"||e===null)throw h("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw h("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw h("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw h("creator must be a non-empty node id when provided");if(t.scopes!==void 0&&ue(t.scopes),t.isolated!==void 0&&typeof t.isolated!="boolean")throw new m(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw h("root_lifecycle must be 'resident' or 'terminal'");if(t.request_key!==void 0&&(typeof t.request_key!="string"||t.request_key.trim()===""||t.request_key.length>128))throw h("request_key must be a non-empty string of at most 128 characters when provided");return t}a(qn,"parseCreateBody");function et(e){if(e===void 0)return;const t=An(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new m(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}a(et,"parseDeadline");function nt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new m(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!Cn.test(e.action))throw new m(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>ae)throw new m(413,"payload_too_large",`serialized payload exceeds ${ae} bytes`)}return e}}a(nt,"parseOutcomeDelivery");function tt(e,t){const n=Nn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new m(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new m(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}a(tt,"resolveOutcomeDelivery");function ot(e,t,n){const r={kind:e.kind,cwd:n,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),t!==void 0&&(r.parent=t),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=T(e.pin_cwd??e.cwd??n)),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}a(ot,"buildRecipe");function rt(e,t,n){return!En()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0||e.isolated!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}a(rt,"warmRequestFor");import{resolveCreateKind as Qo}from"../../../core/runtime/launch-target.js";function he(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return kn(e.model,t,e.modelExact===!0)}a(he,"requestFromLaunch");function it(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(r=>!O(t,r));if(n.length===0)return e;throw new m(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}a(it,"withinCeiling");async function we(e,t,n){const r=(await gn(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await B(he(r),{cwd:e.cwd,profileId:e.profile_id??null},n)}a(we,"assertNodeModelChangeRegistered");function ye(e,t){const n=e.principal;if(n.class!=="broker"&&n.class!=="cron")return;const r=Un({app:n.app,resolved:Jn(n),launched:n.scopes},t,"read");if("root"in r)return;const o="missing"in r?r.missing:null;throw new m(403,"scope_missing",o?`the child's directory ${t} needs missing scope ${o}`:`no permission of this run names the child's directory ${t}`,void 0,void 0,o?{scope:o}:void 0)}a(ye,"assertCallerReaches");const Y=new Map;async function dt(e,t={},n={}){const r=it(qn(e.body),e.ceiling);if(e.principal.class==="broker"){const l=e.principal;if(r.prefer_warm===!0&&l.app!=="app:terminal"&&(r.prefer_warm=!1),r.parent!=null){const i=y(r.parent);if(i.grantee!==l.app)throw new m(403,"other_app_run","cannot create a child under another app's node");if(!U(l,r.parent,i.grantee??"app:terminal"))throw P(`unknown node: ${r.parent}`,{received:r.parent})}if(r.creator!==void 0&&r.creator!==l.node)throw new m(403,"other_app_run","cannot create for another node");if(r.fork_from!==void 0){let i=null;try{i=Ee(Te(r.fork_from))}catch{}if(i?.grantee!==l.app||!U(l,i.node_id,i.grantee))throw new m(403,"other_app_run","cannot fork another app's conversation")}r.creator=l.node}if(e.principal.class==="cron"){const l=e.principal;for(const c of["parent","creator","fork_from","node_id"])if(r[c]!=null)throw new m(403,"permission_error",`a cron cannot set ${c} on a node it starts`);r.prefer_warm=!1;const i=Qe({grantee:l.app,sub:l.sub,grant_id:l.grant,scopes:l.scopes});if(!i.allowed)throw new m(i.reason==="scope_missing"?403:401,i.reason==="scope_missing"?"scope_missing":"grant_revoked",i.message);if(r.scopes!==void 0){const c=r.scopes.find(p=>!O(i.effectiveScopes,p)||!O(l.scopes,p));if(c!==void 0)throw new m(403,"scope_missing",`scope ${c} is not held by this cron`,void 0,void 0,{scope:c})}else l.scopes!==null&&(r.scopes=[...l.scopes]);r.node_id=ee(),l.isolated&&(r.isolated=!0,r.cwd=K(r.node_id,l.app))}r.creator!==void 0&&Kn(y(r.creator),"crtr:act");const o=r.request_key?.trim();if(o===void 0||r.node_id!==void 0&&Ye(r.node_id)&&k(r.node_id)!==null&&Le(o)?.nodeId!==r.node_id)return E(e,r,t,n);const d=Y.get(o);if(d!==void 0)return d;const s=st(e,r,o,t,n);Y.set(o,s);try{return await s}finally{Y.delete(o)}}a(dt,"handleCreate");async function st(e,t,n,r,o){const d=oe(n);if(d.nodeId!==null&&k(d.nodeId)!==null){if(d.state!=="warm_claimed"){const s=k(d.nodeId);if(e.principal.class!=="person"&&!pe(e.principal,s.grantee??"app:terminal",d.nodeId))throw new m(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:g(d.nodeId)}}return E(e,t,r,o,d)}try{return await E(e,t,r,o,d)}catch(s){const l=oe(n);throw(l.nodeId===null||k(l.nodeId)===null)&&ne(n,l.nodeId),s}}a(st,"handleKeyedCreateRequest");async function E(e,t,n,r,o=void 0){const d=r.deadlineAt??et(t.deadline),s=nt(t.outcome_delivery),l=e.principal.class==="cron"?Xe({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:fe(e.principal.cron)?.created_by??null},t.node_id):null;l!==null&&(t.root=l.root===!0);const i=l?.parent??t.parent??void 0;if(i==null&&t.root!==!0)throw h("a node create requires a parent (or root: true for an independent root)");let c=null;if(t.output_schema!==void 0)try{c=JSON.parse(t.output_schema)}catch{throw h("output_schema must be a JSON schema string")}const{profileId:p,kind:u,cwd:f,launch:_}=await Ln(t,{validateKind:ke});ye(e,f),t.worktree!==void 0&&ye(e,T(t.pin_cwd??t.cwd??f));const S={...t,kind:u},I=s===void 0?void 0:tt(s,f);if(await B(he(_),{cwd:f,profileId:p},n.modelRegistry),!await Xn(p))throw new m(412,"no_provider_credential",me,{error:"no_provider_credential",message:me,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let L=null;{const $=o===void 0||o.nodeId===null||o.state==="warm_claimed"?rt(S,f,p):null,j=c===null&&r.beforeBrokerLaunch===void 0?void 0:v=>{c!==null&&$n(v,"terminal",c),r.beforeBrokerLaunch?.(v)};if(o?.state==="warm_claimed"&&o.nodeId!==null){const v=$===null?null:await Pn($,o.nodeId,j);if(v===null)throw ne(o.requestKey,o.nodeId),new m(503,"create_resume_failed",`could not resume warm claim ${o.nodeId}; retry the create`);return te(o.requestKey,v),{status:201,body:g(v)}}if($!==null){const v=await Tn($,{...d===void 0?{}:{deadlineAt:d},...I===void 0?{}:{outcomeDelivery:I},...o===void 0?{}:{requestKey:o.requestKey}},j);if(v!==null)return o!==void 0&&te(o.requestKey,v),le($),{status:201,body:g(v)};L=$}const M=o?.nodeId??t.node_id??(o===void 0?void 0:ee());o!==void 0&&o.nodeId===null&&Me(o.requestKey,M);const R=ot(M===void 0?S:{...S,node_id:M},i,f);l!==null&&(l.rootLifecycle!==void 0&&(R.rootLifecycle=l.rootLifecycle),l.scopes!==void 0&&S.scopes===void 0&&(R.scopes=l.scopes),l.run!==void 0&&(R.run=l.run),l.withinCreate!==void 0&&(R.withinCreate=l.withinCreate)),d!==void 0&&(R.deadlineAt=d),I!==void 0&&(R.outcomeDelivery=I),R.readiness=t.root===!0?"await":"launch";const Q=await Pe(R,j,()=>{L!==null&&le(L)});return o!==void 0&&je(o.requestKey,Q.node.node_id),{status:201,body:g(Q.node.node_id)}}}a(E,"handleCreateRequest");function b(e,t){const n=e.query.getAll(t);if(n.length>1)throw h(`${t} must appear at most once`);return n[0]}a(b,"singleQueryValue");function _e(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw h(`${t} must be true or false`)}}a(_e,"optionalBoolean");function D(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw h(`${t} must be one of: ${n.join(", ")}`)}}a(D,"oneOf");function at(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[_]of e.query)if(!t.has(_))throw h(`unknown nodes query parameter: ${_}`);const n=D(b(e,"status"),"status",["active","idle","done","dead","canceled"]),r=D(b(e,"lifecycle"),"lifecycle",["terminal","resident"]),o=b(e,"kind"),d=D(b(e,"mode"),"mode",["base","orchestrator"]),s=b(e,"profile_id"),l=b(e,"profile_prefix"),i=b(e,"parent"),c=_e(b(e,"top_level"),"top_level"),p=b(e,"under"),u=_e(b(e,"hanging"),"hanging"),f=D(b(e,"include"),"include",["activity"]);if(i!==void 0&&c===!0)throw h("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...r!==void 0?{lifecycle:r}:{},...o!==void 0?{kind:o}:{},...d!==void 0?{mode:d}:{},...s!==void 0?{profile_id:s}:{},...l!==void 0?{profile_prefix:l}:{},...i!==void 0?{parent:i}:{},...c!==void 0?{top_level:c}:{},...p!==void 0?{under:p}:{},...u!==void 0?{hanging:u}:{},...f!==void 0?{include:f}:{}}}a(at,"parseListQuery");function lt(e){const t=at(e);let n=t.status!==void 0?re({status:t.status}):re();if(e.principal.class!=="person"&&(n=n.filter(s=>pe(e.principal,s.grantee??"app:terminal",s.node_id))),t.lifecycle!==void 0&&(n=n.filter(s=>s.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(s=>s.kind===t.kind)),t.mode!==void 0&&(n=n.filter(s=>s.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(s=>s.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(s=>s.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(s=>s.parent===t.parent)),t.top_level===!0&&(n=n.filter(s=>s.parent===null)),t.under!==void 0){const s=new Set(xe(t.under));n=n.filter(l=>s.has(l.node_id))}t.hanging===!0&&(n=n.filter(s=>s.parent!==null&&k(s.parent)===null));const r=t.include==="activity"?He(n.map(s=>s.node_id)):null,o=n.length>0?Oe():new Set;return{status:200,body:n.map(s=>{const l=Vn(s,s.profile_id!==null&&o.has(s.profile_id));if(r!==null){const i=ce(s.node_id);l.activity={latest_report:i[0]??null,final_report:s.final_report===null?null:i.find(c=>c.name===s.final_report)??null,pending_human_count:r[s.node_id]??0}}return l})}}a(lt,"handleList");function ct(e){const t=e.params.id;return y(t),{status:200,body:g(t)}}a(ct,"handleDetail");async function ft(e){const t=e.params.id;y(t);const n=await rn(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.turnReplies===void 0?{}:{turnReplies:n.snapshot.turnReplies},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(o=>({name:o.name,description:o.description,source:o.source})),captured_at:G()}}}a(ft,"handleSnapshot");async function ut(e){const t=e.params.id,n=sn(t);if(n===null)throw P(`unknown node: ${t}`,{received:t});return{status:200,body:n}}a(ut,"handleSubject");function pt(e){for(const[d]of e.query)if(d!=="cursor"&&d!=="limit")throw h(`unknown messages query parameter: ${d}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw h("cursor must appear at most once");if(n.length>1)throw h("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const r=n[0],o=Number(r);if(!Number.isSafeInteger(o)||r==="")throw h("limit must be an integer from 1 through 500");return t.length===0?{limit:o}:{cursor:t[0],limit:o}}a(pt,"parseMessagesQuery");async function mt(e){const t=e.params.id,n=await tn(t,pt(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:G()}}}a(mt,"handleMessages");function ht(e){const t=e.params.id;y(t);const n=on(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:G()}}}a(ht,"handleSession");async function wt(e){const t=e.params.id;return y(t),{status:200,body:{node_id:t,markdown:await dn(t)}}}a(wt,"handleTranscript");function yt(e){const t=e.params.id;y(t);const n=a((o,d)=>({node_id:o,label:k(o)?.name??o,dir:de(o),self:d,files:Zn(o)}),"root"),r=[n(t,!0),...ie(t).map(o=>n(o.node_id,!1))].filter(o=>_t(o.node_id,o.dir)||o.files>0);return{status:200,body:{node_id:t,roots:r}}}a(yt,"handleContext");function _t(e,t){try{return Ze(K(e),t)}catch(n){if(en(n))return!1;throw n}}a(_t,"hasDir");async function gt(e){const t=y(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(d=>O(n,d)),...n.filter(d=>O(t.scopes,d))])],o=await Ae(t.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:g(o.node.node_id)}}a(gt,"handleFork");async function bt(e){const t=e.params.id;y(t);const n=e.body,r=n?.resume??!0,o=n?.reopen??!1;pn(t,o);const d=!r&&n?.cron_id!==void 0?fe(n.cron_id):null,s=await Ne(t,{resume:r,capacity:"refuse",...d!==null?{wakeReason:Bn(d,"schedule_revive")}:{}});s.outcome!=="already-live"&&Fe(t,{failures:0,notBefore:null});const l=k(t)?.status??"active";return{status:200,body:zn(t,s,l)}}a(bt,"handleRevive");async function vt(e){const t=e.params.id;return{status:200,body:{newNodeId:(await un(t))?.newNodeId??null}}}a(vt,"handleRelaunchRoot");function kt(e){const t=e.params.id;y(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw h("caller_pid must be a positive integer when provided");const r=xn(),o=Ce(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:Wn(o)}}a(kt,"handleClose");async function St(e){const t=e.params.id;y(t);const n=await fn(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}a(St,"handleRecycle");async function Rt(e){const t=e.params.id;return y(t),await W(t,{lifecycle:"terminal"}),C(e,t,["lifecycle"]),{status:200,body:g(t)}}a(Rt,"handleDemote");async function Ot(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:"orchestrator",lifecycle:o.resident===!0?"resident":r.lifecycle,model:o.model},t.modelRegistry);const d=await ln(n,{...o.kind!==void 0?{kind:o.kind}:{},...o.resident===!0?{resident:!0}:{},...o.model!==void 0?{model:o.model}:{}});C(e,n,["mode",...o.kind!==void 0?["kind"]:[],...o.resident===!0?["lifecycle"]:[],...o.model!==void 0?["model"]:[]]);const s=J(d.meta,H(n));return s.roadmap_written=d.roadmapWritten,s.roadmap_ref=d.roadmapRef,s.goal_path=d.goalPath,{status:200,body:s}}a(Ot,"handlePromote");async function It(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:o.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:o.model},t.modelRegistry);const d=o.note??"Refresh: continue against your roadmap or goal.";mn(n,d);const s=await cn(n,{...o.promote===!0?{promote:!0}:{},...o.kind!==void 0?{kind:o.kind}:{},...o.model!==void 0?{model:o.model}:{}});return{status:200,body:J(s.meta,H(n))}}a(It,"handleYield");function $t(e){const t=e.params.id;y(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw h("a wait requires a controller node id");const r=k(n.controller);if(r===null)throw P(`unknown controller: ${n.controller}`,{received:n.controller});if(r.status!=="active"&&r.status!=="idle")throw new m(422,"unprocessable",`controller ${n.controller} is ${r.status}`);return Be(t,n.controller),{status:200,body:g(t)}}a($t,"handleWait");async function Ct(e){const t=e.principal,n=await an(t.class==="broker"?o=>o.grantee===t.app&&U(t,o.node_id,o.grantee):void 0);return{status:200,body:{revived:[...n.revived],failed:[...n.failed],frozen:[...n.frozen]}}}a(Ct,"handleReviveAll");const Nt=new Set(["interrupt","steer","after-turn","next-turn"]);function At(e){if(e===null)return null;const t=a(r=>{throw new w({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 t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[r,o]of n)/^(?:[1-9]|10)$/.test(r)||t(`listen level must be 1..10: ${r}`),(typeof o!="string"||!Nt.has(o))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(o)}`);return JSON.stringify(Object.fromEntries(n))}a(At,"listenJson");function C(e,t,n,r){n.length===0&&r===void 0||x(o=>{if(r?.(o),n.length===0)return;const d=Ke(o,t),s=ze(o,e),l=s.class==="person"?s.person:s.class==="app"?s.app:s.node;We(o,l,d),Ve(o,{event:"configured",object:d,actor:l,attrs:{changed:n.join(",")}})})}a(C,"recordConfigured");function ge(e){const t=V().get(e);if(t===void 0)return!1;try{return process.kill(t.pid,"SIGTERM"),!0}catch{return!1}}a(ge,"restartLiveBroker");function be(e,t){try{return Z(e)===Z(t)}catch{return!1}}a(be,"sameDirectory");async function Tt(e,t={}){const n=e.params.id,r=e.body;let o;if(r===void 0)o={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))o=r;else throw new w({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(o.profile!==void 0){if(typeof o.profile!="string"||o.profile==="")throw new w({error:"profile_invalid",message:"profile must be a non-empty profile id or name",received:o.profile,field:"profile",next:"Send a profile id or exact name."});if(Object.keys(o).some(u=>u!=="profile"&&u!=="restart"&&o[u]!==void 0))throw new w({error:"profile_not_exclusive",message:"profile can only be combined with restart",field:"profile",next:"Send profile (and optionally restart) alone."});const i=y(n),c=Mn(e,o.profile);Fn(c.profileId);const p=Gn(c.profileId).manifest.grantee??"app:terminal";if(p!==(i.grantee??"app:terminal"))throw new w({error:"profile_grantee_mismatch",message:`profile ${c.profileId} belongs to ${p}, node ${n} to ${i.grantee}`,received:o.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(i.profile_id??null)!==c.profileId&&(Dn(i.kind)?(await z(i.kind,i.cwd,c.profileId),await W(n,{profileId:c.profileId})):N(n,{profile_id:c.profileId}),C(e,n,["profile"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(Object.prototype.hasOwnProperty.call(o,"cwd")){const i=o.cwd;if(typeof i!="string"||i==="")throw new w({error:"cwd_invalid",message:"cwd must be a non-empty string",received:i,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(o).some(f=>f!=="cwd"&&f!=="keep_session"&&f!=="restart"&&o[f]!==void 0))throw new w({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:o,field:"cwd",next:"Send cwd as the only config field."});const c=y(n),p=A(c.cwd);if(o.keep_session===!0||p&&F(i)&&A(i)&&be(c.cwd,i)){if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const f=T(i);let _=!1;try{_=q(f).isDirectory()}catch{}if(!_)throw new w({error:"cwd_missing",message:`cwd is not an existing directory: ${f}`,received:i,field:"cwd",next:"Send an existing absolute directory."});if(p&&!be(c.cwd,f))throw new w({error:"cwd_not_same_directory",message:`${f} is not the same directory as the recorded ${c.cwd}; --keep-session only relocates an alias`,received:i,field:"cwd",next:"Drop --keep-session to repair a gone cwd, or pass the real path of the recorded directory."});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot relocate its cwd`,received:i,field:"cwd",next:"Reconcile the managed worktree first."});const S=c.cwd;return S!==f&&(x(I=>{N(n,{cwd:f}),X(I,"UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(f,n,S),Je(n,S,f)}),C(e,n,["cwd"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(V().has(n)){const f=`${n} cannot repair its cwd while its broker is live`;throw new m(409,"cwd_node_live",f,{error:"cwd_node_live",message:f,received:i,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(c.fork_from!=null)throw new w({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${c.cwd}`,received:i,field:"cwd",next:`Restore ${c.cwd}, then revive the fork normally.`});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:i,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(A(c.cwd))throw new w({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${c.cwd}; cwd repair is not a relocation command`,received:i,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const u=T(i);if(!A(u))throw new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!q(u).isDirectory())throw new w({error:"cwd_not_a_directory",message:`cwd is not a directory: ${u}`,received:i,field:"cwd",next:"Send an existing absolute directory."})}catch(f){throw f instanceof w?f:new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return x(()=>{N(n,{cwd:u}),Ue(n)}),C(e,n,["cwd"]),{status:200,body:g(n)}}let d=y(n);const s=o.listen===void 0?void 0:At(o.listen);if(o.scopes!==void 0){const i=ue(o.scopes),c=d.grantee==="app:terminal"?Yn():d.grant_id?Hn(d.grant_id):null,p=d.grantee==="app:terminal"&&!Qn("user").runtime?.issuer;if(!i.every(u=>O(d.scopes,u)&&(c?O(c.resolved,u):p)))throw new w({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:i,field:"scopes",next:"Send only scopes the node currently holds."});if(i.includes("crtr:act")&&!O(i,"crtr:llm"))throw new m(400,"invalid_scope","crtr:act requires crtr:llm");d=N(n,{scopes:i})}if(o.situational_context!==void 0&&Ie(n,$e(o.situational_context)),o.model!==void 0){const i=(await se(d.cwd,d.profile_id??null)).modelLadders,c=bn(o.model,i),p=vn(o.model,i);await B({kind:"concrete",spec:p},{cwd:d.cwd,profileId:d.profile_id??null},t.modelRegistry);const u=V();let f=!1;if(u.isClaimed(n)&&await On(n,u.get(n)?.handle.exited)&&(f=await Rn(n,p,c).then(()=>!0,_=>{if(_ instanceof In)return!1;throw _})),!f){if(u.isClaimed(n)){const _=`${n}'s broker did not accept the model switch; the model was not changed`;throw new m(409,"broker_not_ready",_,{error:"broker_not_ready",message:_,received:o.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!p.includes("/"))throw h(`model must resolve to a provider/id spec: ${o.model}`);Sn(n,p,c)}d=y(n)}if(o.kind!==void 0||o.mode!==void 0||o.lifecycle!==void 0){o.kind!==void 0&&await ke(o.kind);const i=o.kind??d.kind,c=o.mode??d.mode,p=o.lifecycle??d.lifecycle;let u;c==="orchestrator"&&!yn(n)&&(u=a(()=>{const f=hn(n);wn(n,f!==null&&f.trim()!==""?{goal:f.trim()}:{})},"beforePersist")),d=await W(n,{...o.kind!==void 0?{kind:i}:{},...o.mode!==void 0?{mode:c}:{},...o.lifecycle!==void 0?{lifecycle:p}:{}},u)}o.name!==void 0&&(d=N(n,{name:o.name}),d.window&&_n(d.window,jn(d)));const l=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(i=>o[i]!==void 0);return C(e,n,l,s===void 0?void 0:i=>{X(i,"UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(s,n)}),{status:200,body:g(n)}}a(Tt,"handleConfig");async function ve(){return(await se(process.cwd(),Re()||null)).kinds}a(ve,"daemonKinds");async function ke(e){const t=Object.keys(await ve());if(!t.includes(e))throw h(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}a(ke,"assertKindServer");async function Pt(){const e=await ve();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}a(Pt,"handleListKinds");const Uo=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:dt},{method:"GET",pattern:"/v1/nodes",handler:lt},{method:"GET",pattern:"/v1/kinds",handler:a(()=>Pt(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:Ct},{method:"GET",pattern:"/v1/nodes/:id",handler:ct},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:ft},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:ut},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:mt},{method:"GET",pattern:"/v1/nodes/:id/session",handler:ht},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:wt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:yt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:gt},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:bt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:vt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:kt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:St},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Rt},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Ot},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:It},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:$t},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Tt}];export{Tt as handleConfig,dt as handleCreate,gt as handleFork,lt as handleList,Ot as handlePromote,It as handleYield,Uo as nodeRoutes,Qo as resolveCreateKind};
|
|
1
|
+
var Se=Object.defineProperty;var a=(e,t)=>Se(e,"name",{value:t,configurable:!0});import{prepared as X}from"../../../core/sqlite-statements.js";import{envProfileId as Re}from"../../../shared/env.js";import{pausedCanvasProfiles as Oe}from"../../../core/profiles/manifest.js";import{existsSync as A,realpathSync as Z,statSync as q}from"node:fs";import{isAbsolute as F,resolve as T}from"node:path";import{appendSituationalContext as Ie,formatSituationalProse as $e}from"../../../core/runtime/situational-context.js";import{closeNode as Ce}from"../../../core/runtime/close.js";import{reviveNode as Ne}from"../../../core/runtime/revive.js";import{nowIso as G}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as B,forkNode as Ae,resolveForkSource as Te,spawnChildPrepared as Ee}from"../../../core/runtime/spawn.js";import{forkSourceNode as Pe,newNodeId as ee}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as ne,childrenOf as De,completeCreateRequest as te,findCreateRequest as Le,getNode as k,recordCreateRequestNode as Me,reserveCreateRequest as oe,reserveCreateRequestNode as je,listNodes as re,recordRespawnAttempt as Fe,subscribersOf as Ge,subscriptionsOf as ie,setMessageWait as Be,updateNode as N}from"../../../core/canvas/canvas.js";import{subtreeIds as Ke}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as K}from"../../../core/canvas/db.js";import{nodeObject as xe}from"../../../core/graph/objects.js";import{recordActedOn as We}from"../../../core/graph/edges.js";import{publish as Ve}from"../../../core/graph/events.js";import{readerFor as ze}from"../reader.js";import{relocateSessionCwd as Je,unbindSession as Ue}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as He}from"../../../core/canvas/attention.js";import{isSafeNodeId as Ye}from"../../../core/canvas/paths.js";import{contextDir as de,nodeAgentDir as x}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as Qe}from"../../cron/authority.js";import{cronBirthPlacement as Xe}from"../../cron/armed-context.js";import{existsBeneath as Ze,isAbsentOrRefused as qe,isBeneathRefusal as en,readdirBeneath as nn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as tn,readNodeSession as on,readNodeSnapshot as rn,transcriptMarkdown as dn}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as sn}from"../../../core/substrate/subject.js";import{reviveAll as an}from"../../../core/runtime/revive-all.js";import{promoteAsync as ln,requestYieldAsync as cn,reshapeNodeAsync as W}from"../../../core/runtime/promote.js";import{recycleNode as fn}from"../../../core/runtime/recycle.js";import{relaunchRoot as un}from"../../../core/runtime/reset.js";import{assertReopenGate as pn}from"../../../core/runtime/reopen.js";import{writeYieldMessage as mn,readGoal as hn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as wn,hasRoadmap as yn}from"../../../core/runtime/roadmap.js";import{renameWindow as _n}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as gn,explicitModelIntent as bn,normalizeModel as vn,readMergedLaunchConfigAsync as se}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as kn}from"../../../core/model-routes.js";import{persistDormantModel as Sn,setModelLive as Rn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as On}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as In}from"../../../core/runtime/broker-request.js";import{boundFleet as V}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as $n}from"../../structured-requests/sidecar.js";import{OUTCOME_PAYLOAD_MAX_BYTES as ae}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as Cn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Nn}from"../../../core/human-actions.js";import{parseDurationMs as An}from"../../../core/wake.js";import{claimWarmNode as Tn,refillWarmPool as le,resumeWarmClaim as En,warmPoolEnabled as Pn}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as z,isLaunchKind as Dn,resolveLaunchTarget as Ln}from"../../../core/runtime/launch-target.js";import{fullName as Mn}from"../../../core/canvas/labels.js";import{reportsForNode as ce}from"./reports.js";import{requireUsableProfile as jn}from"./profiles.js";import{assertProfileActive as Fn,loadExactProfileManifest as Gn}from"../../../core/profiles/manifest.js";import{getCron as fe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Bn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as Kn}from"../../control.js";import{notFound as E,usage as h}from"../../../core/errors.js";import{assertScope as xn,validateScopes as ue}from"../../../core/scopes.js";import{scopeAllowed as O}from"../../../shared/env.js";import{toCloseResultDTO as Wn,toNodeDetailDTO as J,toNodeSummaryDTO as Vn,toReviveResultDTO as zn}from"../map.js";import{ApiError as m}from"../../../api/index.js";import{InputError as w}from"../../../core/io.js";import{brokerMayReach as U,canReadNode as pe,resolvedScopes as Jn}from"../router.js";import{forwardVerb as Un,queryWithoutMachine as Hn,relayError as Yn,unknownError as Qn,withMachine as Xn}from"../../peer/forward.js";import{fileRoot as Zn}from"../../../core/spaces/file-root.js";import{activeGrant as qn,terminalGrant as et}from"../../../core/grants/mirror.js";import{readConfig as nt}from"../../../core/config.js";import{hasConfiguredProviderCredential as tt,NO_PROVIDER_CREDENTIAL_MESSAGE as me}from"../../../core/runtime/provider-credential-gate.js";function y(e){const t=k(e);if(t===null)throw E(`unknown node: ${e}`,{received:e});return t}a(y,"requireMeta");function H(e){return{subscribesTo:ie(e),subscribers:Ge(e),children:De(e)}}a(H,"edgesFor");function g(e){const t=y(e);return J(t,H(e))}a(g,"detailOf");function ot(e){let t=ce(e).length;try{t+=nn(x(e),de(e)).length}catch(n){if(!qe(n))throw n}return t}a(ot,"countFiles");function rt(e){if(typeof e!="object"||e===null)throw h("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw h("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw h("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw h("creator must be a non-empty node id when provided");if(t.scopes!==void 0&&ue(t.scopes),t.isolated!==void 0&&typeof t.isolated!="boolean")throw new m(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw h("root_lifecycle must be 'resident' or 'terminal'");if(t.request_key!==void 0&&(typeof t.request_key!="string"||t.request_key.trim()===""||t.request_key.length>128))throw h("request_key must be a non-empty string of at most 128 characters when provided");return t}a(rt,"parseCreateBody");function it(e){if(e===void 0)return;const t=An(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new m(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}a(it,"parseDeadline");function dt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new m(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!Cn.test(e.action))throw new m(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>ae)throw new m(413,"payload_too_large",`serialized payload exceeds ${ae} bytes`)}return e}}a(dt,"parseOutcomeDelivery");function st(e,t){const n=Nn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new m(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new m(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}a(st,"resolveOutcomeDelivery");function at(e,t,n){const r={kind:e.kind,cwd:n,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),t!==void 0&&(r.parent=t),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=T(e.pin_cwd??e.cwd??n)),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}a(at,"buildRecipe");function lt(e,t,n){return!Pn()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0||e.isolated!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}a(lt,"warmRequestFor");import{resolveCreateKind as tr}from"../../../core/runtime/launch-target.js";function he(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return kn(e.model,t,e.modelExact===!0)}a(he,"requestFromLaunch");function ct(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(r=>!O(t,r));if(n.length===0)return e;throw new m(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}a(ct,"withinCeiling");async function we(e,t,n){const r=(await gn(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await B(he(r),{cwd:e.cwd,profileId:e.profile_id??null},n)}a(we,"assertNodeModelChangeRegistered");function ye(e,t){const n=e.principal;if(n.class!=="broker"&&n.class!=="cron")return;const r=Zn({app:n.app,resolved:Jn(n),launched:n.scopes},t,"read");if("root"in r)return;const o="missing"in r?r.missing:null;throw new m(403,"scope_missing",o?`the child's directory ${t} needs missing scope ${o}`:`no permission of this run names the child's directory ${t}`,void 0,void 0,o?{scope:o}:void 0)}a(ye,"assertCallerReaches");const Y=new Map;async function ft(e,t={},n={}){const r=ct(rt(e.body),e.ceiling);if(e.principal.class==="broker"){const l=e.principal;if(r.prefer_warm===!0&&l.app!=="app:terminal"&&(r.prefer_warm=!1),r.parent!=null){const i=y(r.parent);if(i.grantee!==l.app)throw new m(403,"other_app_run","cannot create a child under another app's node");if(!U(l,r.parent,i.grantee??"app:terminal"))throw E(`unknown node: ${r.parent}`,{received:r.parent})}if(r.creator!==void 0&&r.creator!==l.node)throw new m(403,"other_app_run","cannot create for another node");if(r.fork_from!==void 0){let i=null;try{i=Pe(Te(r.fork_from))}catch{}if(i?.grantee!==l.app||!U(l,i.node_id,i.grantee))throw new m(403,"other_app_run","cannot fork another app's conversation")}r.creator=l.node}if(e.principal.class==="cron"){const l=e.principal;for(const c of["parent","creator","fork_from","node_id"])if(r[c]!=null)throw new m(403,"permission_error",`a cron cannot set ${c} on a node it starts`);r.prefer_warm=!1;const i=Qe({grantee:l.app,sub:l.sub,grant_id:l.grant,scopes:l.scopes});if(!i.allowed)throw new m(i.reason==="scope_missing"?403:401,i.reason==="scope_missing"?"scope_missing":"grant_revoked",i.message);if(r.scopes!==void 0){const c=r.scopes.find(p=>!O(i.effectiveScopes,p)||!O(l.scopes,p));if(c!==void 0)throw new m(403,"scope_missing",`scope ${c} is not held by this cron`,void 0,void 0,{scope:c})}else l.scopes!==null&&(r.scopes=[...l.scopes]);r.node_id=ee(),l.isolated&&(r.isolated=!0,r.cwd=x(r.node_id,l.app))}r.creator!==void 0&&xn(y(r.creator),"crtr:act");const o=r.request_key?.trim();if(o===void 0||r.node_id!==void 0&&Ye(r.node_id)&&k(r.node_id)!==null&&Le(o)?.nodeId!==r.node_id)return P(e,r,t,n);const d=Y.get(o);if(d!==void 0)return d;const s=ut(e,r,o,t,n);Y.set(o,s);try{return await s}finally{Y.delete(o)}}a(ft,"handleCreate");async function ut(e,t,n,r,o){const d=oe(n);if(d.nodeId!==null&&k(d.nodeId)!==null){if(d.state!=="warm_claimed"){const s=k(d.nodeId);if(e.principal.class!=="person"&&!pe(e.principal,s.grantee??"app:terminal",d.nodeId))throw new m(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:g(d.nodeId)}}return P(e,t,r,o,d)}try{return await P(e,t,r,o,d)}catch(s){const l=oe(n);throw(l.nodeId===null||k(l.nodeId)===null)&&ne(n,l.nodeId),s}}a(ut,"handleKeyedCreateRequest");async function P(e,t,n,r,o=void 0){const d=r.deadlineAt??it(t.deadline),s=dt(t.outcome_delivery),l=e.principal.class==="cron"?Xe({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:fe(e.principal.cron)?.created_by??null},t.node_id):null;l!==null&&(t.root=l.root===!0);const i=l?.parent??t.parent??void 0;if(i==null&&t.root!==!0)throw h("a node create requires a parent (or root: true for an independent root)");let c=null;if(t.output_schema!==void 0)try{c=JSON.parse(t.output_schema)}catch{throw h("output_schema must be a JSON schema string")}const{profileId:p,kind:u,cwd:f,launch:_}=await Ln(t,{validateKind:ke});ye(e,f),t.worktree!==void 0&&ye(e,T(t.pin_cwd??t.cwd??f));const S={...t,kind:u},I=s===void 0?void 0:st(s,f);if(await B(he(_),{cwd:f,profileId:p},n.modelRegistry),!await tt(p))throw new m(412,"no_provider_credential",me,{error:"no_provider_credential",message:me,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let L=null;{const $=o===void 0||o.nodeId===null||o.state==="warm_claimed"?lt(S,f,p):null,M=c===null&&r.beforeBrokerLaunch===void 0?void 0:v=>{c!==null&&$n(v,"terminal",c),r.beforeBrokerLaunch?.(v)};if(o?.state==="warm_claimed"&&o.nodeId!==null){const v=$===null?null:await En($,o.nodeId,M);if(v===null)throw ne(o.requestKey,o.nodeId),new m(503,"create_resume_failed",`could not resume warm claim ${o.nodeId}; retry the create`);return te(o.requestKey,v),{status:201,body:g(v)}}if($!==null){const v=await Tn($,{...d===void 0?{}:{deadlineAt:d},...I===void 0?{}:{outcomeDelivery:I},...o===void 0?{}:{requestKey:o.requestKey}},M);if(v!==null)return o!==void 0&&te(o.requestKey,v),le($),{status:201,body:g(v)};L=$}const j=o?.nodeId??t.node_id??(o===void 0?void 0:ee());o!==void 0&&o.nodeId===null&&je(o.requestKey,j);const R=at(j===void 0?S:{...S,node_id:j},i,f);l!==null&&(l.rootLifecycle!==void 0&&(R.rootLifecycle=l.rootLifecycle),l.scopes!==void 0&&S.scopes===void 0&&(R.scopes=l.scopes),l.run!==void 0&&(R.run=l.run),l.withinCreate!==void 0&&(R.withinCreate=l.withinCreate)),d!==void 0&&(R.deadlineAt=d),I!==void 0&&(R.outcomeDelivery=I),R.readiness=t.root===!0?"await":"launch";const Q=await Ee(R,M,()=>{L!==null&&le(L)});return o!==void 0&&Me(o.requestKey,Q.node.node_id),{status:201,body:g(Q.node.node_id)}}}a(P,"handleCreateRequest");function b(e,t){const n=e.query.getAll(t);if(n.length>1)throw h(`${t} must appear at most once`);return n[0]}a(b,"singleQueryValue");function _e(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw h(`${t} must be true or false`)}}a(_e,"optionalBoolean");function D(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw h(`${t} must be one of: ${n.join(", ")}`)}}a(D,"oneOf");function pt(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[_]of e.query)if(!t.has(_))throw h(`unknown nodes query parameter: ${_}`);const n=D(b(e,"status"),"status",["active","idle","done","dead","canceled"]),r=D(b(e,"lifecycle"),"lifecycle",["terminal","resident"]),o=b(e,"kind"),d=D(b(e,"mode"),"mode",["base","orchestrator"]),s=b(e,"profile_id"),l=b(e,"profile_prefix"),i=b(e,"parent"),c=_e(b(e,"top_level"),"top_level"),p=b(e,"under"),u=_e(b(e,"hanging"),"hanging"),f=D(b(e,"include"),"include",["activity"]);if(i!==void 0&&c===!0)throw h("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...r!==void 0?{lifecycle:r}:{},...o!==void 0?{kind:o}:{},...d!==void 0?{mode:d}:{},...s!==void 0?{profile_id:s}:{},...l!==void 0?{profile_prefix:l}:{},...i!==void 0?{parent:i}:{},...c!==void 0?{top_level:c}:{},...p!==void 0?{under:p}:{},...u!==void 0?{hanging:u}:{},...f!==void 0?{include:f}:{}}}a(pt,"parseListQuery");function mt(e){const t=pt(e);let n=t.status!==void 0?re({status:t.status}):re();if(e.principal.class!=="person"&&(n=n.filter(s=>pe(e.principal,s.grantee??"app:terminal",s.node_id))),t.lifecycle!==void 0&&(n=n.filter(s=>s.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(s=>s.kind===t.kind)),t.mode!==void 0&&(n=n.filter(s=>s.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(s=>s.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(s=>s.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(s=>s.parent===t.parent)),t.top_level===!0&&(n=n.filter(s=>s.parent===null)),t.under!==void 0){const s=new Set(Ke(t.under));n=n.filter(l=>s.has(l.node_id))}t.hanging===!0&&(n=n.filter(s=>s.parent!==null&&k(s.parent)===null));const r=t.include==="activity"?He(n.map(s=>s.node_id)):null,o=n.length>0?Oe():new Set;return{status:200,body:n.map(s=>{const l=Vn(s,s.profile_id!==null&&o.has(s.profile_id));if(r!==null){const i=ce(s.node_id);l.activity={latest_report:i[0]??null,final_report:s.final_report===null?null:i.find(c=>c.name===s.final_report)??null,pending_human_count:r[s.node_id]??0}}return l})}}a(mt,"handleList");async function ht(e){const t=e.params.id,n=await Un(e,t,{method:"GET",path:`/v1/nodes/${encodeURIComponent(t)}`,query:Hn(e)});if(n.kind==="unknown")throw Qn(t,n.unreachable);if(n.kind==="remote"){if(n.status>=400)throw Yn(n.status,n.body);return{status:n.status,body:Xn(n.body,n.machine)}}return y(t),{status:200,body:g(t)}}a(ht,"handleDetail");async function wt(e){const t=e.params.id;y(t);const n=await rn(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.turnReplies===void 0?{}:{turnReplies:n.snapshot.turnReplies},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(o=>({name:o.name,description:o.description,source:o.source})),captured_at:G()}}}a(wt,"handleSnapshot");async function yt(e){const t=e.params.id,n=sn(t);if(n===null)throw E(`unknown node: ${t}`,{received:t});return{status:200,body:n}}a(yt,"handleSubject");function _t(e){for(const[d]of e.query)if(d!=="cursor"&&d!=="limit")throw h(`unknown messages query parameter: ${d}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw h("cursor must appear at most once");if(n.length>1)throw h("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const r=n[0],o=Number(r);if(!Number.isSafeInteger(o)||r==="")throw h("limit must be an integer from 1 through 500");return t.length===0?{limit:o}:{cursor:t[0],limit:o}}a(_t,"parseMessagesQuery");async function gt(e){const t=e.params.id,n=await tn(t,_t(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:G()}}}a(gt,"handleMessages");function bt(e){const t=e.params.id;y(t);const n=on(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:G()}}}a(bt,"handleSession");async function vt(e){const t=e.params.id;return y(t),{status:200,body:{node_id:t,markdown:await dn(t)}}}a(vt,"handleTranscript");function kt(e){const t=e.params.id;y(t);const n=a((o,d)=>({node_id:o,label:k(o)?.name??o,dir:de(o),self:d,files:ot(o)}),"root"),r=[n(t,!0),...ie(t).map(o=>n(o.node_id,!1))].filter(o=>St(o.node_id,o.dir)||o.files>0);return{status:200,body:{node_id:t,roots:r}}}a(kt,"handleContext");function St(e,t){try{return Ze(x(e),t)}catch(n){if(en(n))return!1;throw n}}a(St,"hasDir");async function Rt(e){const t=y(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(d=>O(n,d)),...n.filter(d=>O(t.scopes,d))])],o=await Ae(t.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:g(o.node.node_id)}}a(Rt,"handleFork");async function Ot(e){const t=e.params.id;y(t);const n=e.body,r=n?.resume??!0,o=n?.reopen??!1;pn(t,o);const d=!r&&n?.cron_id!==void 0?fe(n.cron_id):null,s=await Ne(t,{resume:r,capacity:"refuse",...d!==null?{wakeReason:Bn(d,"schedule_revive")}:{}});s.outcome!=="already-live"&&Fe(t,{failures:0,notBefore:null});const l=k(t)?.status??"active";return{status:200,body:zn(t,s,l)}}a(Ot,"handleRevive");async function It(e){const t=e.params.id;return{status:200,body:{newNodeId:(await un(t))?.newNodeId??null}}}a(It,"handleRelaunchRoot");function $t(e){const t=e.params.id;y(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw h("caller_pid must be a positive integer when provided");const r=Kn(),o=Ce(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:Wn(o)}}a($t,"handleClose");async function Ct(e){const t=e.params.id;y(t);const n=await fn(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}a(Ct,"handleRecycle");async function Nt(e){const t=e.params.id;return y(t),await W(t,{lifecycle:"terminal"}),C(e,t,["lifecycle"]),{status:200,body:g(t)}}a(Nt,"handleDemote");async function At(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:"orchestrator",lifecycle:o.resident===!0?"resident":r.lifecycle,model:o.model},t.modelRegistry);const d=await ln(n,{...o.kind!==void 0?{kind:o.kind}:{},...o.resident===!0?{resident:!0}:{},...o.model!==void 0?{model:o.model}:{}});C(e,n,["mode",...o.kind!==void 0?["kind"]:[],...o.resident===!0?["lifecycle"]:[],...o.model!==void 0?["model"]:[]]);const s=J(d.meta,H(n));return s.roadmap_written=d.roadmapWritten,s.roadmap_ref=d.roadmapRef,s.goal_path=d.goalPath,{status:200,body:s}}a(At,"handlePromote");async function Tt(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:o.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:o.model},t.modelRegistry);const d=o.note??"Refresh: continue against your roadmap or goal.";mn(n,d);const s=await cn(n,{...o.promote===!0?{promote:!0}:{},...o.kind!==void 0?{kind:o.kind}:{},...o.model!==void 0?{model:o.model}:{}});return{status:200,body:J(s.meta,H(n))}}a(Tt,"handleYield");function Et(e){const t=e.params.id;y(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw h("a wait requires a controller node id");const r=k(n.controller);if(r===null)throw E(`unknown controller: ${n.controller}`,{received:n.controller});if(r.status!=="active"&&r.status!=="idle")throw new m(422,"unprocessable",`controller ${n.controller} is ${r.status}`);return Be(t,n.controller),{status:200,body:g(t)}}a(Et,"handleWait");async function Pt(e){const t=e.principal,n=await an(t.class==="broker"?o=>o.grantee===t.app&&U(t,o.node_id,o.grantee):void 0);return{status:200,body:{revived:[...n.revived],failed:[...n.failed],frozen:[...n.frozen]}}}a(Pt,"handleReviveAll");const Dt=new Set(["interrupt","steer","after-turn","next-turn"]);function Lt(e){if(e===null)return null;const t=a(r=>{throw new w({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 t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[r,o]of n)/^(?:[1-9]|10)$/.test(r)||t(`listen level must be 1..10: ${r}`),(typeof o!="string"||!Dt.has(o))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(o)}`);return JSON.stringify(Object.fromEntries(n))}a(Lt,"listenJson");function C(e,t,n,r){n.length===0&&r===void 0||K(o=>{if(r?.(o),n.length===0)return;const d=xe(o,t),s=ze(o,e),l=s.class==="person"?s.person:s.class==="app"?s.app:s.node;We(o,l,d),Ve(o,{event:"configured",object:d,actor:l,attrs:{changed:n.join(",")}})})}a(C,"recordConfigured");function ge(e){const t=V().get(e);if(t===void 0)return!1;try{return process.kill(t.pid,"SIGTERM"),!0}catch{return!1}}a(ge,"restartLiveBroker");function be(e,t){try{return Z(e)===Z(t)}catch{return!1}}a(be,"sameDirectory");async function Mt(e,t={}){const n=e.params.id,r=e.body;let o;if(r===void 0)o={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))o=r;else throw new w({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(o.profile!==void 0){if(typeof o.profile!="string"||o.profile==="")throw new w({error:"profile_invalid",message:"profile must be a non-empty profile id or name",received:o.profile,field:"profile",next:"Send a profile id or exact name."});if(Object.keys(o).some(u=>u!=="profile"&&u!=="restart"&&o[u]!==void 0))throw new w({error:"profile_not_exclusive",message:"profile can only be combined with restart",field:"profile",next:"Send profile (and optionally restart) alone."});const i=y(n),c=jn(e,o.profile);Fn(c.profileId);const p=Gn(c.profileId).manifest.grantee??"app:terminal";if(p!==(i.grantee??"app:terminal"))throw new w({error:"profile_grantee_mismatch",message:`profile ${c.profileId} belongs to ${p}, node ${n} to ${i.grantee}`,received:o.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(i.profile_id??null)!==c.profileId&&(Dn(i.kind)?(await z(i.kind,i.cwd,c.profileId),await W(n,{profileId:c.profileId})):N(n,{profile_id:c.profileId}),C(e,n,["profile"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(Object.prototype.hasOwnProperty.call(o,"cwd")){const i=o.cwd;if(typeof i!="string"||i==="")throw new w({error:"cwd_invalid",message:"cwd must be a non-empty string",received:i,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(o).some(f=>f!=="cwd"&&f!=="keep_session"&&f!=="restart"&&o[f]!==void 0))throw new w({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:o,field:"cwd",next:"Send cwd as the only config field."});const c=y(n),p=A(c.cwd);if(o.keep_session===!0||p&&F(i)&&A(i)&&be(c.cwd,i)){if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const f=T(i);let _=!1;try{_=q(f).isDirectory()}catch{}if(!_)throw new w({error:"cwd_missing",message:`cwd is not an existing directory: ${f}`,received:i,field:"cwd",next:"Send an existing absolute directory."});if(p&&!be(c.cwd,f))throw new w({error:"cwd_not_same_directory",message:`${f} is not the same directory as the recorded ${c.cwd}; --keep-session only relocates an alias`,received:i,field:"cwd",next:"Drop --keep-session to repair a gone cwd, or pass the real path of the recorded directory."});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot relocate its cwd`,received:i,field:"cwd",next:"Reconcile the managed worktree first."});const S=c.cwd;return S!==f&&(K(I=>{N(n,{cwd:f}),X(I,"UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(f,n,S),Je(n,S,f)}),C(e,n,["cwd"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(V().has(n)){const f=`${n} cannot repair its cwd while its broker is live`;throw new m(409,"cwd_node_live",f,{error:"cwd_node_live",message:f,received:i,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(c.fork_from!=null)throw new w({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${c.cwd}`,received:i,field:"cwd",next:`Restore ${c.cwd}, then revive the fork normally.`});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:i,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(A(c.cwd))throw new w({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${c.cwd}; cwd repair is not a relocation command`,received:i,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const u=T(i);if(!A(u))throw new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!q(u).isDirectory())throw new w({error:"cwd_not_a_directory",message:`cwd is not a directory: ${u}`,received:i,field:"cwd",next:"Send an existing absolute directory."})}catch(f){throw f instanceof w?f:new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return K(()=>{N(n,{cwd:u}),Ue(n)}),C(e,n,["cwd"]),{status:200,body:g(n)}}let d=y(n);const s=o.listen===void 0?void 0:Lt(o.listen);if(o.scopes!==void 0){const i=ue(o.scopes),c=d.grantee==="app:terminal"?et():d.grant_id?qn(d.grant_id):null,p=d.grantee==="app:terminal"&&!nt("user").runtime?.issuer;if(!i.every(u=>O(d.scopes,u)&&(c?O(c.resolved,u):p)))throw new w({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:i,field:"scopes",next:"Send only scopes the node currently holds."});if(i.includes("crtr:act")&&!O(i,"crtr:llm"))throw new m(400,"invalid_scope","crtr:act requires crtr:llm");d=N(n,{scopes:i})}if(o.situational_context!==void 0&&Ie(n,$e(o.situational_context)),o.model!==void 0){const i=(await se(d.cwd,d.profile_id??null)).modelLadders,c=bn(o.model,i),p=vn(o.model,i);await B({kind:"concrete",spec:p},{cwd:d.cwd,profileId:d.profile_id??null},t.modelRegistry);const u=V();let f=!1;if(u.isClaimed(n)&&await On(n,u.get(n)?.handle.exited)&&(f=await Rn(n,p,c).then(()=>!0,_=>{if(_ instanceof In)return!1;throw _})),!f){if(u.isClaimed(n)){const _=`${n}'s broker did not accept the model switch; the model was not changed`;throw new m(409,"broker_not_ready",_,{error:"broker_not_ready",message:_,received:o.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!p.includes("/"))throw h(`model must resolve to a provider/id spec: ${o.model}`);Sn(n,p,c)}d=y(n)}if(o.kind!==void 0||o.mode!==void 0||o.lifecycle!==void 0){o.kind!==void 0&&await ke(o.kind);const i=o.kind??d.kind,c=o.mode??d.mode,p=o.lifecycle??d.lifecycle;let u;c==="orchestrator"&&!yn(n)&&(u=a(()=>{const f=hn(n);wn(n,f!==null&&f.trim()!==""?{goal:f.trim()}:{})},"beforePersist")),d=await W(n,{...o.kind!==void 0?{kind:i}:{},...o.mode!==void 0?{mode:c}:{},...o.lifecycle!==void 0?{lifecycle:p}:{}},u)}o.name!==void 0&&(d=N(n,{name:o.name}),d.window&&_n(d.window,Mn(d)));const l=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(i=>o[i]!==void 0);return C(e,n,l,s===void 0?void 0:i=>{X(i,"UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(s,n)}),{status:200,body:g(n)}}a(Mt,"handleConfig");async function ve(){return(await se(process.cwd(),Re()||null)).kinds}a(ve,"daemonKinds");async function ke(e){const t=Object.keys(await ve());if(!t.includes(e))throw h(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}a(ke,"assertKindServer");async function jt(){const e=await ve();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}a(jt,"handleListKinds");const qo=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:ft},{method:"GET",pattern:"/v1/nodes",handler:mt},{method:"GET",pattern:"/v1/kinds",handler:a(()=>jt(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:Pt},{method:"GET",pattern:"/v1/nodes/:id",handler:ht},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:wt},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:yt},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:gt},{method:"GET",pattern:"/v1/nodes/:id/session",handler:bt},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:vt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:kt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:Rt},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Ot},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:It},{method:"POST",pattern:"/v1/nodes/:id/close",handler:$t},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:Ct},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Nt},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:At},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Tt},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Et},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Mt}];export{Mt as handleConfig,ft as handleCreate,Rt as handleFork,mt as handleList,At as handlePromote,Tt as handleYield,qo as nodeRoutes,tr as resolveCreateKind};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var Z=Object.defineProperty;var f=(e,r)=>Z(e,"name",{value:r,configurable:!0});import{prepared as J}from"../../../core/sqlite-statements.js";import{ApiError as g}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as K}from"../../../api/dto/objects.js";import{openDb as A,withCanvasWrite as b}from"../../../core/canvas/db.js";import{actorOf as $}from"../../../core/graph/documents.js";import{readerForObject as F}from"../../../core/graph/reader.js";import{canRead as U}from"../../../core/graph/access.js";import{customObjectRef as I,authorizeCustom as S,fenceArgv as C}from"./custom-objects.js";import{edgesOf as Y}from"../../../core/graph/edges.js";import{publish as B}from"../../../core/graph/events.js";import{objectDTO as a}from"../../../core/graph/kinds/dto.js";import{isKind as Q,kindNames as X,kindOf as D}from"../../../core/graph/kinds/registry.js";import{listObjects as x,searchObjects as L}from"../../../core/graph/objects.js";import{checkoutsForCwd as ee}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as te,unwatch as re,watchersOf as ne,watchesOf as oe}from"../../../core/graph/watches.js";import{readerFor as m,resolveRef as P}from"../reader.js";import{invalidRequest as E,isRecord as v}from"./validate.js";const W=f(e=>r=>ee(e,r),"reposFnFor");function z(e,r){return{...a(e,r),...D(e,r.type).listItem?.(e,r)}}f(z,"listItem");function ie(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}f(ie,"remoteMessage");function G(e,r,t){try{return k(e,r,t)}catch(o){if(o instanceof g&&o.code==="not_found"&&!o.details?.deleted)return null;throw o}}f(G,"ownerFilter");function k(e,r,t){const o=P(e,r,t);if("remote"in o)throw new g(404,"not_found",ie(o.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in o)throw new g(404,"not_found",`${o.deleted.name} is deleted`,{id:o.deleted.id,deleted:!0});return o}f(k,"liveRef");const O=f(e=>decodeURIComponent(e.params.ref),"refParam");function se(e){const r=["1","true"].includes(e.query.get("fields")??"");return b(t=>{const o=m(t,e),n=P(t,o,O(e));if("remote"in n)return{state:"remote",remote:n.remote};if("deleted"in n)return{state:"deleted",deleted:a(t,n.deleted)};const{data:i,text:s}=D(t,n.type).read(t,o,n,{fields:r,reposFn:W(t)});return{state:"object",type:n.type,object:a(t,n),text:s,data:i}})}f(se,"read");function q(e,r,t,o){if(e!=null){if(!t.includes(e)){o.push({field:r,problem:`must be one of ${t.join(", ")}`,received:e});return}return e}}f(q,"oneOf");function V(e,r,t){if(r!=null){if(typeof r!="string"||!Q(e,r)){t.push({field:"type",problem:`must be a kind: one of ${X(e).join(", ")}`,received:r});return}return r}}f(V,"kindName");function H(e,r,t,o){if(e==null)return o;const n=Number(e);return!Number.isInteger(n)||n<1||n>100?(t.push({field:r,problem:"must be an integer from 1 to 100",received:e}),o):n}f(H,"limitOf");function ce(e){const r=e.query,t=[],o=V(A(),r.get("type"),t),n=q(r.get("privacy"),"privacy",K,t),i=H(r.get("limit"),"limit",t,50),s=r.get("cursor");s!==null&&!/^\d+$/.test(s)&&t.push({field:"cursor",problem:"is not a cursor from a previous page",received:s});const c=r.get("deleted");return c!==null&&!["0","1","true","false"].includes(c)&&t.push({field:"deleted",problem:"must be true or false",received:c}),t.length>0&&E("object list request",t),b(u=>{const d=m(u,e),p={...o?{type:o}:{},...n?{privacy:n}:{},...r.get("kind")!==null?{kind:r.get("kind")}:{},...c==="1"||c==="true"?{deleted:!0}:{}},h=r.get("owner");if(h!==null){const y=G(u,d,h);if(y===null)return{items:[],next_cursor:null};p.owner=y}const _=r.get("name"),w=[];let l=s===null?0:Number(s),T=!0;for(;w.length<i&&T;){const y=x(u,d,p,{limit:100,after_rowid:l});T=y.length===100;for(const R of y)if(l=R.rowid,(_===null||R.name.startsWith(_))&&w.push(R),w.length===i)break}const N=w.at(-1);return{items:w.map(y=>z(u,y)),next_cursor:w.length===i&&N?String(N.rowid):null}})}f(ce,"list");function ue(e){const r=[],t=v(e.body)?e.body:{};v(e.body)||r.push({field:"body",problem:"must be an object",received:e.body});const o=t.text;(typeof o!="string"||o.trim()==="")&&r.push({field:"text",problem:"is required",received:o});const n=t.grep;if(n!==void 0)if(typeof n!="string")r.push({field:"grep",problem:"must be a regular expression string",received:n});else try{new RegExp(n)}catch(c){r.push({field:"grep",problem:`is not a valid regular expression: ${c.message}`,received:n})}t.body!==void 0&&typeof t.body!="boolean"&&r.push({field:"body",problem:"must be a boolean",received:t.body});const i=V(A(),t.type,r);t.kind!==void 0&&typeof t.kind!="string"&&r.push({field:"kind",problem:"must be a string",received:t.kind}),t.owner!==void 0&&typeof t.owner!="string"&&r.push({field:"owner",problem:"must be a string",received:t.owner});const s=H(t.limit,"limit",r,50);return r.length>0&&E("object search request",r),b(c=>{const u=m(c,e),d=typeof t.owner=="string"?G(c,u,t.owner):null;if(typeof t.owner=="string"&&d===null)return{items:[]};const p=L(c,u,{text:o,body:t.body===!0||typeof n=="string"}),h=new Set(p.map(l=>l.object.rowid));return{items:(typeof n=="string"?L(c,u,{text:n,grep:!0}).filter(l=>h.has(l.object.rowid)):p).filter(l=>(!i||l.object.type===i)&&(t.kind===void 0||l.object.kind===t.kind)&&(!d||l.object.owner===d.rowid)).slice(0,s).map(l=>({object:z(c,l.object),...l.line!==void 0?{matches:[{line:l.line,text:l.text??""}]}:{}}))}})}f(ue,"search");const M=["interrupt","steer","after-turn","next-turn"],fe=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function de(e,r){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(t=>typeof t!="string"||!fe.test(t)||t.includes(">")&&!t.endsWith(">"))){r.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}f(de,"patternsOf");function le(e,r){if(e===void 0)return;if(!v(e)||Object.keys(e).length===0){r.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const t=[];for(const[o,n]of Object.entries(e)){const i=Number(o);!Number.isInteger(i)||i<1||i>10?r.push({field:`config.${o}`,problem:"level must be an integer from 1 to 10"}):M.includes(n)?t.push({threshold:i,delivery:n}):r.push({field:`config.${o}`,problem:`delivery must be one of ${M.join(", ")}`,received:n})}return t.sort((o,n)=>n.threshold-o.threshold)}f(le,"configOf");function ae(e){const r=[],t=e.body===void 0?{}:v(e.body)?e.body:(r.push({field:"body",problem:"must be an object"}),{}),o=de(t.patterns,r),n=le(t.config,r);return t.filter!==void 0&&!v(t.filter)&&r.push({field:"filter",problem:"must be an object",received:t.filter}),t.watcher!==void 0&&typeof t.watcher!="string"&&r.push({field:"watcher",problem:"must be a custom-object ref",received:t.watcher}),r.length>0&&E("watch request",r),b(i=>{const s=typeof t.watcher=="string"?I(i,t.watcher):null;if(e.publishToken&&!s)throw new g(404,"not_found","watcher not found");if(e.principal.class==="anonymous"&&!s)throw new g(404,"not_found","watcher not found");const c=s?S(i,e,s):$(m(i,e));s&&C(i,e,s);const u=s?F(i,s):m(i,e),d=s?(()=>{const h=k(i,u,O(e));if(!U(i,u,h))throw new g(404,"not_found","object not found");return h})():k(i,u,O(e)),p=o??[">"];return te(i,s??c,d,s?"act":"ask",{patterns:p,...n?{config:n}:{},...t.filter!==void 0?{filter:t.filter}:{}}),B(i,{event:"watched",object:d,actor:c,attrs:{}},W(i)),{object:a(i,d),patterns:p}})}f(ae,"watch");function pe(e){const r=e.query.get("pattern"),t=e.query.get("watcher");return b(o=>{const n=t?I(o,t):null;if((e.publishToken||e.principal.class==="anonymous")&&!n)throw new g(404,"not_found","watcher not found");const i=n?S(o,e,n):$(m(o,e));n&&C(o,e,n);const s=n?F(o,n):m(o,e),c=k(o,s,O(e)),u=f(()=>J(o,`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.rowid = s.watch
|
|
2
|
-
WHERE w.watcher = ? AND w.object = ?`).get((
|
|
1
|
+
var we=Object.defineProperty;var u=(e,t)=>we(e,"name",{value:t,configurable:!0});import{prepared as ye}from"../../../core/sqlite-statements.js";import{ApiError as w}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as be}from"../../../api/dto/objects.js";import{openDb as T,withCanvasWrite as y}from"../../../core/canvas/db.js";import{actorOf as V}from"../../../core/graph/documents.js";import{readerForObject as A}from"../../../core/graph/reader.js";import{canRead as ge}from"../../../core/graph/access.js";import{customObjectRef as H,authorizeCustom as B,fenceArgv as Z}from"./custom-objects.js";import{edgesOf as je}from"../../../core/graph/edges.js";import{publish as ke}from"../../../core/graph/events.js";import{objectDTO as b}from"../../../core/graph/kinds/dto.js";import{isKind as _e,kindNames as ve,kindOf as J}from"../../../core/graph/kinds/registry.js";import{listObjects as Ee,searchObjects as K}from"../../../core/graph/objects.js";import{checkoutsForCwd as Oe}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as Q,unwatch as Y,watchersOf as qe,watchesOf as Re}from"../../../core/graph/watches.js";import{readerFor as g,resolveRef as L}from"../reader.js";import{invalidRequest as $,isRecord as k}from"./validate.js";import{callerNode as X,callerStub as N,forwardVerb as x,originates as ee,queryWithoutMachine as P,relayError as C,remoteStub as Te,unknownError as te,forwarding as S,withMachine as F}from"../../peer/forward.js";import{getById as ne}from"../../../core/graph/objects.js";import{isStub as re}from"../../../core/peer/stubs.js";import{isUnreachable as $e}from"../../../core/peer/client.js";import{normalizeMachineId as I}from"../../../core/peer/directory.js";const M=u(e=>t=>Oe(e,t),"reposFnFor");function oe(e,t){return{...b(e,t),...J(e,t.type).listItem?.(e,t)}}u(oe,"listItem");function Se(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}u(Se,"remoteMessage");function ie(e,t,n){try{return R(e,t,n)}catch(r){if(r instanceof w&&r.code==="not_found"&&!r.details?.deleted)return null;throw r}}u(ie,"ownerFilter");function R(e,t,n){const r=L(e,t,n);if("remote"in r)throw new w(404,"not_found",Se(r.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in r)throw new w(404,"not_found",`${r.deleted.name} is deleted`,{id:r.deleted.id,deleted:!0});return r}u(R,"liveRef");const _=u(e=>decodeURIComponent(e.params.ref),"refParam"),se=u(e=>{const t=e.trim().replace(/^\[\[(.*)\]\]$/,"$1").trim(),n=t.indexOf("/");return n>0?t.slice(0,n):t},"idOf");function ae(e){const t=ne(T(),se(e));return t!==null&&re(T(),t)?t.id:null}u(ae,"stubIdOf");async function W(e,t,n,r){const o=ae(t);return o!==null?x(e,o,n):r()?{kind:"local"}:ee(e.principal)?x(e,se(t),n):{kind:"local"}}u(W,"forwardRef");function D(e,t){return y(n=>{try{return!("remote"in L(n,g(n,t),e))}catch{return!1}})}u(D,"resolvesLocally");const G=u(e=>`/v1/objects/${encodeURIComponent(e)}`,"objectPath");function ue(e,t,n,r,o){const i=t?.object;!i?.id||!i.type||y(s=>{const a=X(s,e);if(a===null)return;const c=Te(s,i.id,i.type,n,{kind:i.kind??null,name:i.name??i.id,...i.preview===void 0?{}:{preview:i.preview},owner:i.owner??null});Q(s,a,c,r,o===void 0?{}:{patterns:o})})}u(ue,"watchRemote");async function Ie(e){const t=_(e),n=["1","true"].includes(e.query.get("fields")??""),r=await W(e,t,{method:"GET",path:G(t),query:P(e)},()=>D(t,e));if(r.kind==="unknown")return{state:"unknown",ref:t,unreachable:r.unreachable};if(r.kind==="remote"){if(r.status>=400)throw C(r.status,r.body);return ue(e,r.body,r.machine.id,"read"),F(r.body,r.machine)}return y(o=>{const i=N(o,e),s=i===null?g(o,e):A(o,i,M(o)),a=L(o,s,t);if("remote"in a)return{state:"remote",remote:a.remote};if("deleted"in a)return{state:"deleted",deleted:b(o,a.deleted)};const{data:c,text:l}=J(o,a.type).read(o,s,a,{fields:n,reposFn:M(o)});return{state:"object",type:a.type,object:b(o,a),text:l,data:c}})}u(Ie,"read");function z(e,t,n,r){if(e!=null){if(!n.includes(e)){r.push({field:t,problem:`must be one of ${n.join(", ")}`,received:e});return}return e}}u(z,"oneOf");function ce(e,t,n){if(t!=null){if(typeof t!="string"||!_e(e,t)){n.push({field:"type",problem:`must be a kind: one of ${ve(e).join(", ")}`,received:t});return}return t}}u(ce,"kindName");function le(e,t,n,r){if(e==null)return r;const o=Number(e);return!Number.isInteger(o)||o<1||o>100?(n.push({field:t,problem:"must be an integer from 1 to 100",received:e}),r):o}u(le,"limitOf");function fe(e){const t=e.query,n=[],r=ce(T(),t.get("type"),n),o=z(t.get("privacy"),"privacy",be,n),i=le(t.get("limit"),"limit",n,50),s=t.get("cursor");s!==null&&!/^\d+$/.test(s)&&n.push({field:"cursor",problem:"is not a cursor from a previous page",received:s});const a=t.get("deleted");return a!==null&&!["0","1","true","false"].includes(a)&&n.push({field:"deleted",problem:"must be true or false",received:a}),n.length>0&&$("object list request",n),y(c=>{const l=g(c,e),h={...r?{type:r}:{},...o?{privacy:o}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...a==="1"||a==="true"?{deleted:!0}:{}},p=t.get("owner");if(p!==null){const m=ie(c,l,p);if(m===null)return{items:[],next_cursor:null};h.owner=m}const v=t.get("name"),j=[];let d=s===null?0:Number(s),E=!0;for(;j.length<i&&E;){const m=Ee(c,l,h,{limit:100,after_rowid:d});E=m.length===100;for(const q of m)if(d=q.rowid,(v===null||q.name.startsWith(v))&&j.push(q),j.length===i)break}const f=j.at(-1);return{items:j.map(m=>oe(c,m)),next_cursor:j.length===i&&f?String(f.rowid):null}})}u(fe,"listLocal");const Ae={ms:3e4},Le="self",U=u((e,t)=>e.map(n=>({...n,machine:t})),"labelItems");async function de(e,t,n,r){const o=S.current;try{const i=await o.call(t.id,{method:"GET",path:"/v1/objects",query:n},o.envelope(e.principal),r);if($e(i))return{state:"unreachable",items:[],next:null};if(i.status===426)return{state:"too_old",items:[],next:null};const s=i.body;return i.status!==200||!Array.isArray(s?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:U(s.items,t),next:s.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}u(de,"remotePage");async function Ne(e){const t=new Promise(n=>e.addEventListener("abort",()=>n(null),{once:!0}));return Promise.race([S.current.machines().catch(()=>null),t])}u(Ne,"machinesWithin");async function Pe(e){const t=e.query.get("machine");if(!ee(e.principal)||!S.current.joined()||t===Le)return fe(me(e));const r=S.current.self(),o=t!==null&&I(t)!==r,i=o?null:fe(me(e)),s=new AbortController,a=setTimeout(()=>s.abort(),Ae.ms);a.unref?.();try{const c=await Ne(s.signal);if(c===null){if(o)throw new w(503,"runtime_unreachable",`The directory did not answer, so ${I(t)} cannot be listed.`,{machine:I(t)});return i}const l=u(f=>({id:f,name:c.find(m=>m.machine_id===f)?.name??f}),"labelOf"),h=l(r),p=c.filter(f=>f.machine_id!==r),v=P(e);if(t!==null){if(!o)return{items:U(i.items,h),next_cursor:i.next_cursor,machines:[{machine_id:r,name:h.name,state:"ok",more:i.next_cursor!==null}]};const f=I(t);if(!p.some(q=>q.machine_id===f))throw new w(404,"not_found",`no machine ${f} on your account`,{machine:f});const m=await de(e,l(f),v,s.signal);return{items:m.items,next_cursor:m.next,machines:[{machine_id:f,name:l(f).name,state:m.state,more:m.next!==null}]}}const{cursor:j,...d}=v,E=await Promise.all(p.map(f=>de(e,l(f.machine_id),d,s.signal)));return{items:[...U(i.items,h),...E.flatMap(f=>f.items)],next_cursor:i.next_cursor,machines:[{machine_id:r,name:h.name,state:"ok",more:i.next_cursor!==null},...p.map((f,m)=>({machine_id:f.machine_id,name:f.name,state:E[m].state,more:E[m].next!==null}))]}}finally{clearTimeout(a)}}u(Pe,"list");function me(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}u(me,"withoutMachine");function Ce(e){const t=[],n=k(e.body)?e.body:{};k(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const r=n.text;(typeof r!="string"||r.trim()==="")&&t.push({field:"text",problem:"is required",received:r});const o=n.grep;if(o!==void 0)if(typeof o!="string")t.push({field:"grep",problem:"must be a regular expression string",received:o});else try{new RegExp(o)}catch(a){t.push({field:"grep",problem:`is not a valid regular expression: ${a.message}`,received:o})}n.body!==void 0&&typeof n.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:n.body});const i=ce(T(),n.type,t);n.kind!==void 0&&typeof n.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:n.kind}),n.owner!==void 0&&typeof n.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:n.owner});const s=le(n.limit,"limit",t,50);return t.length>0&&$("object search request",t),y(a=>{const c=g(a,e),l=typeof n.owner=="string"?ie(a,c,n.owner):null;if(typeof n.owner=="string"&&l===null)return{items:[]};const h=K(a,c,{text:r,body:n.body===!0||typeof o=="string"}),p=new Set(h.map(d=>d.object.rowid));return{items:(typeof o=="string"?K(a,c,{text:o,grep:!0}).filter(d=>p.has(d.object.rowid)):h).filter(d=>(!i||d.object.type===i)&&(n.kind===void 0||d.object.kind===n.kind)&&(!l||d.object.owner===l.rowid)).slice(0,s).map(d=>({object:oe(a,d.object),...d.line!==void 0?{matches:[{line:d.line,text:d.text??""}]}:{}}))}})}u(Ce,"search");const he=["interrupt","steer","after-turn","next-turn"],Fe=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function Me(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(n=>typeof n!="string"||!Fe.test(n)||n.includes(">")&&!n.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}u(Me,"patternsOf");function We(e,t){if(e===void 0)return;if(!k(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const n=[];for(const[r,o]of Object.entries(e)){const i=Number(r);!Number.isInteger(i)||i<1||i>10?t.push({field:`config.${r}`,problem:"level must be an integer from 1 to 10"}):he.includes(o)?n.push({threshold:i,delivery:o}):t.push({field:`config.${r}`,problem:`delivery must be one of ${he.join(", ")}`,received:o})}return n.sort((r,o)=>o.threshold-r.threshold)}u(We,"configOf");function pe(e){const t=ae(e);if(t!==null)throw new w(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}u(pe,"refuseStubWatch");async function De(e){const t=_(e);if(typeof(k(e.body)?e.body:{}).watcher=="string"&&pe(t),typeof(k(e.body)?e.body:{}).watcher!="string"){const n=await W(e,t,{method:"POST",path:`${G(t)}/watch`,body:e.body},()=>D(t,e));if(n.kind==="unknown")throw te(t,n.unreachable);if(n.kind==="remote"){if(n.status>=400)throw C(n.status,n.body);const r=n.body.patterns;return ue(e,n.body,n.machine.id,"ask",r),F(n.body,n.machine)}}return Ge(e)}u(De,"watch");function Ge(e){const t=[],n=e.body===void 0?{}:k(e.body)?e.body:(t.push({field:"body",problem:"must be an object"}),{}),r=Me(n.patterns,t),o=We(n.config,t);return n.filter!==void 0&&!k(n.filter)&&t.push({field:"filter",problem:"must be an object",received:n.filter}),n.watcher!==void 0&&typeof n.watcher!="string"&&t.push({field:"watcher",problem:"must be a custom-object ref",received:n.watcher}),t.length>0&&$("watch request",t),y(i=>{const s=typeof n.watcher=="string"?H(i,n.watcher):null;if(e.publishToken&&!s)throw new w(404,"not_found","watcher not found");if(e.principal.class==="anonymous"&&!s)throw new w(404,"not_found","watcher not found");const a=s?B(i,e,s):N(i,e)??V(g(i,e));s&&Z(i,e,s);const c=s?A(i,s):g(i,e),l=s?(()=>{const p=R(i,c,_(e));if(!ge(i,c,p))throw new w(404,"not_found","object not found");return p})():R(i,c,_(e)),h=r??[">"];return Q(i,s??a,l,s?"act":"ask",{patterns:h,...o?{config:o}:{},...n.filter!==void 0?{filter:n.filter}:{}}),ke(i,{event:"watched",object:l,actor:a,attrs:{}},M(i)),{object:b(i,l),patterns:h}})}u(Ge,"watchLocal");async function ze(e){const t=_(e);if(e.query.get("watcher")&&pe(t),!e.query.get("watcher")){const n=await W(e,t,{method:"DELETE",path:`${G(t)}/watch`,query:P(e)},()=>D(t,e));if(n.kind==="unknown")throw te(t,n.unreachable);if(n.kind==="remote"){if(n.status>=400)throw C(n.status,n.body);const r=n.body.object?.id;return y(o=>{const i=X(o,e),s=r===void 0?null:ne(o,r);i!==null&&s!==null&&re(o,s)&&Y(o,i,s,e.query.get("pattern")??void 0)}),F(n.body,n.machine)}}return Ue(e)}u(ze,"unwatchRoute");function Ue(e){const t=e.query.get("pattern"),n=e.query.get("watcher");return y(r=>{const o=n?H(r,n):null;if((e.publishToken||e.principal.class==="anonymous")&&!o)throw new w(404,"not_found","watcher not found");const i=o?B(r,e,o):N(r,e)??V(g(r,e));o&&Z(r,e,o);const s=o?A(r,o):g(r,e),a=R(r,s,_(e)),c=u(()=>ye(r,`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.rowid = s.watch
|
|
2
|
+
WHERE w.watcher = ? AND w.object = ?`).get((o??i).rowid,a.rowid).n,"count"),l=c();return Y(r,o??i,a,t??void 0),{object:b(r,a),removed:l-c()}})}u(Ue,"unwatchLocal");function Ve(e){const t=[],n=z(e.query.get("type"),"type",["acted-on","links-to","watches"],t),r=z(e.query.get("direction"),"direction",["out","in"],t);return t.length>0&&$("edges request",t),y(o=>{const i=g(o,e),s=R(o,i,_(e)),a=[];if(n!=="watches")for(const c of je(o,i,s,{...n?{type:n}:{},direction:r??"both"}))a.push({type:c.type,src:b(o,c.src),dst:b(o,c.dst),...c.written_as?{written_as:c.written_as}:{}});if(n===void 0||n==="watches"){const c=[...r!=="in"?Re(o,i,s):[],...r!=="out"?qe(o,i,s):[]];for(const l of c)a.push({type:"watches",src:b(o,l.watcher),dst:b(o,l.object)})}return{items:a}})}u(Ve,"edges");const O=u(e=>async t=>({status:200,body:await e(t)}),"ok"),ht=[{method:"POST",pattern:"/v1/objects/search",handler:O(Ce)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:O(Ve)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:O(De)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:O(ze)},{method:"GET",pattern:"/v1/objects/:ref",handler:O(Ie)},{method:"GET",pattern:"/v1/objects",handler:O(Pe)}];export{Ae as listBudget,ht as objectRoutes};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ApiError } from '../../api/errors.js';
|
|
2
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
3
|
+
import type { ObjectRow } from '../../core/graph/types.js';
|
|
4
|
+
import { type Envelope, type EnvelopeCaller } from '../../core/peer/envelope.js';
|
|
5
|
+
import { type PeerRequest } from '../../core/peer/client.js';
|
|
6
|
+
import { type HomeDeps } from '../../core/peer/home.js';
|
|
7
|
+
import { peerCall } from '../../core/peer/client.js';
|
|
8
|
+
import type { RequestContext, RequestPrincipal } from '../api/router.js';
|
|
9
|
+
export interface MachineLabel {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ForwardDeps extends Omit<HomeDeps, 'call'> {
|
|
14
|
+
/** Without an envelope the call is the machine's own (`peer.locate`); with one it is made for the caller. */
|
|
15
|
+
call(machine: string, request: PeerRequest, envelope?: Envelope, signal?: AbortSignal): ReturnType<typeof peerCall>;
|
|
16
|
+
envelope(principal: EnvelopeCaller): Envelope;
|
|
17
|
+
label(machine: string): Promise<MachineLabel>;
|
|
18
|
+
}
|
|
19
|
+
export declare const defaultForwardDeps: ForwardDeps;
|
|
20
|
+
/** The deps the handlers use; tests replace `current`. */
|
|
21
|
+
export declare const forwarding: {
|
|
22
|
+
current: ForwardDeps;
|
|
23
|
+
};
|
|
24
|
+
export type ForwardOutcome = {
|
|
25
|
+
kind: 'local';
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'unknown';
|
|
28
|
+
unreachable: string[];
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'remote';
|
|
31
|
+
status: number;
|
|
32
|
+
body: unknown;
|
|
33
|
+
machine: MachineLabel;
|
|
34
|
+
};
|
|
35
|
+
/** The callers whose by-id verbs may leave this machine: a person, a broker (a node), a cron. */
|
|
36
|
+
export declare const originates: (principal: RequestPrincipal) => principal is EnvelopeCaller;
|
|
37
|
+
/** Relay a non-2xx peer answer as the same API error. */
|
|
38
|
+
export declare function relayError(status: number, body: unknown): ApiError;
|
|
39
|
+
/** The error a verb throws when a machine could not answer. Never `not_found`. */
|
|
40
|
+
export declare function unknownError(id: string, unreachable: string[]): ApiError;
|
|
41
|
+
/** Add `machine` to an object body. */
|
|
42
|
+
export declare const withMachine: (body: unknown, machine: MachineLabel) => unknown;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve where `id` lives and, when it is another machine, make `request` there as the caller. `request` is built from the home
|
|
45
|
+
* machine's id only for logging; it is the same call whatever machine answers.
|
|
46
|
+
*/
|
|
47
|
+
export declare function forwardVerb(ctx: RequestContext, id: string, request: PeerRequest): Promise<ForwardOutcome>;
|
|
48
|
+
/** The envelope a forwarded call carried, rebuilt from its verified principal. */
|
|
49
|
+
export declare function envelopeOfForwarded(principal: Extract<RequestPrincipal, {
|
|
50
|
+
class: 'forwarded';
|
|
51
|
+
}>): Envelope;
|
|
52
|
+
/** The query a forwarded request carries: the caller's, without the `machine` hint (a hint names where to go, not what to ask). */
|
|
53
|
+
export declare function queryWithoutMachine(ctx: RequestContext): Record<string, string>;
|
|
54
|
+
/** On the home machine: the stub of the node a forwarded app call is made for (created or refreshed from the verified envelope), or null
|
|
55
|
+
* for a person actor, an unanchored app, or a local caller. */
|
|
56
|
+
export declare function callerStub(db: DatabaseSync, ctx: RequestContext): ObjectRow | null;
|
|
57
|
+
/** On the calling machine: the node making a call, when the caller is a node (a broker), else null. */
|
|
58
|
+
export declare function callerNode(db: DatabaseSync, ctx: RequestContext): ObjectRow | null;
|
|
59
|
+
/** On the calling machine: the stub of an object the home machine answered for. */
|
|
60
|
+
export declare function remoteStub(db: DatabaseSync, id: string, type: string, machine: string, ref?: {
|
|
61
|
+
kind?: string | null;
|
|
62
|
+
name?: string;
|
|
63
|
+
preview?: string;
|
|
64
|
+
owner?: {
|
|
65
|
+
type: string;
|
|
66
|
+
handle: string;
|
|
67
|
+
external_id?: string | null;
|
|
68
|
+
} | null;
|
|
69
|
+
}): ObjectRow;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var x=Object.defineProperty;var r=(e,n)=>x(e,"name",{value:n,configurable:!0});import{ApiError as f}from"../../api/errors.js";import{openDb as _}from"../../core/canvas/db.js";import{getById as v,nodeObject as $}from"../../core/graph/objects.js";import{envelopeFor as g}from"../../core/peer/envelope.js";import{isUnreachable as j}from"../../core/peer/client.js";import{machineReach as D}from"../../core/peer/directory.js";import{defaultHomeDeps as O,homeOf as S,relocate as q}from"../../core/peer/home.js";import{ensureStub as k,rehomeStub as A,stubOf as E}from"../../core/peer/stubs.js";import{peerCall as F}from"../../core/peer/client.js";const C={...O,call:r((e,n,o,t)=>F(e,n,{...o===void 0?{}:{envelope:o},...t===void 0?{}:{signal:t}}),"call"),envelope:r(e=>g(e),"envelope"),label:r(async e=>{try{const n=await D(e);return{id:e,name:n?.name??e}}catch{return{id:e,name:e}}},"label")},M={current:C},N=r(e=>e.class==="person"||e.class==="broker"||e.class==="cron","originates"),m=r(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 f(e,o?.code??"error",o?.message??`the home machine answered ${e}`,o?.details)}r(L,"relayError");function P(e,n){return new f(503,"runtime_unreachable",`No machine of yours answers for ${e} (unreachable: ${n.join(", ")}).`,{id:e,unreachable:n})}r(P,"unknownError");const Q=r((e,n)=>e!==null&&typeof e=="object"&&!Array.isArray(e)?{...e,machine:n}:e,"withMachine");async function T(e,n,o){const t=M.current,a=_(),u=v(a,n),l=u===null?null:E(a,u),w=e.principal;if(!N(w)){if(l!==null)throw new f(404,"not_here",`${n} is not homed on this machine (it is a stub of ${l.home_machine})`,{id:n,home_machine:l.home_machine});return{kind:"local"}}if(u!==null&&l===null)return{kind:"local"};const b={...t,call:r((s,d)=>t.call(s,d),"call")};let i=await S(a,n,{hint:e.query.get("machine"),deps:b});for(let s=0;s<2;s++){if(i.where==="nowhere"||i.where==="here"){if(l!==null)throw new f(404,"not_found",`${n} is no longer on any machine of yours`,{id:n});return{kind:"local"}}if(i.where==="unknown")return{kind:"unknown",unreachable:i.unreachable};const d=i.machine,c=await t.call(d,o,t.envelope(w)),p=await t.label(d);if(j(c))return{kind:"unknown",unreachable:[`${p.name} (${c.unreachable.reason})`]};const y=i.source!=="locate";if(c.status===404&&s===0&&(m(c.body)==="not_here"||y&&m(c.body)==="not_found")){const h=await q(a,n,d,b);if(h.where==="machine"){i=h;continue}if(h.where==="unknown")return{kind:"unknown",unreachable:h.unreachable};if(m(c.body)==="not_found")return{kind:"remote",status:c.status,body:c.body,machine:p};if(l!==null)throw new f(404,"not_found",`${n} is no longer on any machine of yours`,{id:n});return{kind:"local"}}return{kind:"remote",status:c.status,body:c.body,machine:p}}return{kind:"unknown",unreachable:[]}}r(T,"forwardVerb");function W(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}}}}r(W,"envelopeOfForwarded");function X(e){const n={};for(const[o,t]of e.query)o!=="machine"&&(n[o]=t);return n}r(X,"queryWithoutMachine");function Y(e,n){const o=n.principal;return o.class!=="forwarded"||o.actor.kind!=="app"||o.actor.node===null?null:k(e,o.actor.node,"node",o.via,W(o))}r(Y,"callerStub");function Z(e,n){return n.principal.class==="broker"?$(e,n.principal.node):null}r(Z,"callerNode");function ee(e,n,o,t,a){A(e,n,t);const u=a?.owner,l=u&&u.type==="app"?{id:"",type:"app",scheme:"app",external_id:u.external_id??(u.handle.startsWith("app:")?u.handle:`app:${u.handle}`),handle:u.handle}:null;return k(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:l})}r(ee,"remoteStub");export{Z as callerNode,Y as callerStub,C as defaultForwardDeps,W as envelopeOfForwarded,T as forwardVerb,M as forwarding,N as originates,X as queryWithoutMachine,L as relayError,ee as remoteStub,P as unknownError,Q as withMachine};
|
|
@@ -2,4 +2,6 @@ import type { RouteHandler, RouteTable } from '../api/router.js';
|
|
|
2
2
|
export declare const peerEvents: RouteHandler;
|
|
3
3
|
export declare const peerClaim: RouteHandler;
|
|
4
4
|
export declare const peerAck: RouteHandler;
|
|
5
|
+
/** `peer.locate`: "do you hold `id`?" -- `here` (a real local object), `moved` (a stub: the machine that homes it), or `no`. Reads nothing else. */
|
|
6
|
+
export declare const peerLocate: RouteHandler;
|
|
5
7
|
export declare const peerRoutes: RouteTable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var a=(e,t)=>u(e,"name",{value:t,configurable:!0});import{ApiError as c}from"../../api/errors.js";import{withCanvasWrite as l}from"../../core/canvas/db.js";import{getById as d}from"../../core/graph/objects.js";import{stubOf as v}from"../../core/peer/stubs.js";import{ackFor as y,claimFor as f,ingestPeerEvents as h,MAX_EVENTS_PER_CALL as p}from"../../core/peer/ingest.js";function m(e){if(e.principal.class!=="machine")throw new c(403,"permission_error","peer routes are for a machine");return e.principal.via}a(m,"via");const o=a(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{},"fields"),s=a(e=>typeof e=="string"&&e!=="","text");function w(e){const t=o(e),r=o(t.object);return s(t.key)&&s(t.message_id)&&s(t.event)&&typeof t.level=="number"&&s(r.id)&&s(r.type)&&typeof r.name=="string"&&(t.actor===null||s(o(t.actor).id)&&s(o(t.actor).type))&&o(t.attrs)===t.attrs}a(w,"validEvent");const b=a(e=>{const t=m(e),r=o(e.body).events;if(!Array.isArray(r))throw new c(400,"invalid_request","events must be an array");if(r.length>p)throw new c(400,"invalid_request",`at most ${p} events per call`);const n=r.findIndex(i=>!w(i));if(n>=0)throw new c(400,"invalid_request",`events[${n}] is not a well-formed event`);return{status:200,body:l(i=>h(i,t,r))}},"peerEvents"),_=a(e=>{const t=m(e),r=o(e.body).limit;return{status:200,body:{rows:l(i=>f(i,t,typeof r=="number"?r:50))}}},"peerClaim"),k=a(e=>{const t=m(e),r=o(e.body).acks;if(!Array.isArray(r)||r.some(n=>!s(o(n).key)||!s(o(n).claim_token)))throw new c(400,"invalid_request","acks must be an array of {key, claim_token}");return{status:200,body:{acked:l(n=>y(n,t,r))}}},"peerAck"),A=a(e=>{m(e);const t=o(e.body).id;if(!s(t))throw new c(400,"invalid_request","id must be a non-empty string");return l(r=>{const n=d(r,t);if(n===null)return{status:200,body:{answer:"no"}};const i=v(r,n);return{status:200,body:i===null?{answer:"here"}:{answer:"moved",machine:i.home_machine}}})},"peerLocate"),T=[{method:"POST",pattern:"/v1/peer/events",handler:b},{method:"POST",pattern:"/v1/peer/outbox/claim",handler:_},{method:"POST",pattern:"/v1/peer/outbox/ack",handler:k},{method:"POST",pattern:"/v1/peer/locate",handler:A}];export{k as peerAck,_ as peerClaim,b as peerEvents,A as peerLocate,T as peerRoutes};
|
|
@@ -53,6 +53,8 @@ export interface InboxCardEntry {
|
|
|
53
53
|
/** An already-resolved sender section supplied to the pure digest formatter. */
|
|
54
54
|
export interface InboxCardSection {
|
|
55
55
|
id: string;
|
|
56
|
+
/** The machine of the account the sender lives on, when it is not this one. */
|
|
57
|
+
machine?: string;
|
|
56
58
|
entries: readonly InboxCardEntry[];
|
|
57
59
|
}
|
|
58
60
|
export interface GeneratedCard {
|
|
@@ -80,4 +82,10 @@ export declare function isHumanWordsEntry(entry: CardEntry): boolean;
|
|
|
80
82
|
/** Explain how an inbox entry's ref is read without guessing its filesystem location. */
|
|
81
83
|
export declare function formatInboxRefInstruction(ref: string): string;
|
|
82
84
|
/** Format a complete inbox card from report bodies resolved by the caller. */
|
|
85
|
+
/** The machine a section's sender lives on, when its entries say it is another one (`data.from_machine`, set by the home side of a forwarded send). */
|
|
86
|
+
export declare function machineOfEntries(items: readonly {
|
|
87
|
+
data?: Record<string, unknown>;
|
|
88
|
+
}[]): {
|
|
89
|
+
machine?: string;
|
|
90
|
+
};
|
|
83
91
|
export declare function formatInboxCard(sections: readonly InboxCardSection[]): string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
1
|
+
var v=Object.defineProperty;var o=(e,t)=>v(e,"name",{value:t,configurable:!0});const T="crtr-context",E="crtr-situational-context",R="crtr-context-nudge",O="crtr-review-boundary",Y="You've stopped but you're not waiting on anyone and haven't finished. Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human send` if you are blocked or need the user.",I="This conversation has been idle with nothing left to wake it, so it is being concluded. This is your last turn. Use it to leave a trustworthy inheritance, not to restart or broaden the work. Do these four things now, then stop.\n\n1. Establish current truth. Check only state that may have changed outside the transcript and matters to resuming\u2014such as the working tree, a remote run, or an external decision. Do not start new work; perform only a quick check needed to avoid recording an unverified claim. If no mandate or work ever began, record that plainly in the inheritance and keep every artifact minimal.\n\n2. Put supporting material in documents you own (`crtr doc write`) only when it is needed to keep the inheritance concise. Rewrite existing living documents rather than leave superseded versions. Task state, identifiers, and recovery detail belong here, under this node, not under a longer-lived owner.\n\n3. Give a longer-lived owner (`--owner repo|profile|user`) only to a non-obvious, reusable lesson that should survive this task and is not already recorded. Read `crtr doc write -h`, search before writing (`crtr canvas search`), and choose the narrowest owner that will reach the next agent who needs it. Do not put a conversation recap, task status, recovery handles, or facts already captured in code or docs into such a document.\n\n4. Push exactly one regular update with `crtr push update --tier deferred`, never `crtr push final`. Write for someone who has not seen this conversation: name the work in plain terms, say where it stands, and say what remains or is blocked. Put the current outcome in the first line; include only needed decisions and recovery handles, then stop.",$="Provider credentials were just updated (a new login landed). Your previous turn stopped on a provider authentication failure. Continue from where you left off and retry the work that failed.",L="The network connection is back online. Your previous turn stopped on a connection error (the network was down). Continue from where you left off and retry the work that failed.",S="Your previous turn stopped on a connection error reaching the model provider. Retrying now: continue from where you left off and retry the work that failed.",M="Your previous turn stopped on a provider fault. Continue from where you left off and retry the work that failed.",D="<crtr-review-approval>",j="</crtr-review-approval>",V="<model-fallback-recovery>",B="</model-fallback-recovery>",g="\n```";function F(e,t){return`You must submit a result matching the required schema before you can stop: call the \`submit_result\` tool with \`request_id: "${t}"\` and the JSON in \`result\`, or with \`decline: { reason, code }\` when the schema cannot be honestly satisfied. You cannot finish or go dormant any other way while this request is pending.
|
|
2
2
|
|
|
3
3
|
Required schema:
|
|
4
4
|
|
|
5
5
|
\`\`\`json
|
|
6
|
-
${e}${g}`}o(F,"formatStructuredOutputReprompt");function q(e,t,n){return n==="credential"?`The previous model (${e}) had no usable provider credential, so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`:`The previous model (${e}) was unavailable (provider 404 not_found), so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`}o(q,"formatModelFallbackRecovery");function
|
|
7
|
-
`);return`<from${p({id:n.id})}>${i}</from>`}).join(`
|
|
8
|
-
`);return y("inbox",{},t)}o(
|
|
6
|
+
${e}${g}`}o(F,"formatStructuredOutputReprompt");function q(e,t,n){return n==="credential"?`The previous model (${e}) had no usable provider credential, so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`:`The previous model (${e}) was unavailable (provider 404 not_found), so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`}o(q,"formatModelFallbackRecovery");function x(e){switch(e){case R:return"context-nudge";case T:return"bearings";case O:return"review-boundary";case E:return"situational";default:return}}o(x,"legacyCustomTypeKind");const A=/^[A-Za-z_:][A-Za-z0-9_:.-]*$/,l=/\s+([A-Za-z_:][A-Za-z0-9_:.-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/gy;function k(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}o(k,"escapeXmlAttribute");function w(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">")}o(w,"escapeXmlText");function h(e){return e.replace(/&(?:amp|lt|gt|quot|apos);/g,t=>({"&":"&","<":"<",">":">",""":'"',"'":"'"})[t])}o(h,"unescapeXmlAttribute");function f(e){const t={};l.lastIndex=0;let n=0;for(;n<e.length&&!/^\s*$/.test(e.slice(n));){l.lastIndex=n;const i=l.exec(e);if(i===null)return null;const[,r,a,u]=i;if(r===void 0||Object.hasOwn(t,r))return null;t[r]=h(a??u??""),n=l.lastIndex}return t}o(f,"parseAttributes");function p(e){return Object.entries(e).filter(([,t])=>t!==void 0).map(([t,n])=>{if(!A.test(t))throw new Error(`Invalid XML attribute name: ${t}`);return` ${t}="${k(String(n))}"`}).join("")}o(p,"formatAttributes");function C(e){return typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(t=>typeof t=="object"&&t!==null&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}o(C,"generatedContextText");function y(e,t,n){if(e==="")throw new Error("Runtime card kind is required");if(Object.hasOwn(t,"kind"))throw new Error("Runtime card facts cannot replace kind");return`<runtime${p({kind:e,...t})}>${n}</runtime>`}o(y,"formatCard");function X(e,t,n){return y(e,t,w(n))}o(X,"formatDataCard");function P(e){const t=[],n=/<from\b([^>]*)>([\s\S]*?)<\/from>/g;for(const i of e.matchAll(n)){const r=f(i[1]??"");if(r?.id===void 0)continue;const a=[],u=i[2]??"",c=/<entry\b([^>]*)>([\s\S]*?)<\/entry>/g;for(const d of u.matchAll(c)){const s=f(d[1]??"");if(s?.kind===void 0)continue;const _=s.disposition==="human-answer"||s.disposition==="human-canceled"?s.disposition:"report";a.push({kind:s.kind,disposition:_,body:h(d[2]??""),...s.ref===void 0?{}:{ref:s.ref}})}const m=r.updates===void 0?Number.NaN:Number(r.updates);t.push({id:r.id,updates:Number.isFinite(m)?m:a.length,finished:r.finished==="true"||a.some(d=>d.kind==="final"),entries:a})}return t}o(P,"parseInboxBody");function N(e,t,n,i){return{kind:e,facts:t,body:n,senders:i}}o(N,"cardFor");function b(e){const t=/^<runtime\b([^>]*)>/.exec(e);if(t===null||!e.endsWith("</runtime>"))return null;const n=f(t[1]??"");if(n?.kind===void 0)return null;const i=e.slice(t[0].length,-10),{kind:r,...a}=n,u=Object.freeze(a),c=r.includes(":")?h(i):i;return N(r,u,c,r==="inbox"?P(c):[])}o(b,"parseEnvelope");function W(e){const t=C(e),n=b(t);if(n!==null)return n;if(e.role!=="custom")return null;const i=x(e.customType);return i===void 0?null:{kind:i,facts:Object.freeze({}),body:t,senders:[]}}o(W,"parseCard");function z(e){return e.disposition==="human-answer"&&b(e.body.trim())===null}o(z,"isHumanWordsEntry");function K(e){return e.startsWith("/")?`Preview only. Read the full body from file \`${e}\`.`:`Read this report with \`crtr canvas read ${e}\`.`}o(K,"formatInboxRefInstruction");function Z(e){const t=e.map(n=>n.data?.from_machine).find(n=>typeof n=="string");return t===void 0?{}:{machine:t}}o(Z,"machineOfEntries");function G(e){const t=e.map(n=>{const i=n.entries.map(r=>{const a=r.disposition==="human-answer"||r.disposition==="human-canceled"?r.disposition:void 0;return`<entry${p({kind:r.kind,ref:r.ref,disposition:a})}>${w(r.body)}</entry>`}).join(`
|
|
7
|
+
`);return`<from${p({id:n.id,machine:n.machine})}>${i}</from>`}).join(`
|
|
8
|
+
`);return y("inbox",{},t)}o(G,"formatInboxCard");export{$ as AUTH_FAULT_RECOVERY_BODY,L as CONNECTION_FAULT_RECOVERY_BODY,T as CONTEXT_INTRO_CUSTOM_TYPE,R as CONTEXT_NUDGE_CUSTOM_TYPE,I as PARK_SUMMARY_PROMPT,M as PROVIDER_FAULT_RECOVERY_BODY,O as REVIEW_BOUNDARY_CUSTOM_TYPE,S as RUN_CONNECTION_FAULT_RETRY_BODY,E as SITUATIONAL_CONTEXT_CUSTOM_TYPE,Y as STALL_REPROMPT,y as formatCard,X as formatDataCard,G as formatInboxCard,K as formatInboxRefInstruction,q as formatModelFallbackRecovery,F as formatStructuredOutputReprompt,C as generatedContextText,z as isHumanWordsEntry,Z as machineOfEntries,W as parseCard};
|