@north-light/cli 0.3.444 → 0.3.446
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/builtin-memory/crouter-sdk/release-notes.md +6 -0
- package/dist/clients/attach/viewer.js +127 -127
- package/dist/core/audit.d.ts +23 -0
- package/dist/core/audit.js +3 -0
- package/dist/core/canvas/migrations.js +12 -12
- package/dist/core/graph/reader.js +3 -3
- package/dist/daemon/api/app-listener.js +12 -12
- package/dist/daemon/api/handlers/bash.d.ts +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/human-requests.d.ts +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/messages.js +1 -1
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/operations.d.ts +1 -1
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/principal.d.ts +3 -1
- package/dist/daemon/api/principal.js +1 -1
- package/dist/daemon/api/router.d.ts +29 -1
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/peer/handlers.d.ts +2 -0
- package/dist/daemon/peer/handlers.js +1 -0
- package/dist/daemon/peer/ingress.d.ts +34 -0
- package/dist/daemon/peer/ingress.js +1 -0
- package/docs/sdk/release-notes.md +6 -0
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
var X=Object.defineProperty;var c=(t,e)=>X(t,"name",{value:e,configurable:!0});import{randomBytes as Y}from"node:crypto";import{claimNodeMail as Z,acknowledgeNodeMail as ee}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as te}from"../../../core/feed/inbox.js";import{enqueueNodeMail as M,cancelPendingNodeMail as re}from"../../../core/feed/messages.js";import{reviveNode as B}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as T}from"../../../core/runtime/broker-request.js";import{isBrokerLive as A}from"../../../core/runtime/model-swap.js";import{deliverLive as ne,interruptLive as oe}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as ie}from"../../../core/profiles/manifest.js";import{getNode as $,withFreshTerminalGuard as ae}from"../../../core/canvas/canvas.js";import{getById as se,nodeObject as z,ownerForGrantee as de}from"../../../core/graph/objects.js";import{recordActedOn as ce}from"../../../core/graph/edges.js";import{recordWatch as ue}from"../../../core/graph/watches.js";import{publish as W}from"../../../core/graph/events.js";import{readerFor as le}from"../reader.js";import{withCanvasWrite as J}from"../../../core/canvas/db.js";import{getPendingStructuredRequestForNode as L}from"../../../core/canvas/structured-requests.js";import{cancelCronsOnWake as G}from"../../../core/canvas/crons.js";import{assertNotFinalized as C,assertFinalizedForReopen as fe,commitReopenResident as j}from"../../../core/runtime/reopen.js";import{admitLegacyStructuredOutput as me}from"../../structured-requests/sidecar.js";import{appendSituationalContext as F,formatSituationalProse as pe}from"../../../core/runtime/situational-context.js";import{formatDataCard as D}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as ye}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as he}from"../../park-pending.js";import{wantsExecution as ge}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as ve}from"../../../core/runtime/revive.js";import{CrtrError as be,notFound as q,usage as d}from"../../../core/errors.js";import{emitEvent as we}from"../../../core/events/emit.js";import{assertScope as _e}from"../../../core/scopes.js";import{InputError as O}from"../../../core/io.js";import{ApiError as ke}from"../../../api/index.js";import{ownerOnly as xe}from"../router.js";const Se=["critical","urgent","normal","deferred"];function U(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw d(`${e} must be an object { kind, facts?, body? }`);const i=t,r=i.kind;if(typeof r!="string"||r.trim()==="")throw d(`${e}.kind is required`);if(!r.includes(":"))throw d(`${e}.kind must be namespaced (contain ':'): ${r}`);const s={kind:r},n=i.facts;if(n!==void 0){if(typeof n!="object"||n===null||Array.isArray(n))throw d(`${e}.facts must be an object of string or number values`);const m={};for(const[l,f]of Object.entries(n)){if(typeof f!="string"&&typeof f!="number")throw d(`${e}.facts.${l} must be a string or number`);m[l]=f}s.facts=m}const o=i.body;if(o!==void 0){if(typeof o!="string")throw d(`${e}.body must be a string`);s.body=o}return s}c(U,"parseCardRequest");function H(t,e){try{return D(t.kind,t.facts??{},t.body??"")}catch(i){throw d(`${e}: ${i instanceof Error?i.message:String(i)}`)}}c(H,"renderCard");function $e(t){if(typeof t!="object"||t===null)throw d("a message requires a JSON body { body, tier?, fresh? }");const e=t,i=e.body,r=e.fresh===!0,s=e.tier,n=e.situational_context,o=e.output_schema,m=typeof i=="string"&&i.trim()!=="",l=typeof n=="string"&&n.trim()!=="",f=typeof o=="string"&&o.trim()!=="",w=e.situational_card,h=e.context_cards,v=w===void 0?void 0:U(w,"situational_card");if(h!==void 0&&!Array.isArray(h))throw d("context_cards must be an array of { kind, facts?, body? }");const p=h?.map((R,y)=>U(R,`context_cards[${y}]`));if(v!==void 0&&typeof n=="string"&&n!=="")throw d("situational_card and situational_context are mutually exclusive");const _=v!==void 0||p!==void 0&&p.length>0;if(!r&&!m&&!l&&!f&&!_)throw d("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(r&&p!==void 0&&p.length>0)throw d("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(s!==void 0&&!Se.includes(s))throw d(`invalid tier: ${String(s)} (expected critical|urgent|normal|deferred)`);const u={body:typeof i=="string"?i:""};s!==void 0&&(u.tier=s),r&&(u.fresh=!0),e.reopen===!0&&(u.reopen=!0),typeof n=="string"&&(u.situational_context=n),v!==void 0&&(u.situational_card=v),p!==void 0&&(u.context_cards=p),typeof o=="string"&&(u.output_schema=o),typeof e.from=="string"&&(u.from=e.from);const b=e.delivery;if(b!==void 0&&b!=="interactive")throw d(`invalid delivery: ${String(b)} (expected interactive)`);if(b==="interactive"){if(r||u.situational_context!==void 0||u.output_schema!==void 0)throw d("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!m)throw d("interactive delivery requires a non-empty body");if(u.tier==="deferred")throw d("interactive delivery cannot be deferred");u.delivery="interactive"}return u}c($e,"parseSendBody");function qe(t){try{return JSON.parse(t)}catch{throw d("output_schema must be a JSON schema string")}}c(qe,"parseSchema");function Ne(t){return t.split(`
|
|
2
|
-
`)[0].slice(0,120)}c(Ne,"label");function K(t,e){return e===null?"":D("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}c(K,"previousFinalReportCard");function Ae(t,e,i){if(i!==null&&i!=="human"&&se(t,i)?.type==="node"){const n=z(t,i);return{actor:n,senderNode:n}}if(i==="human")return{actor:de(t,"user:local"),senderNode:null};const r=le(t,e);return{actor:r.class==="person"?r.person:r.class==="app"?r.app:r.node,senderNode:r.class==="node"?r.node:null}}c(Ae,"messageActor");function Q(t,e,i,r,s,n){const o=z(t,i),{actor:m,senderNode:l}=Ae(t,e,r),f=s===null?{}:{pointer:s};ce(t,m,o),l!==null&&l.rowid!==o.rowid&&ue(t,l,o,"message",{endsOn:n&&s!==null?`result:${s}`:"final"}),W(t,{event:"messaged",object:o,actor:m,attrs:{},...f}),l!==null&&W(t,{event:"sent",object:l,actor:l,attrs:{to:o.id},...f})}c(Q,"recordMessage");function Ce(t,e){return new O({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."})}c(Ce,"deferredNoNaturalCycle");function je(t){if(!ve(t))throw new ke(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}c(je,"assertRecoverableForFresh");function Fe(t,e){return t instanceof O?{error:t.payload.error,message:t.payload.message,next:t.payload.next,message_id:e}:t instanceof be?{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}}c(Fe,"wakeFailure");async function Oe(t){const e=t.params.id,i=$(e);if(i===null)throw q(`unknown node: ${e}`,{received:e});const r=$e(t.body),s=r.tier??"normal",n=ie(i.profile_id),o=r.from??null;if(o!==null){const a=$(o);a!==null&&_e(a,"crtr:act")}const m=r.body.trim()!=="",l=r.situational_card!==void 0?H(r.situational_card,"situational_card"):r.situational_context!==void 0?pe(r.situational_context.trim()):"",f=l!=="",w=(r.context_cards??[]).map((a,g)=>H(a,`context_cards[${g}]`)),h=r.output_schema!==void 0&&r.output_schema.trim()!==""?qe(r.output_schema):null;let v=!1;const p=c(a=>{if(!(h===null||v)){if(L(e)!==null)throw new O({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."});me(e,"oneoff",h,a),v=!0}},"ensureSchema");if(r.fresh){const a=r.reopen?fe(e):null;r.reopen||C(e),je(e),p(),f&&F(e,l),r.reopen&&j(e,a);const g=await B(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:g.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&C(e);let _=!1,u="";if(r.delivery==="interactive"&&r.reopen&&(u=K(e,j(e)),_=!0),r.delivery==="interactive"&&p(),r.delivery==="interactive"&&!n&&!i.run_id&&A(i))try{return f&&F(e,l),await ne(e,r.body,{cards:[...u===""?[]:[u],...f?[l]:[],...w],origin:o==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...o===null?{}:{from:o},kind:"message",tier:s}]}}),J(g=>Q(g,t,e,o,null,!1)),G(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(a){if(!(a instanceof T))throw a}const b=c(()=>{r.reopen||C(e);const a=Y(16).toString("hex"),g=c(S=>Q(S,t,e,o,a,h!==null),"withinEnqueue");p(a),f&&F(e,l),r.reopen&&!_&&(u=K(e,j(e)));const N=[...u===""?[]:[u],...w],I=N.length>0?{cards:N}:{};if(m||h!==null){const S=m?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: "${L(e)?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return M(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",messageId:a,withinEnqueue:g,label:Ne(S),bodyJson:{body:S,...f?{situational:!0}:{},...I}})}return M(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",messageId:a,withinEnqueue:g,label:f?"(ambient context updated)":"(context delivered)",bodyJson:{...f?{situational:!0}:{},situationalOnly:!0,...I}})},"deliverImmediate"),y=c(()=>{if(s==="deferred"){const a=ae(e,ye,b);if(a.kind==="missing")throw q(`unknown node: ${e}`,{received:e});if(a.kind==="terminal")throw Ce(e,a.status);return a.result}return b()},"deliver")();y.urgency!=="deferred"&&J(()=>he(e));const k=$(e);if(k===null)throw q(`unknown node: ${e}`,{received:e});i.frozen_at!==null&&G(e);let P=!1,E=!1,x;if((r.reopen||k.lifecycle==="terminal"||!ge(k))&&y.urgency!=="deferred"&&!n&&!A(k))try{const a=await B(e,{resume:!0,capacity:"freeze"});P=a.launch!==void 0,E=a.outcome==="frozen"}catch(a){x=Fe(a,y.messageId),we({level:"error",event:"message.wake_failed",node_id:e,error:a,fields:{message_id:y.messageId,error_code:x.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:P,...E?{not_revived_reason:"capacity_frozen"}:{},...x===void 0?{}:{wake_failed:x},delivered_at:y.createdAt,...y.urgency===s?{}:{delivered_tier:y.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}c(Oe,"handleMessage");async function Re(t){const e=t.params.id,i=$(e);if(i===null)throw q(`unknown node: ${e}`,{received:e});const r=re(e,{senderNodeId:"human",kind:"message"});let s=!1;if(A(i))try{s=await oe(e)!=="idle"}catch(o){if(!(o instanceof T))throw o}return{status:200,body:{node_id:e,outcome:s?"aborted_turn":r.length>0?"canceled_pending":"idle",aborted_turn:s,canceled_pending:r.length}}}c(Re,"handleInterrupt");function V(t){if(typeof t.body!="object"||t.body===null||Array.isArray(t.body))throw d("mail requires an object body");const e=t.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw d("execution_id is required");return e}c(V,"mailBody");function Pe(t){const e=V(t),i=e.channel;if(i!=="wake"&&i!=="passive"&&i!=="deferred_run")throw d("channel must be wake, passive, or deferred_run");const r=Z(t.params.id,e.execution_id,i);return{status:200,body:{action:r.action,deliveries:r.deliveries.map(n=>({delivery_id:n.deliveryId,attempts:n.attempts,handoff:n.handoff,entry:{...te(n),seq:n.message.seq}}))}}}c(Pe,"handleMailClaim");function Ee(t){const e=V(t);if(!Array.isArray(e.deliveries))throw d("deliveries must be an array");const i=e.deliveries.map(n=>{if(typeof n!="object"||n===null||Array.isArray(n))throw d("each delivery must be an object");const o=n;if(typeof o.delivery_id!="string"||o.delivery_id==="")throw d("delivery_id is required");if(!Number.isSafeInteger(o.attempts)||o.attempts<1)throw d("attempts must be a positive integer");if(o.disposition!=="acknowledged"&&o.disposition!=="released")throw d("disposition must be acknowledged or released");return{delivery_id:o.delivery_id,attempts:o.attempts,disposition:o.disposition}}),r=ee(t.params.id,e.execution_id,i.map(n=>({deliveryId:n.delivery_id,attempts:n.attempts,disposition:n.disposition})));return{status:200,body:{action:r.action,results:r.results.map(n=>({delivery_id:n.deliveryId,outcome:n.outcome}))}}}c(Ee,"handleMailAcknowledge");const gt=xe([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:Pe},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:Ee}]),vt=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:Oe},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Re}];export{gt as brokerMailRoutes,Oe as handleMessage,vt as messageRoutes};
|
|
2
|
+
`)[0].slice(0,120)}c(Ne,"label");function K(t,e){return e===null?"":D("reopen-final-report",{report:`${t}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}c(K,"previousFinalReportCard");function Ae(t,e,i){if(i!==null&&i!=="human"&&se(t,i)?.type==="node"){const n=z(t,i);return{actor:n,senderNode:n}}if(i==="human")return{actor:de(t,"user:local"),senderNode:null};const r=le(t,e);return{actor:r.class==="person"?r.person:r.class==="app"?r.app:r.node,senderNode:r.class==="node"?r.node:null}}c(Ae,"messageActor");function Q(t,e,i,r,s,n){const o=z(t,i),{actor:m,senderNode:l}=Ae(t,e,r),f=s===null?{}:{pointer:s};ce(t,m,o),l!==null&&l.rowid!==o.rowid&&ue(t,l,o,"message",{endsOn:n&&s!==null?`result:${s}`:"final"}),W(t,{event:"messaged",object:o,actor:m,attrs:{},...f}),l!==null&&W(t,{event:"sent",object:l,actor:l,attrs:{to:o.id},...f})}c(Q,"recordMessage");function Ce(t,e){return new O({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."})}c(Ce,"deferredNoNaturalCycle");function je(t){if(!ve(t))throw new ke(422,"unprocessable",`node ${t} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}c(je,"assertRecoverableForFresh");function Fe(t,e){return t instanceof O?{error:t.payload.error,message:t.payload.message,next:t.payload.next,message_id:e}:t instanceof be?{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}}c(Fe,"wakeFailure");async function Oe(t){const e=t.params.id,i=$(e);if(i===null)throw q(`unknown node: ${e}`,{received:e});const r=$e(t.body),s=r.tier??"normal",n=ie(i.profile_id),o=t.principal.class==="forwarded"?null:r.from??null;if(o!==null){const a=$(o);a!==null&&_e(a,"crtr:act")}const m=r.body.trim()!=="",l=r.situational_card!==void 0?H(r.situational_card,"situational_card"):r.situational_context!==void 0?pe(r.situational_context.trim()):"",f=l!=="",w=(r.context_cards??[]).map((a,g)=>H(a,`context_cards[${g}]`)),h=r.output_schema!==void 0&&r.output_schema.trim()!==""?qe(r.output_schema):null;let v=!1;const p=c(a=>{if(!(h===null||v)){if(L(e)!==null)throw new O({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."});me(e,"oneoff",h,a),v=!0}},"ensureSchema");if(r.fresh){const a=r.reopen?fe(e):null;r.reopen||C(e),je(e),p(),f&&F(e,l),r.reopen&&j(e,a);const g=await B(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:g.launch!==void 0}}}r.delivery==="interactive"&&!r.reopen&&C(e);let _=!1,u="";if(r.delivery==="interactive"&&r.reopen&&(u=K(e,j(e)),_=!0),r.delivery==="interactive"&&p(),r.delivery==="interactive"&&!n&&!i.run_id&&A(i))try{return f&&F(e,l),await ne(e,r.body,{cards:[...u===""?[]:[u],...f?[l]:[],...w],origin:o==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...o===null?{}:{from:o},kind:"message",tier:s}]}}),J(g=>Q(g,t,e,o,null,!1)),G(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(a){if(!(a instanceof T))throw a}const b=c(()=>{r.reopen||C(e);const a=Y(16).toString("hex"),g=c(S=>Q(S,t,e,o,a,h!==null),"withinEnqueue");p(a),f&&F(e,l),r.reopen&&!_&&(u=K(e,j(e)));const N=[...u===""?[]:[u],...w],I=N.length>0?{cards:N}:{};if(m||h!==null){const S=m?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: "${L(e)?.request_id??"<request-id>"}"\`) before you stop; after it is accepted, continue normally.`;return M(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",messageId:a,withinEnqueue:g,label:Ne(S),bodyJson:{body:S,...f?{situational:!0}:{},...I}})}return M(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",messageId:a,withinEnqueue:g,label:f?"(ambient context updated)":"(context delivered)",bodyJson:{...f?{situational:!0}:{},situationalOnly:!0,...I}})},"deliverImmediate"),y=c(()=>{if(s==="deferred"){const a=ae(e,ye,b);if(a.kind==="missing")throw q(`unknown node: ${e}`,{received:e});if(a.kind==="terminal")throw Ce(e,a.status);return a.result}return b()},"deliver")();y.urgency!=="deferred"&&J(()=>he(e));const k=$(e);if(k===null)throw q(`unknown node: ${e}`,{received:e});i.frozen_at!==null&&G(e);let P=!1,E=!1,x;if((r.reopen||k.lifecycle==="terminal"||!ge(k))&&y.urgency!=="deferred"&&!n&&!A(k))try{const a=await B(e,{resume:!0,capacity:"freeze"});P=a.launch!==void 0,E=a.outcome==="frozen"}catch(a){x=Fe(a,y.messageId),we({level:"error",event:"message.wake_failed",node_id:e,error:a,fields:{message_id:y.messageId,error_code:x.error}})}return{status:201,body:{node_id:e,delivered:!0,revived:P,...E?{not_revived_reason:"capacity_frozen"}:{},...x===void 0?{}:{wake_failed:x},delivered_at:y.createdAt,...y.urgency===s?{}:{delivered_tier:y.urgency},...r.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}c(Oe,"handleMessage");async function Re(t){const e=t.params.id,i=$(e);if(i===null)throw q(`unknown node: ${e}`,{received:e});const r=re(e,{senderNodeId:"human",kind:"message"});let s=!1;if(A(i))try{s=await oe(e)!=="idle"}catch(o){if(!(o instanceof T))throw o}return{status:200,body:{node_id:e,outcome:s?"aborted_turn":r.length>0?"canceled_pending":"idle",aborted_turn:s,canceled_pending:r.length}}}c(Re,"handleInterrupt");function V(t){if(typeof t.body!="object"||t.body===null||Array.isArray(t.body))throw d("mail requires an object body");const e=t.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw d("execution_id is required");return e}c(V,"mailBody");function Pe(t){const e=V(t),i=e.channel;if(i!=="wake"&&i!=="passive"&&i!=="deferred_run")throw d("channel must be wake, passive, or deferred_run");const r=Z(t.params.id,e.execution_id,i);return{status:200,body:{action:r.action,deliveries:r.deliveries.map(n=>({delivery_id:n.deliveryId,attempts:n.attempts,handoff:n.handoff,entry:{...te(n),seq:n.message.seq}}))}}}c(Pe,"handleMailClaim");function Ee(t){const e=V(t);if(!Array.isArray(e.deliveries))throw d("deliveries must be an array");const i=e.deliveries.map(n=>{if(typeof n!="object"||n===null||Array.isArray(n))throw d("each delivery must be an object");const o=n;if(typeof o.delivery_id!="string"||o.delivery_id==="")throw d("delivery_id is required");if(!Number.isSafeInteger(o.attempts)||o.attempts<1)throw d("attempts must be a positive integer");if(o.disposition!=="acknowledged"&&o.disposition!=="released")throw d("disposition must be acknowledged or released");return{delivery_id:o.delivery_id,attempts:o.attempts,disposition:o.disposition}}),r=ee(t.params.id,e.execution_id,i.map(n=>({deliveryId:n.delivery_id,attempts:n.attempts,disposition:n.disposition})));return{status:200,body:{action:r.action,results:r.results.map(n=>({delivery_id:n.deliveryId,outcome:n.outcome}))}}}c(Ee,"handleMailAcknowledge");const gt=xe([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:Pe},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:Ee}]),vt=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:Oe},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Re}];export{gt as brokerMailRoutes,Oe as handleMessage,vt as messageRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var T=Object.defineProperty;var i=(t,e)=>T(t,"name",{value:e,configurable:!0});import{assertLaunchKind as v}from"../../../core/runtime/launch-target.js";import{listNodesByProfile as h,shiftProfileNodeDeadlines as k}from"../../../core/canvas/canvas.js";import{liveExecutionForNode as D}from"../../../core/canvas/executions.js";import{shiftAutoBackgroundBashDeadlines as q}from"../../../core/bash-jobs.js";import{contextDir as N}from"../../../core/canvas/node-agent-paths.js";import{boundFleet as O}from"../../../core/runtime/fleet.js";import{recordedPidLiveness as L}from"../../../core/canvas/pid.js";import{withCanvasWrite as M}from"../../../core/canvas/db.js";import{renameProfileObject as S}from"../../../core/graph/objects.js";import{usage as l}from"../../../core/errors.js";import{ApiError as p}from"../../../api/errors.js";import{scopeAllowed as P}from"../../../core/scopes.js";import{validateEnvVarName as V}from"../../../core/env-name.js";import{listProfileEnvNames as $,removeProfileEnvVar as F,setProfileEnvVar as R}from"../../../core/profiles/env-store.js";import{listAppEnvNames as G,removeAppEnvVar as U,setAppEnvVar as B}from"../../../core/profiles/app-env-store.js";import{addProfileProject as C,assertDeliveryLimits as K,setProfileDeliveryLimit as H,assertProfileProjects as y,createProfile as w,ensureRootProfile as W,listProfiles as u,loadProfileManifest as _,pauseProfile as z,removeProfileProject as J,renameProfile as Q,resumeProfile as X,setProfileDefaultKind as Y,updateProfileMetadata as Z}from"../../../core/profiles/manifest.js";import{requestProfileDeletion as x}from"../../profile-delete.js";import{brokerSignalBus as ee}from"../../broker-signals/bus.js";import{toProfileDTO as d}from"../map.js";import{appOf as b,resolvedScopes as te}from"../router.js";const E="root";function m(t){return b(t.principal)??"app:terminal"}i(m,"callerApp");function g(t,e,n=null){if(u().some(r=>r.manifest.name===e&&r.profileId!==n&&(r.manifest.grantee??"app:terminal")===t))throw new p(400,"invalid_request",`${t} already has a profile named ${e}`)}i(g,"assertNameFree");function f(t,e){const n=A(t,e),r=n.manifest.grantee??"app:terminal";if(t.principal.class!=="person"&&r!==b(t.principal))throw new p(403,"permission_error",`profile ${n.profileId} belongs to ${r}; only that app changes it`);return n}i(f,"requireOwnProfile");async function re(t){const e=t.body??{};if(typeof e.name!="string"||e.name.trim()==="")throw l("a profile name is required",{field:"name"});e.projects!==void 0&&y(e.projects);const n=m(t),r=e.name.trim();g(n,r),e.default_kind!==void 0&&await v(e.default_kind,process.cwd(),null);const o=w(r,e.projects??[],{defaultKind:e.default_kind,metadata:e.metadata,grantee:n});return{status:201,body:d(o)}}i(re,"handleCreate");function ne(t,e){const n=e.trim();if(n==="")throw l("profile name must not be empty");return M(r=>(S(r,t,n),Q(t,n)))}i(ne,"renameProfileAndHandle");async function ae(t){const{profileId:e,manifest:n}=f(t,t.params.name),r=t.body??{};return r.name!==void 0&&g(n.grantee??"app:terminal",r.name.trim(),e),r.default_kind!==void 0&&await v(r.default_kind,process.cwd(),e),r.add_project!==void 0&&y([r.add_project]),r.set_delivery_limit!==void 0&&K({[r.set_delivery_limit.owner]:r.set_delivery_limit.level}),r.name!==void 0&&ne(e,r.name),r.default_kind!==void 0&&Y(e,r.default_kind),r.add_project!==void 0&&C(e,r.add_project.path),r.set_delivery_limit!==void 0&&H(e,r.set_delivery_limit.owner,r.set_delivery_limit.level),r.remove_project!==void 0&&J(e,r.remove_project),{status:200,body:d(_(e))}}i(ae,"handleUpdate");function ie(t){const{profileId:e}=f(t,t.params.name);return{status:200,body:{profile_id:e,names:$(e)}}}i(ie,"handleEnvList");function c(t){const e=t.params.var,n=V(e);if(!n.isValid)throw l(`invalid env var name: ${n.errors.join("; ")}`,{field:"name",received:e});return e}i(c,"requireEnvVarName");function oe(t){const{profileId:e}=f(t,t.params.name),n=c(t),{value:r}=t.body??{};if(typeof r!="string"||r==="")throw l("a non-empty env value is required",{field:"value"});return{status:200,body:{profile_id:e,changed:R(e,n,r)}}}i(oe,"handleEnvSet");function se(t){const{profileId:e}=f(t,t.params.name),n=c(t);return{status:200,body:{profile_id:e,changed:F(e,n)}}}i(se,"handleEnvRemove");async function de(t){const e=t.params.name,n=t.body??{};n.projects!==void 0&&y(n.projects);const r=m(t);if(e===E&&r==="app:terminal")return{status:200,body:d(W())};if(e===E)throw new p(403,"permission_error","root belongs to the terminal app");const o=u().find(s=>s.manifest.name===e&&(s.manifest.grantee??"app:terminal")===r);if(o!==void 0)return{status:200,body:d(o)};n.default_kind!==void 0&&await v(n.default_kind,process.cwd(),null);const a=w(e,n.projects??[],{defaultKind:n.default_kind,metadata:n.metadata,grantee:r});return{status:200,body:d(a)}}i(de,"handleEnsure");function le(t){const e=f(t,t.params.name),n=t.body??{};if(typeof n!="object"||n===null||Array.isArray(n))throw l("profile metadata body must be an object",{field:"body"});const r=n,o=r.unset===void 0?[]:r.unset;if(!Array.isArray(o)||o.some(I=>typeof I!="string"))throw l("profile metadata `unset` must be an array of strings",{field:"unset"});const a=r.set===void 0?{}:r.set,s=Z(e.profileId,a,o);return{status:200,body:d(s)}}i(le,"handleSetMetadata");function fe(t){const e=_(t.params.name),n=z(e.profileId),r=h(e.profileId).filter(a=>a.status==="active"||a.status==="idle");if(r.length===0)return{status:200,body:{profile_id:e.profileId,paused_at:n.manifest.paused_at}};const o=O();for(const a of r){const s=o.get(a.node_id);if(s!==void 0){o.interruptForProfilePause(a.node_id,s.pid);continue}a.pi_pid!=null&&L(a.pi_pid,a.pi_pid_identity)==="alive"&&o.interruptForProfilePause(a.node_id,a.pi_pid)}return{status:200,body:{profile_id:e.profileId,paused_at:n.manifest.paused_at}}}i(fe,"handlePause");function pe(t){const e=_(t.params.name),n=X(e.profileId);for(const r of h(e.profileId))(r.status==="active"||r.status==="idle"||D(r.node_id)!==null)&&ee.markMail(r.node_id);if(n.pausedAt!==null){const r=Date.parse(n.pausedAt);if(!Number.isNaN(r)){const o=Math.max(0,Date.now()-r);k(e.profileId,o);for(const a of h(e.profileId))a.status!=="dead"&&q(N(a.node_id),o)}}return{status:200,body:{profile_id:e.profileId,paused_at:n.manifest.paused_at}}}i(pe,"handleResume");function j(t){const e=t.principal;if(e.class==="person")return u();const n=te(e);return u().filter(({profileId:r,manifest:o})=>{const a=o.grantee??"app:terminal";if(a===b(e))return!0;const s=`crtr:memory:rw:${a}:profile:${r}`;return P(n,s)&&(e.class!=="broker"||P(e.scopes,s))})}i(j,"visibleProfiles");function A(t,e){const n=j(t),r=n.find(({profileId:a})=>a===e),o=r?[r]:n.filter(({manifest:a})=>a.name===e);if(o.length===0)throw new p(404,"not_found","profile not found");if(o.length>1)throw new p(400,"ambiguous","profile name matches multiple visible profiles; use an exact id");return o[0]}i(A,"requireUsableProfile");function me(t){return{status:200,body:j(t).map(d)}}i(me,"handleList");function ue(t){return{status:200,body:d(A(t,t.params.name))}}i(ue,"handleGet");async function ce(t){return x(f(t,t.params.name).profileId,t.body)}i(ce,"handleDelete");const Ve=[{method:"GET",pattern:"/v1/apps/self/env",handler:i(t=>({status:200,body:{names:G(m(t))}}),"handler")},{method:"PUT",pattern:"/v1/apps/self/env/:var",handler:i(t=>{const e=c(t),{value:n}=t.body??{};if(typeof n!="string"||!n)throw l("a non-empty env value is required",{field:"value"});return{status:200,body:{changed:B(m(t),e,n)}}},"handler")},{method:"DELETE",pattern:"/v1/apps/self/env/:var",handler:i(t=>({status:200,body:{changed:U(m(t),c(t))}}),"handler")},{method:"PUT",pattern:"/v1/profiles/:name",handler:de},{method:"POST",pattern:"/v1/profiles/:name/pause",ownerOnly:!0,handler:fe},{method:"POST",pattern:"/v1/profiles/:name/resume",ownerOnly:!0,handler:pe},{method:"PATCH",pattern:"/v1/profiles/:name/metadata",handler:le},{method:"POST",pattern:"/v1/profiles",handler:re},{method:"PATCH",pattern:"/v1/profiles/:name",handler:ae},{method:"GET",pattern:"/v1/profiles/:name/env",handler:ie},{method:"PUT",pattern:"/v1/profiles/:name/env/:var",handler:oe},{method:"DELETE",pattern:"/v1/profiles/:name/env/:var",handler:se},{method:"DELETE",pattern:"/v1/profiles/:name",handler:ce},{method:"GET",pattern:"/v1/profiles",handler:me},{method:"GET",pattern:"/v1/profiles/:name",handler:ue}];export{Ve as profileRoutes,ne as renameProfileAndHandle,A as requireUsableProfile};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var E=Object.defineProperty;var s=(e,r)=>E(e,"name",{value:r,configurable:!0});import{randomUUID as P}from"node:crypto";import{readConfig as I}from"../../../core/config.js";import{activeGrantForApp as R,localGrants as
|
|
1
|
+
var E=Object.defineProperty;var s=(e,r)=>E(e,"name",{value:r,configurable:!0});import{randomUUID as P}from"node:crypto";import{readConfig as I}from"../../../core/config.js";import{activeGrantForApp as R,localGrants as h}from"../../../core/grants/mirror.js";import{getNode as O}from"../../../core/canvas/canvas.js";import{scopeAllowed as $}from"../../../core/scopes.js";import{ProviderError as u,providerErrorBody as q,scopeMissing as x}from"../../../core/providers/errors.js";import{callProvider as G,providerTools as N}from"../../../core/providers/call.js";import{providerIdsFromGrants as T,providerInstallState as F}from"../../../core/providers/bundles.js";import{listInstalledPlugins as j}from"../../../core/resolver.js";import{listAudit as C,writeProviderAudit as D}from"../../../core/providers/audit.js";import{emitEvent as _}from"../../../core/events/emit.js";import{resolvedScopes as w}from"../router.js";const fe=new Set(["provider.tools","provider.call","audit.list"]);function M(e){if(e.class==="forwarded"||e.class==="machine")throw new u("permission_error","this operation is not available to the caller");if(e.class==="person")return{class:"person",sub:null,grantee:null,client_id:null,resolved:null,nodeScopes:null,run_id:null,node_id:null};if(e.class==="app"){const r=R(e.app);if(!r)throw new u("grant_revoked",`app ${e.app} has no active grant`);return{class:"app",sub:r.sub,grantee:e.app,client_id:null,resolved:r.resolved,nodeScopes:e.scopes,run_id:null,node_id:null}}return e.class==="cron"?{class:"app",sub:e.sub,grantee:e.app,client_id:null,resolved:w(e),nodeScopes:e.scopes,run_id:e.origin_run,node_id:null}:{class:"broker",sub:e.sub,grantee:e.app,client_id:e.client_id,resolved:w(e),nodeScopes:e.scopes,run_id:e.run??O(e.node)?.run_id??null,node_id:e.node}}s(M,"callerFromRequest");function ce(e){return{class:"app",sub:e.sub,grantee:e.grantee,client_id:e.client_id,resolved:e.resolved,nodeScopes:null,run_id:null,node_id:null}}s(ce,"callerFromApp");const U=/^([A-Za-z0-9_-]{1,64}):([A-Za-z0-9_-]{1,64})$/;function k(e){const r=U.exec(e);return r!==null&&r[1]!=="crtr"}s(k,"isProviderScope");const g=new WeakMap;function z(e){let r=g.get(e);return r===void 0&&(r=new Set(e),g.set(e,r)),r}s(z,"heldSet");function y(e,r){return e===null?!0:k(r)?z(e).has(r):$(e,r)}s(y,"holds");function S(e,r){return e.class==="person"?!0:y(e.resolved??[],r)&&y(e.nodeScopes,r)}s(S,"callerAllows");function pe(e,r,t){const n=`${r}:${t}`;if(!S(e,n))throw x(n)}s(pe,"requireGroup");function L(){return!!I("user").runtime?.issuer}s(L,"providerOperationsEnabled");const V=/^[A-Za-z0-9_-]{1,64}$/;function p(e,r){return new u("invalid_request",e,{param:r})}s(p,"invalid");function A(e){if(typeof e!="string"||!V.test(e)||e==="crtr")throw p("provider must be a provider id","provider");return e}s(A,"parseProvider");function Z(e){if(!e||typeof e!="object"||Array.isArray(e))throw new u("invalid_request","a JSON object is required");const r=e,t=A(r.provider),n=r.tool;if(typeof n!="string"||!n.trim())throw p("tool must be a non-empty string","tool");const i=r.arguments??{};if(!i||typeof i!="object"||Array.isArray(i))throw p("arguments must be an object","arguments");const a=r.version;if(a!==void 0&&(typeof a!="number"||!Number.isInteger(a)||a<1))throw p("version must be an integer >= 1","version");const o=r.approval;if(o!==void 0&&(typeof o!="string"||!o))throw p("approval must be a question id","approval");return{provider:t,tool:n.trim(),arguments:i,...a===void 0?{}:{version:a},...o===void 0?{}:{approval:o}}}s(Z,"parseCallInput");function B(e,r=new URLSearchParams){const t=s((o,f,c)=>{const l=r.get(o);if(l===null)return f;if(!/^\d+$/.test(l)||Number(l)>c||Number(l)<1)throw p(`invalid ${o}`,o);return Number(l)},"numeric"),n=r.has("after")?t("after",0,Number.MAX_SAFE_INTEGER):void 0,i=t("limit",100,1e3),a=Object.fromEntries(["operation","outcome","run_id","since","until"].filter(o=>r.has(o)).map(o=>[o,r.get(o)]));return{status:200,body:C(e.class==="person"?null:e.grantee,{after:n,limit:i,...a})}}s(B,"auditList");async function H(e,r,t){const n=performance.now(),i=new Set(j("user").filter(d=>d.enabled&&d.manifest.provider?.id===d.name).map(d=>d.name)),a=T(h()),o=[...new Set([...i,...a])].sort();if(r!==void 0&&!o.includes(r))throw new u("not_found",`provider "${r}" is not available`);const f=r===void 0?o:[r],c=e.class==="person"?h().flatMap(d=>d.status==="active"?d.resolved_scopes.map(({scope:v})=>v):[]):e.resolved??[],l=await Promise.all(f.map(async d=>{if(!c.some(m=>m.startsWith(`${d}:`)&&S(e,m)))return null;if(i.has(d)){const m=await N(e,d);return m.groups.length>0?m:null}const b=F(d);return{provider:d,display_name:d,status:b.status,...b.error?{error:b.error}:{},groups:[],commands:[]}})).then(d=>d.filter(v=>v!==null));if(_({level:"debug",event:"api.provider.tools",duration_ms:performance.now()-n,fields:{caller:e.class,provider:r??null,providers:l.length}}),r!==void 0){if(l.length===0)throw new u("not_found",`provider "${r}" is not available`);return{status:200,body:l[0]}}return{status:200,body:{providers:l}}}s(H,"providerTools");async function W(e,r,t){return G(e,r,t)}s(W,"providerCall");async function J(e,r,t,n){if(!L())throw new u("not_found","provider operations need a directory-connected runtime");if(e==="audit.list")return B(r,t.query);if(e==="provider.tools")return H(r,t.params.provider===void 0?void 0:A(t.params.provider),n);if(e==="provider.call"){let i;try{i=Z(t.body)}catch(a){const o=t.body&&typeof t.body=="object"&&!Array.isArray(t.body)?t.body:{};throw D({request_id:n.requestId,caller:r,provider:typeof o.provider=="string"?o.provider:"",tool:typeof o.tool=="string"?o.tool:"",outcome:`refused:${a instanceof u?a.code:"invalid_request"}`}),a}return W(r,i,n)}throw new u("not_found","unknown operation")}s(J,"handleProviderOperation");function X(e){const r=new AbortController,t=s(()=>{e.writableFinished||r.abort()},"abort");return e.on("close",t),{signal:r.signal,release:s(()=>e.off("close",t),"release")}}s(X,"abortOnClose");function K(e,r,t,n){const i=q(e,r,t,n??void 0);return i.status>=500&&!(e instanceof u)&&_({event:"api.provider.failed",level:"error",error:e instanceof Error?e:new Error(String(e)),fields:{request_id:r}}),i}s(K,"providerFailure");const me=[{method:"GET",pattern:"/v1/audit",name:"audit.list"},{method:"GET",pattern:"/v1/providers/tools",name:"provider.tools"},{method:"GET",pattern:"/v1/providers/:provider/tools",name:"provider.tools"},{method:"POST",pattern:"/v1/provider/call",name:"provider.call"}].map(({method:e,pattern:r,name:t})=>({method:e,pattern:r,handler:s(async n=>{const i=P(),{signal:a,release:o}=X(n.res);let f=null;try{return f=M(n.principal),{...await J(t,f,{params:n.params,body:n.body,query:new URL(n.req.url??"/","http://runtime.local").searchParams},{requestId:i,signal:a}),headers:{"Request-Id":i}}}catch(c){return K(c,i,!1,f?.run_id)}finally{o()}},"handler")}));export{fe as PROVIDER_OPERATIONS,X as abortOnClose,S as callerAllows,ce as callerFromApp,M as callerFromRequest,J as handleProviderOperation,Z as parseCallInput,A as parseProvider,K as providerFailure,L as providerOperationsEnabled,me as providerRoutes,pe as requireGroup};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Scope } from '@north-light/identity';
|
|
2
|
-
export type CallerClass = 'anonymous' | 'person' | 'app' | 'broker' | 'cron' | 'directory';
|
|
2
|
+
export type CallerClass = 'anonymous' | 'person' | 'app' | 'broker' | 'cron' | 'directory' | 'forwarded' | 'machine';
|
|
3
3
|
export type ResourceRule = 'none' | 'node-read' | 'node-write' | 'node-own' | 'nodes-list' | 'canvas-read' | 'cron' | 'profile' | 'human' | 'run' | 'daemon-bash' | 'objects';
|
|
4
4
|
export interface Operation {
|
|
5
5
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var n=Object.defineProperty;var r=(e,s)=>n(e,"name",{value:s,configurable:!0});const a=[{name:"health",method:"GET",path:"/v1/health",classes:["anonymous"],resource:"none",stage:"v0.5"},{name:"chat-inventory.get.1",method:"GET",path:"/v1/nodes/:id/chat-inventory",classes:["person","broker","cron"],resource:"node-read"},{name:"model-config.put.2",method:"PUT",path:"/v1/model-config",classes:["person","broker"],resource:"none"},{name:"files.get.3",method:"GET",path:"/v1/files/peek",classes:["person","broker"],resource:"none"},{name:"files.post.4",method:"POST",path:"/v1/files/write",classes:["person","broker"],resource:"none"},{name:"files.get.5",method:"GET",path:"/v1/files/list",classes:["person","broker"],resource:"none"},{name:"reviews.post.6",method:"POST",path:"/v1/human/reviews",classes:["person","broker"],resource:"human",scope:"crtr:act"},{name:"reviews.get.7",method:"GET",path:"/v1/human/reviews",classes:["person","broker"],resource:"human"},{name:"reviews.get.8",method:"GET",path:"/v1/human/reviews/:review_id",classes:["person","broker"],resource:"human"},{name:"reviews.post.9",method:"POST",path:"/v1/human/reviews/:review_id/submit",classes:["person","broker"],resource:"human"},{name:"reviews.post.10",method:"POST",path:"/v1/human/reviews/:review_id/cancel",classes:["person","broker"],resource:"human"},{name:"reviews.get.11",method:"GET",path:"/v1/human/reviews/:review_id/document",classes:["person","broker"],resource:"human"},{name:"feedback-comments.post.12",method:"POST",path:"/v1/human/inbox/:ticket_id/feedback-comments",classes:["person","broker"],resource:"human"},{name:"feedback-comments.post.13",method:"POST",path:"/v1/human/inbox/:ticket_id/feedback-comments/:comment_id/resolve",classes:["person","broker"],resource:"human"},{name:"node.log.append",method:"POST",path:"/v1/nodes/:id/records/log",classes:["person","broker"],resource:"node-own"},{name:"node.telemetry.put",method:"PUT",path:"/v1/nodes/:id/records/telemetry",classes:["person","broker"],resource:"node-own"},{name:"node.recap.put",method:"PUT",path:"/v1/nodes/:id/records/recap",classes:["person","broker"],resource:"node-own"},{name:"node.inbox.read",method:"GET",path:"/v1/nodes/:id/records/inbox",classes:["person","broker"],resource:"node-own"},{name:"node.passive.read",method:"GET",path:"/v1/nodes/:id/records/passive",classes:["person","broker"],resource:"node-own"},{name:"node.pushed-final",method:"POST",path:"/v1/nodes/:id/records/pushed-final",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.14",method:"POST",path:"/v1/nodes/:id/broker/session-bound",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.15",method:"POST",path:"/v1/nodes/:id/broker/settle",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.16",method:"POST",path:"/v1/nodes/:id/broker/park-complete",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.17",method:"POST",path:"/v1/nodes/:id/broker/park-activity",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.18",method:"POST",path:"/v1/nodes/:id/broker/telemetry",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.19",method:"POST",path:"/v1/nodes/:id/broker/model",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.get.20",method:"GET",path:"/v1/nodes/:id/broker/extension-state",classes:["person","broker"],resource:"node-own"},{name:"broker.signals",method:"GET",path:"/v1/nodes/:id/broker/signals",classes:["broker"],resource:"node-own",stream:!0},{name:"broker-ops.post.21",method:"POST",path:"/v1/nodes/:id/broker/generated-name",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.22",method:"POST",path:"/v1/nodes/:id/broker/persona-ack",classes:["person","broker"],resource:"node-own"},{name:"objects.read",method:"GET",path:"/v1/objects/:ref",classes:["person","app","broker","cron"],resource:"objects"},{name:"objects.list",method:"GET",path:"/v1/objects",classes:["person","app","broker","cron"],resource:"objects"},{name:"objects.search",method:"POST",path:"/v1/objects/search",classes:["person","app","broker","cron"],resource:"objects"},{name:"objects.watch",method:"POST",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"objects.unwatch",method:"DELETE",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"custom-objects.register",method:"POST",path:"/v1/custom-objects",classes:["person","app","broker","cron"],resource:"objects"},{name:"custom-objects.publish",method:"POST",path:"/v1/custom-objects/:ref/events",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"custom-objects.unregister",method:"DELETE",path:"/v1/custom-objects/:ref",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"custom-objects.receive",method:"GET",path:"/v1/custom-objects/:ref/deliveries",classes:["anonymous","person","app","broker","cron"],resource:"objects",stream:!0},{name:"custom-objects.ack",method:"POST",path:"/v1/custom-objects/:ref/deliveries/ack",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"objects.edges",method:"GET",path:"/v1/objects/:ref/edges",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.write",method:"POST",path:"/v1/docs",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.edit",method:"PATCH",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.move",method:"POST",path:"/v1/docs/:ref/move",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.delete",method:"DELETE",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.history",method:"GET",path:"/v1/docs/:ref/history",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.lint",method:"POST",path:"/v1/docs/lint",classes:["person","app","broker","cron"],resource:"objects"},{name:"documents.reconcile-packages",method:"POST",path:"/v1/documents/reconcile-packages",classes:["person","broker"],resource:"none"},{name:"nodes.delivery",method:"POST",path:"/v1/nodes/:id/delivery",classes:["person","broker"],resource:"node-own"},{name:"delivery.dry-run",method:"POST",path:"/v1/delivery/dry-run",classes:["person","broker"],resource:"none"},{name:"bash-jobs.background",method:"POST",path:"/v1/nodes/:id/jobs/:jobId/background",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"health.get.33",method:"GET",path:"/healthz",classes:["anonymous"],resource:"none"},{name:"health.get.34",method:"GET",path:"/v1/status",classes:["person","broker"],resource:"none"},{name:"daemon.due",method:"GET",path:"/v1/due",classes:["person","broker"],resource:"none"},{name:"bash-jobs.start",method:"POST",path:"/v1/nodes/:id/jobs/start",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"hooks.plan",method:"GET",path:"/v1/nodes/:id/hooks/plan",classes:["broker"],resource:"node-own"},{name:"hooks.exec",method:"POST",path:"/v1/nodes/:id/hooks/exec",classes:["broker"],resource:"node-own"},{name:"hooks.exec.person",method:"POST",path:"/v1/hooks/exec",classes:["person","broker"],resource:"none"},{name:"bash-jobs.get.35",method:"GET",path:"/v1/nodes/:id/jobs",classes:["person","broker","cron"],resource:"node-read"},{name:"bash-jobs.delete.36",method:"DELETE",path:"/v1/nodes/:id/jobs/:jobId",classes:["person","broker"],resource:"node-write"},{name:"prospective-chat-inventory.get.37",method:"GET",path:"/v1/prospective-chat-inventory",classes:["person","broker"],resource:"none"},{name:"node-events.get.38",method:"GET",path:"/v1/nodes/:id/events",classes:["person","broker","cron"],resource:"node-read"},{name:"bash.post.39",method:"POST",path:"/v1/bash",classes:["person","broker"],resource:"daemon-bash",scope:"crtr:act"},{name:"subscriptions.post.40",method:"POST",path:"/v1/nodes/:id/subscriptions",classes:["person","broker"],resource:"node-write"},{name:"subscriptions.delete.41",method:"DELETE",path:"/v1/nodes/:id/subscriptions/:target",classes:["person","broker"],resource:"node-write"},{name:"attach.post.42",method:"POST",path:"/v1/nodes/:id/attach",classes:["person","broker"],resource:"node-write"},{name:"review-comments.post.44",method:"POST",path:"/v1/human/reviews/self/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.45",method:"GET",path:"/v1/human/reviews/self/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.post.46",method:"POST",path:"/v1/human/reviews/:review_id/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.47",method:"GET",path:"/v1/human/reviews/:review_id/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.48",method:"GET",path:"/v1/human/reviews/:review_id/comment-events",classes:["person","broker"],resource:"human"},{name:"review-comments.post.49",method:"POST",path:"/v1/human/reviews/:review_id/comment-ranges",classes:["person","broker"],resource:"human"},{name:"review-comments.get.50",method:"GET",path:"/v1/human/comments/:comment_id",classes:["person","broker"],resource:"human"},{name:"review-comments.post.51",method:"POST",path:"/v1/human/comments/:comment_id/edit",classes:["person","broker"],resource:"human"},{name:"review-comments.post.52",method:"POST",path:"/v1/human/comments/:comment_id/resolve",classes:["person","broker"],resource:"human"},{name:"review-comments.post.53",method:"POST",path:"/v1/human/comments/:comment_id/reopen",classes:["person","broker"],resource:"human"},{name:"review-comments.post.54",method:"POST",path:"/v1/human/comments/:comment_id/delete",classes:["person","broker"],resource:"human"},{name:"review-comments.post.55",method:"POST",path:"/v1/human/comments/:comment_id/fork",classes:["person","broker"],resource:"human"},{name:"messages.post.56",method:"POST",path:"/v1/nodes/:id/mail/claim",classes:["person","broker"],resource:"node-own"},{name:"messages.post.57",method:"POST",path:"/v1/nodes/:id/mail/acknowledge",classes:["person","broker"],resource:"node-own"},{name:"messages.post.58",method:"POST",path:"/v1/nodes/:id/messages",classes:["person","broker","cron"],resource:"node-write"},{name:"messages.post.59",method:"POST",path:"/v1/nodes/:id/interrupt",classes:["person","broker","cron"],resource:"node-write"},{name:"reports.post.60",method:"POST",path:"/v1/nodes/:id/reports",classes:["person","broker"],resource:"node-own"},{name:"reports.get.61",method:"GET",path:"/v1/nodes/:id/reports",classes:["person","broker","cron"],resource:"node-read"},{name:"reports.post.62",method:"POST",path:"/v1/nodes/:id/result",classes:["person","broker"],resource:"node-own"},{name:"inbox.get.63",method:"GET",path:"/v1/human/inbox",classes:["person","broker"],resource:"human"},{name:"inbox.get.64",method:"GET",path:"/v1/human/inbox/history",classes:["person","broker"],resource:"human"},{name:"inbox.get.65",method:"GET",path:"/v1/human/inbox/:ticket_id",classes:["person","broker"],resource:"human"},{name:"inbox.get.66",method:"GET",path:"/v1/human/inbox/:ticket_id/response",classes:["person","broker"],resource:"human"},{name:"inbox.post.67",method:"POST",path:"/v1/human/inbox/:ticket_id/respond",classes:["person","broker"],resource:"human"},{name:"inbox.post.68",method:"POST",path:"/v1/human/inbox/:ticket_id/progress",classes:["person","broker"],resource:"human"},{name:"inbox.post.69",method:"POST",path:"/v1/human/inbox/:ticket_id/cancel",classes:["person","broker"],resource:"human"},{name:"worktree.post.70",method:"POST",path:"/v1/nodes/:id/worktree/close",classes:["person","broker"],resource:"node-write"},{name:"worktree.post.71",method:"POST",path:"/v1/nodes/:id/worktree/abandon",classes:["person","broker"],resource:"node-write"},{name:"worktree.get.72",method:"GET",path:"/v1/worktrees/quarantined",classes:["person","broker"],resource:"none"},{name:"crons.post.73",method:"POST",path:"/v1/crons",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.get.74",method:"GET",path:"/v1/crons",classes:["person","app","broker","cron"],resource:"cron"},{name:"crons.get.75",method:"GET",path:"/v1/crons/:cronId",classes:["person","app","broker","cron"],resource:"cron"},{name:"crons.post.76",method:"POST",path:"/v1/crons/:cronId/pause",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.77",method:"POST",path:"/v1/crons/:cronId/resume",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.78",method:"POST",path:"/v1/crons/poke",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.79",method:"POST",path:"/v1/crons/:cronId/run",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.delete.80",method:"DELETE",path:"/v1/crons/:cronId",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"modelauth.get.81",method:"GET",path:"/v1/model-auth",classes:["person","broker"],resource:"none"},{name:"modelauth.get.82",method:"GET",path:"/v1/model-auth/readiness",classes:["person","broker"],resource:"none"},{name:"modelauth.put.83",method:"PUT",path:"/v1/model-auth/:provider",classes:["person","broker"],resource:"none"},{name:"modelauth.delete.84",method:"DELETE",path:"/v1/model-auth/:provider",classes:["person","broker"],resource:"none"},{name:"model_auth.start",method:"POST",path:"/v1/model-auth/flows",classes:["person","broker"],resource:"none"},{name:"model_auth.complete",method:"POST",path:"/v1/model-auth/flows/:flow_id/complete",classes:["person","broker"],resource:"none"},{name:"model_auth.cancel",method:"POST",path:"/v1/model-auth/flows/:flow_id/cancel",classes:["person","broker"],resource:"none"},{name:"model_auth.get",method:"GET",path:"/v1/model-auth/flows/:flow_id",classes:["person","broker"],resource:"none"},{name:"nodes.post.85",method:"POST",path:"/v1/nodes",classes:["person","broker","cron"],resource:"node-own",scope:"crtr:act"},{name:"nodes.get.86",method:"GET",path:"/v1/nodes",classes:["person","broker"],resource:"nodes-list"},{name:"nodes.post.87",method:"POST",path:"/v1/nodes/revive-all",classes:["person","broker"],resource:"none"},{name:"nodes.get.88",method:"GET",path:"/v1/nodes/:id",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.89",method:"GET",path:"/v1/nodes/:id/snapshot",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.90",method:"GET",path:"/v1/nodes/:id/subject",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.91",method:"GET",path:"/v1/nodes/:id/messages",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.92",method:"GET",path:"/v1/nodes/:id/session",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.93",method:"GET",path:"/v1/nodes/:id/transcript",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.94",method:"GET",path:"/v1/nodes/:id/context",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.post.96",method:"POST",path:"/v1/nodes/:id/fork",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.97",method:"POST",path:"/v1/nodes/:id/revive",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.98",method:"POST",path:"/v1/nodes/:id/relaunch-root",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.99",method:"POST",path:"/v1/nodes/:id/close",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.100",method:"POST",path:"/v1/nodes/:id/recycle",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.101",method:"POST",path:"/v1/nodes/:id/demote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.102",method:"POST",path:"/v1/nodes/:id/promote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.103",method:"POST",path:"/v1/nodes/:id/yield",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.104",method:"POST",path:"/v1/nodes/:id/wait",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.patch.105",method:"PATCH",path:"/v1/nodes/:id/config",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"broker-recovery.post.106",method:"POST",path:"/v1/broker/:id/turn",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.107",method:"POST",path:"/v1/broker/:id/provider-retry",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.108",method:"POST",path:"/v1/broker/:id/fault",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.get.109",method:"GET",path:"/v1/broker/:id/recovery",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.110",method:"POST",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"broker-recovery.delete.111",method:"DELETE",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"profiles.put.112",method:"PUT",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profiles.post.113",method:"POST",path:"/v1/profiles/:name/pause",classes:["person","broker"],resource:"profile"},{name:"profiles.post.114",method:"POST",path:"/v1/profiles/:name/resume",classes:["person","broker"],resource:"profile"},{name:"profiles.patch.115",method:"PATCH",path:"/v1/profiles/:name/metadata",classes:["person","app","broker"],resource:"profile"},{name:"profile.create",method:"POST",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile"},{name:"profile.update",method:"PATCH",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"app.env.list",method:"GET",path:"/v1/apps/self/env",classes:["person","app","broker"],resource:"profile"},{name:"app.env.set",method:"PUT",path:"/v1/apps/self/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"app.env.remove",method:"DELETE",path:"/v1/apps/self/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.list",method:"GET",path:"/v1/profiles/:name/env",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.set",method:"PUT",path:"/v1/profiles/:name/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.remove",method:"DELETE",path:"/v1/profiles/:name/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profiles.delete.116",method:"DELETE",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profile.list",method:"GET",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile",stage:"chat"},{name:"profiles.get.118",method:"GET",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"node-outcomes.get.119",method:"GET",path:"/v1/nodes/:id/outcome",classes:["person","broker","cron"],resource:"node-read"},{name:"node-outcomes.put.120",method:"PUT",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"node-outcomes.get.121",method:"GET",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker","cron"],resource:"node-read"},{name:"node-outcomes.delete.122",method:"DELETE",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"canvas.get.123",method:"GET",path:"/v1/canvas/attention",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.124",method:"POST",path:"/v1/canvas/attention/counts",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.125",method:"POST",path:"/v1/canvas/history/search",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.126",method:"POST",path:"/v1/canvas/history/grep",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.127",method:"GET",path:"/v1/canvas/history/read",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.128",method:"POST",path:"/v1/canvas/history/stats",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.129",method:"GET",path:"/v1/canvas/snapshot",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.130",method:"GET",path:"/v1/canvas/roster",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.browse",method:"GET",path:"/v1/canvas/browse",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.analytics",method:"GET",path:"/v1/canvas/analytics",classes:["person","broker"],resource:"canvas-read"},{name:"memory-reads.post",method:"POST",path:"/v1/nodes/:id/memory-reads",classes:["person","broker"],resource:"node-own"},{name:"canvas.get.131",method:"GET",path:"/v1/canvas/graph",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.132",method:"POST",path:"/v1/canvas/prune",classes:["person","broker"],resource:"none"},{name:"daemon.post.133",method:"POST",path:"/v1/daemon/restart",classes:["person","broker"],resource:"none"},{name:"daemon.post.134",method:"POST",path:"/v1/daemon/migrate",classes:["person","broker"],resource:"none"},{name:"daemon.post.135",method:"POST",path:"/v1/daemon/admit",classes:["person","broker"],resource:"none"},{name:"human.components.list",method:"GET",path:"/v1/human/components",classes:["person","broker"],resource:"none"},{name:"human-requests.post.136",method:"POST",path:"/v1/human/requests",classes:["person","broker"],resource:"human",scope:"crtr:act"},{name:"human-requests.get.137",method:"GET",path:"/v1/human/requests/:request_id",classes:["person","broker"],resource:"human"},{name:"human-requests.post.138",method:"POST",path:"/v1/human/requests/:request_id/replace",classes:["person","broker"],resource:"human"},{name:"human-requests.post.139",method:"POST",path:"/v1/human/requests/:request_id/respond",classes:["person","broker"],resource:"human"},{name:"human-requests.post.140",method:"POST",path:"/v1/human/requests/:request_id/dismiss",classes:["person","broker"],resource:"human"},{name:"human-requests.post.141",method:"POST",path:"/v1/human/requests/:request_id/cancel",classes:["person","broker"],resource:"human"},{name:"focus.get.142",method:"GET",path:"/v1/focuses",classes:["person","broker"],resource:"none"},{name:"focus.post.143",method:"POST",path:"/v1/focuses",classes:["person","broker"],resource:"none"},{name:"focus.get.144",method:"GET",path:"/v1/focuses/by-node",classes:["person","broker"],resource:"none"},{name:"focus.get.145",method:"GET",path:"/v1/focuses/by-pane",classes:["person","broker"],resource:"none"},{name:"focus.patch.146",method:"PATCH",path:"/v1/focuses/:focus_id",classes:["person","broker"],resource:"none"},{name:"focus.delete.147",method:"DELETE",path:"/v1/focuses/:focus_id",classes:["person","broker"],resource:"none"},{name:"delivery.retry",method:"POST",path:"/v1/deliveries/:delivery_id/retry",classes:["person","broker"],resource:"none"},{name:"limits.show",method:"GET",path:"/v1/limits",classes:["person"],resource:"none"},{name:"limits.set",method:"PUT",path:"/v1/limits/apps/:app",classes:["person"],resource:"none"},{name:"limits.remove",method:"DELETE",path:"/v1/limits/apps/:app",classes:["person"],resource:"none"},{name:"space.list",method:"GET",path:"/v1/spaces",classes:["person","broker"],resource:"none"},{name:"kinds.list",method:"GET",path:"/v1/kinds",classes:["person","app","broker"],resource:"none"},{name:"grant.get",method:"GET",path:"/v1/grant",classes:["app"],resource:"none",stage:"v0.5"},{name:"usage.get",method:"GET",path:"/v1/usage",classes:["person","app","broker"],resource:"none",stage:"v1"},{name:"llm",method:"POST",path:"/v1/llm",classes:["app","person","broker"],scope:"crtr:llm",resource:"none",stage:"v1"},{name:"structured-request.create",method:"POST",path:"/v1/structured-requests",classes:["person","app","broker"],scope:"crtr:act",resource:"none"},{name:"structured-request.get",method:"GET",path:"/v1/structured-requests/:request_id",classes:["person","app","broker"],resource:"none"},{name:"structured-request.cancel",method:"POST",path:"/v1/structured-requests/:request_id/cancel",classes:["person","app","broker"],scope:"crtr:act",resource:"none"},{name:"run.start",method:"POST",path:"/v1/runs",classes:["app"],scope:"crtr:act",resource:"none",stage:"v0.5",idempotency:"24h"},{name:"run.list",method:"GET",path:"/v1/runs",classes:["app","person","broker","cron"],resource:"run",stage:"v0.5"},{name:"run.get",method:"GET",path:"/v1/runs/:run_id",classes:["app","person","broker","cron"],resource:"run",stage:"v0.5"},{name:"run.message",method:"POST",path:"/v1/runs/:run_id/messages",classes:["app","person","broker","cron"],scope:"crtr:act",resource:"run",stage:"v0.5",idempotency:"24h"},{name:"run.events",method:"GET",path:"/v1/runs/:run_id/events",classes:["app","person","broker","cron"],resource:"run",stage:"v0.5",stream:!0},{name:"run.interrupt",method:"POST",path:"/v1/runs/:run_id/interrupt",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.cancel",method:"POST",path:"/v1/runs/:run_id/cancel",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.delete",method:"DELETE",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.rename",method:"POST",path:"/v1/runs/:run_id/rename",classes:["app"],resource:"run",stage:"chat"},{name:"question.get",method:"GET",path:"/v1/questions/:question_id",classes:["app"],resource:"none",stage:"chat"},{name:"question.answer",method:"POST",path:"/v1/questions/:question_id/answer",classes:["app"],resource:"none",stage:"chat"},{name:"trace.get",method:"GET",path:"/v1/runs/:run_id/trace",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"upload.create",method:"POST",path:"/v1/uploads",classes:["app"],scope:"crtr:act",resource:"none",stage:"file-transfer"},{name:"attachment.link",method:"GET",path:"/v1/attachments/link",classes:["app"],resource:"none",stage:"file-transfer"},{name:"file.download",method:"GET",path:"/v1/files/download",classes:["app"],resource:"none",stage:"file-transfer",stream:"bytes"},{name:"share.create",method:"POST",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.list",method:"GET",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.delete",method:"DELETE",path:"/v1/shares/:share_id",classes:["app"],resource:"none",stage:"file-transfer"},{name:"memory.list",method:"GET",path:"/v1/memory",classes:["person","app","broker"],resource:"none",stage:"m13"},{name:"memory.get",method:"GET",path:"/v1/memory/document",classes:["person","app","broker"],resource:"none",stage:"m13"},{name:"audit.list",method:"GET",path:"/v1/audit",classes:["person","app"],resource:"none",stage:"v1"},{name:"provider.tools",method:"GET",path:"/v1/providers/tools",classes:["person","app","broker","cron"],resource:"none",stage:"v1"},{name:"provider.tools",method:"GET",path:"/v1/providers/:provider/tools",classes:["person","app","broker","cron"],resource:"none",stage:"v1"},{name:"provider.call",method:"POST",path:"/v1/provider/call",classes:["person","app","broker","cron"],resource:"none",stage:"v1"},{name:"runtime.sync-notice",method:"POST",path:"/v1/runtime/sync-notice",classes:["directory"],resource:"none",stage:"v1"},{name:"runtime.vendor-status",method:"GET",path:"/v1/runtime/vendor-status",classes:["directory"],resource:"none",stage:"v1"}];function c(e,s){return a.find(o=>o.method===e.toUpperCase()&&o.path===s)}r(c,"operationFor");export{a as OPERATIONS,c as operationFor};
|
|
1
|
+
var a=Object.defineProperty;var r=(e,s)=>a(e,"name",{value:s,configurable:!0});const n=[{name:"health",method:"GET",path:"/v1/health",classes:["anonymous"],resource:"none",stage:"v0.5"},{name:"chat-inventory.get.1",method:"GET",path:"/v1/nodes/:id/chat-inventory",classes:["person","broker","cron"],resource:"node-read"},{name:"model-config.put.2",method:"PUT",path:"/v1/model-config",classes:["person","broker"],resource:"none"},{name:"files.get.3",method:"GET",path:"/v1/files/peek",classes:["person","broker"],resource:"none"},{name:"files.post.4",method:"POST",path:"/v1/files/write",classes:["person","broker"],resource:"none"},{name:"files.get.5",method:"GET",path:"/v1/files/list",classes:["person","broker"],resource:"none"},{name:"reviews.post.6",method:"POST",path:"/v1/human/reviews",classes:["person","broker"],resource:"human",scope:"crtr:act"},{name:"reviews.get.7",method:"GET",path:"/v1/human/reviews",classes:["person","broker"],resource:"human"},{name:"reviews.get.8",method:"GET",path:"/v1/human/reviews/:review_id",classes:["person","broker"],resource:"human"},{name:"reviews.post.9",method:"POST",path:"/v1/human/reviews/:review_id/submit",classes:["person","broker"],resource:"human"},{name:"reviews.post.10",method:"POST",path:"/v1/human/reviews/:review_id/cancel",classes:["person","broker"],resource:"human"},{name:"reviews.get.11",method:"GET",path:"/v1/human/reviews/:review_id/document",classes:["person","broker"],resource:"human"},{name:"feedback-comments.post.12",method:"POST",path:"/v1/human/inbox/:ticket_id/feedback-comments",classes:["person","broker"],resource:"human"},{name:"feedback-comments.post.13",method:"POST",path:"/v1/human/inbox/:ticket_id/feedback-comments/:comment_id/resolve",classes:["person","broker"],resource:"human"},{name:"node.log.append",method:"POST",path:"/v1/nodes/:id/records/log",classes:["person","broker"],resource:"node-own"},{name:"node.telemetry.put",method:"PUT",path:"/v1/nodes/:id/records/telemetry",classes:["person","broker"],resource:"node-own"},{name:"node.recap.put",method:"PUT",path:"/v1/nodes/:id/records/recap",classes:["person","broker"],resource:"node-own"},{name:"node.inbox.read",method:"GET",path:"/v1/nodes/:id/records/inbox",classes:["person","broker"],resource:"node-own"},{name:"node.passive.read",method:"GET",path:"/v1/nodes/:id/records/passive",classes:["person","broker"],resource:"node-own"},{name:"node.pushed-final",method:"POST",path:"/v1/nodes/:id/records/pushed-final",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.14",method:"POST",path:"/v1/nodes/:id/broker/session-bound",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.15",method:"POST",path:"/v1/nodes/:id/broker/settle",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.16",method:"POST",path:"/v1/nodes/:id/broker/park-complete",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.17",method:"POST",path:"/v1/nodes/:id/broker/park-activity",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.18",method:"POST",path:"/v1/nodes/:id/broker/telemetry",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.19",method:"POST",path:"/v1/nodes/:id/broker/model",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.get.20",method:"GET",path:"/v1/nodes/:id/broker/extension-state",classes:["person","broker"],resource:"node-own"},{name:"broker.signals",method:"GET",path:"/v1/nodes/:id/broker/signals",classes:["broker"],resource:"node-own",stream:!0},{name:"broker-ops.post.21",method:"POST",path:"/v1/nodes/:id/broker/generated-name",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.22",method:"POST",path:"/v1/nodes/:id/broker/persona-ack",classes:["person","broker"],resource:"node-own"},{name:"objects.read",method:"GET",path:"/v1/objects/:ref",classes:["person","app","broker","cron","forwarded"],resource:"objects"},{name:"objects.list",method:"GET",path:"/v1/objects",classes:["person","app","broker","cron","forwarded"],resource:"objects"},{name:"objects.search",method:"POST",path:"/v1/objects/search",classes:["person","app","broker","cron"],resource:"objects"},{name:"objects.watch",method:"POST",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron","forwarded"],resource:"objects"},{name:"objects.unwatch",method:"DELETE",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron","forwarded"],resource:"objects"},{name:"custom-objects.register",method:"POST",path:"/v1/custom-objects",classes:["person","app","broker","cron"],resource:"objects"},{name:"custom-objects.publish",method:"POST",path:"/v1/custom-objects/:ref/events",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"custom-objects.unregister",method:"DELETE",path:"/v1/custom-objects/:ref",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"custom-objects.receive",method:"GET",path:"/v1/custom-objects/:ref/deliveries",classes:["anonymous","person","app","broker","cron"],resource:"objects",stream:!0},{name:"custom-objects.ack",method:"POST",path:"/v1/custom-objects/:ref/deliveries/ack",classes:["anonymous","person","app","broker","cron"],resource:"objects"},{name:"objects.edges",method:"GET",path:"/v1/objects/:ref/edges",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.write",method:"POST",path:"/v1/docs",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.edit",method:"PATCH",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.move",method:"POST",path:"/v1/docs/:ref/move",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.delete",method:"DELETE",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.history",method:"GET",path:"/v1/docs/:ref/history",classes:["person","app","broker","cron"],resource:"objects"},{name:"docs.lint",method:"POST",path:"/v1/docs/lint",classes:["person","app","broker","cron"],resource:"objects"},{name:"documents.reconcile-packages",method:"POST",path:"/v1/documents/reconcile-packages",classes:["person","broker"],resource:"none"},{name:"nodes.delivery",method:"POST",path:"/v1/nodes/:id/delivery",classes:["person","broker"],resource:"node-own"},{name:"delivery.dry-run",method:"POST",path:"/v1/delivery/dry-run",classes:["person","broker"],resource:"none"},{name:"bash-jobs.background",method:"POST",path:"/v1/nodes/:id/jobs/:jobId/background",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"health.get.33",method:"GET",path:"/healthz",classes:["anonymous"],resource:"none"},{name:"health.get.34",method:"GET",path:"/v1/status",classes:["person","broker"],resource:"none"},{name:"daemon.due",method:"GET",path:"/v1/due",classes:["person","broker"],resource:"none"},{name:"bash-jobs.start",method:"POST",path:"/v1/nodes/:id/jobs/start",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"hooks.plan",method:"GET",path:"/v1/nodes/:id/hooks/plan",classes:["broker"],resource:"node-own"},{name:"hooks.exec",method:"POST",path:"/v1/nodes/:id/hooks/exec",classes:["broker"],resource:"node-own"},{name:"hooks.exec.person",method:"POST",path:"/v1/hooks/exec",classes:["person","broker"],resource:"none"},{name:"bash-jobs.get.35",method:"GET",path:"/v1/nodes/:id/jobs",classes:["person","broker","cron"],resource:"node-read"},{name:"bash-jobs.delete.36",method:"DELETE",path:"/v1/nodes/:id/jobs/:jobId",classes:["person","broker"],resource:"node-write"},{name:"prospective-chat-inventory.get.37",method:"GET",path:"/v1/prospective-chat-inventory",classes:["person","broker"],resource:"none"},{name:"node-events.get.38",method:"GET",path:"/v1/nodes/:id/events",classes:["person","broker","cron"],resource:"node-read"},{name:"bash.post.39",method:"POST",path:"/v1/bash",classes:["person","broker"],resource:"daemon-bash",scope:"crtr:act"},{name:"subscriptions.post.40",method:"POST",path:"/v1/nodes/:id/subscriptions",classes:["person","broker"],resource:"node-write"},{name:"subscriptions.delete.41",method:"DELETE",path:"/v1/nodes/:id/subscriptions/:target",classes:["person","broker"],resource:"node-write"},{name:"attach.post.42",method:"POST",path:"/v1/nodes/:id/attach",classes:["person","broker"],resource:"node-write"},{name:"review-comments.post.44",method:"POST",path:"/v1/human/reviews/self/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.45",method:"GET",path:"/v1/human/reviews/self/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.post.46",method:"POST",path:"/v1/human/reviews/:review_id/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.47",method:"GET",path:"/v1/human/reviews/:review_id/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.48",method:"GET",path:"/v1/human/reviews/:review_id/comment-events",classes:["person","broker"],resource:"human"},{name:"review-comments.post.49",method:"POST",path:"/v1/human/reviews/:review_id/comment-ranges",classes:["person","broker"],resource:"human"},{name:"review-comments.get.50",method:"GET",path:"/v1/human/comments/:comment_id",classes:["person","broker"],resource:"human"},{name:"review-comments.post.51",method:"POST",path:"/v1/human/comments/:comment_id/edit",classes:["person","broker"],resource:"human"},{name:"review-comments.post.52",method:"POST",path:"/v1/human/comments/:comment_id/resolve",classes:["person","broker"],resource:"human"},{name:"review-comments.post.53",method:"POST",path:"/v1/human/comments/:comment_id/reopen",classes:["person","broker"],resource:"human"},{name:"review-comments.post.54",method:"POST",path:"/v1/human/comments/:comment_id/delete",classes:["person","broker"],resource:"human"},{name:"review-comments.post.55",method:"POST",path:"/v1/human/comments/:comment_id/fork",classes:["person","broker"],resource:"human"},{name:"messages.post.56",method:"POST",path:"/v1/nodes/:id/mail/claim",classes:["person","broker"],resource:"node-own"},{name:"messages.post.57",method:"POST",path:"/v1/nodes/:id/mail/acknowledge",classes:["person","broker"],resource:"node-own"},{name:"messages.post.58",method:"POST",path:"/v1/nodes/:id/messages",classes:["person","broker","cron","forwarded"],resource:"node-write"},{name:"messages.post.59",method:"POST",path:"/v1/nodes/:id/interrupt",classes:["person","broker","cron","forwarded"],resource:"node-write"},{name:"reports.post.60",method:"POST",path:"/v1/nodes/:id/reports",classes:["person","broker"],resource:"node-own"},{name:"reports.get.61",method:"GET",path:"/v1/nodes/:id/reports",classes:["person","broker","cron"],resource:"node-read"},{name:"reports.post.62",method:"POST",path:"/v1/nodes/:id/result",classes:["person","broker"],resource:"node-own"},{name:"inbox.get.63",method:"GET",path:"/v1/human/inbox",classes:["person","broker"],resource:"human"},{name:"inbox.get.64",method:"GET",path:"/v1/human/inbox/history",classes:["person","broker"],resource:"human"},{name:"inbox.get.65",method:"GET",path:"/v1/human/inbox/:ticket_id",classes:["person","broker"],resource:"human"},{name:"inbox.get.66",method:"GET",path:"/v1/human/inbox/:ticket_id/response",classes:["person","broker"],resource:"human"},{name:"inbox.post.67",method:"POST",path:"/v1/human/inbox/:ticket_id/respond",classes:["person","broker"],resource:"human"},{name:"inbox.post.68",method:"POST",path:"/v1/human/inbox/:ticket_id/progress",classes:["person","broker"],resource:"human"},{name:"inbox.post.69",method:"POST",path:"/v1/human/inbox/:ticket_id/cancel",classes:["person","broker"],resource:"human"},{name:"worktree.post.70",method:"POST",path:"/v1/nodes/:id/worktree/close",classes:["person","broker"],resource:"node-write"},{name:"worktree.post.71",method:"POST",path:"/v1/nodes/:id/worktree/abandon",classes:["person","broker"],resource:"node-write"},{name:"worktree.get.72",method:"GET",path:"/v1/worktrees/quarantined",classes:["person","broker"],resource:"none"},{name:"crons.post.73",method:"POST",path:"/v1/crons",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.get.74",method:"GET",path:"/v1/crons",classes:["person","app","broker","cron"],resource:"cron"},{name:"crons.get.75",method:"GET",path:"/v1/crons/:cronId",classes:["person","app","broker","cron"],resource:"cron"},{name:"crons.post.76",method:"POST",path:"/v1/crons/:cronId/pause",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.77",method:"POST",path:"/v1/crons/:cronId/resume",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.78",method:"POST",path:"/v1/crons/poke",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.79",method:"POST",path:"/v1/crons/:cronId/run",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"crons.delete.80",method:"DELETE",path:"/v1/crons/:cronId",classes:["person","app","broker","cron"],resource:"cron",scope:"crtr:schedule"},{name:"modelauth.get.81",method:"GET",path:"/v1/model-auth",classes:["person","broker"],resource:"none"},{name:"modelauth.get.82",method:"GET",path:"/v1/model-auth/readiness",classes:["person","broker"],resource:"none"},{name:"modelauth.put.83",method:"PUT",path:"/v1/model-auth/:provider",classes:["person","broker"],resource:"none"},{name:"modelauth.delete.84",method:"DELETE",path:"/v1/model-auth/:provider",classes:["person","broker"],resource:"none"},{name:"model_auth.start",method:"POST",path:"/v1/model-auth/flows",classes:["person","broker"],resource:"none"},{name:"model_auth.complete",method:"POST",path:"/v1/model-auth/flows/:flow_id/complete",classes:["person","broker"],resource:"none"},{name:"model_auth.cancel",method:"POST",path:"/v1/model-auth/flows/:flow_id/cancel",classes:["person","broker"],resource:"none"},{name:"model_auth.get",method:"GET",path:"/v1/model-auth/flows/:flow_id",classes:["person","broker"],resource:"none"},{name:"nodes.post.85",method:"POST",path:"/v1/nodes",classes:["person","broker","cron"],resource:"node-own",scope:"crtr:act"},{name:"nodes.get.86",method:"GET",path:"/v1/nodes",classes:["person","broker"],resource:"nodes-list"},{name:"nodes.post.87",method:"POST",path:"/v1/nodes/revive-all",classes:["person","broker"],resource:"none"},{name:"nodes.get.88",method:"GET",path:"/v1/nodes/:id",classes:["person","broker","cron","forwarded"],resource:"node-read"},{name:"nodes.get.89",method:"GET",path:"/v1/nodes/:id/snapshot",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.90",method:"GET",path:"/v1/nodes/:id/subject",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.91",method:"GET",path:"/v1/nodes/:id/messages",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.92",method:"GET",path:"/v1/nodes/:id/session",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.93",method:"GET",path:"/v1/nodes/:id/transcript",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.get.94",method:"GET",path:"/v1/nodes/:id/context",classes:["person","broker","cron"],resource:"node-read"},{name:"nodes.post.96",method:"POST",path:"/v1/nodes/:id/fork",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.97",method:"POST",path:"/v1/nodes/:id/revive",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.98",method:"POST",path:"/v1/nodes/:id/relaunch-root",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.99",method:"POST",path:"/v1/nodes/:id/close",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.100",method:"POST",path:"/v1/nodes/:id/recycle",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.101",method:"POST",path:"/v1/nodes/:id/demote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.102",method:"POST",path:"/v1/nodes/:id/promote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.103",method:"POST",path:"/v1/nodes/:id/yield",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.104",method:"POST",path:"/v1/nodes/:id/wait",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.patch.105",method:"PATCH",path:"/v1/nodes/:id/config",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"broker-recovery.post.106",method:"POST",path:"/v1/broker/:id/turn",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.107",method:"POST",path:"/v1/broker/:id/provider-retry",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.108",method:"POST",path:"/v1/broker/:id/fault",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.get.109",method:"GET",path:"/v1/broker/:id/recovery",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.110",method:"POST",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"broker-recovery.delete.111",method:"DELETE",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"profiles.put.112",method:"PUT",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profiles.post.113",method:"POST",path:"/v1/profiles/:name/pause",classes:["person","broker"],resource:"profile"},{name:"profiles.post.114",method:"POST",path:"/v1/profiles/:name/resume",classes:["person","broker"],resource:"profile"},{name:"profiles.patch.115",method:"PATCH",path:"/v1/profiles/:name/metadata",classes:["person","app","broker"],resource:"profile"},{name:"profile.create",method:"POST",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile"},{name:"profile.update",method:"PATCH",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"app.env.list",method:"GET",path:"/v1/apps/self/env",classes:["person","app","broker"],resource:"profile"},{name:"app.env.set",method:"PUT",path:"/v1/apps/self/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"app.env.remove",method:"DELETE",path:"/v1/apps/self/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.list",method:"GET",path:"/v1/profiles/:name/env",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.set",method:"PUT",path:"/v1/profiles/:name/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.remove",method:"DELETE",path:"/v1/profiles/:name/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profiles.delete.116",method:"DELETE",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profile.list",method:"GET",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile",stage:"chat"},{name:"profiles.get.118",method:"GET",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"node-outcomes.get.119",method:"GET",path:"/v1/nodes/:id/outcome",classes:["person","broker","cron"],resource:"node-read"},{name:"node-outcomes.put.120",method:"PUT",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"node-outcomes.get.121",method:"GET",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker","cron"],resource:"node-read"},{name:"node-outcomes.delete.122",method:"DELETE",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"canvas.get.123",method:"GET",path:"/v1/canvas/attention",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.post.124",method:"POST",path:"/v1/canvas/attention/counts",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.post.125",method:"POST",path:"/v1/canvas/history/search",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.post.126",method:"POST",path:"/v1/canvas/history/grep",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.get.127",method:"GET",path:"/v1/canvas/history/read",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.post.128",method:"POST",path:"/v1/canvas/history/stats",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.get.129",method:"GET",path:"/v1/canvas/snapshot",classes:["person","broker","forwarded"],resource:"canvas-read"},{name:"canvas.get.130",method:"GET",path:"/v1/canvas/roster",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.browse",method:"GET",path:"/v1/canvas/browse",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.analytics",method:"GET",path:"/v1/canvas/analytics",classes:["person","broker"],resource:"canvas-read"},{name:"memory-reads.post",method:"POST",path:"/v1/nodes/:id/memory-reads",classes:["person","broker"],resource:"node-own"},{name:"canvas.get.131",method:"GET",path:"/v1/canvas/graph",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.132",method:"POST",path:"/v1/canvas/prune",classes:["person","broker"],resource:"none"},{name:"daemon.post.133",method:"POST",path:"/v1/daemon/restart",classes:["person","broker"],resource:"none"},{name:"daemon.post.134",method:"POST",path:"/v1/daemon/migrate",classes:["person","broker"],resource:"none"},{name:"daemon.post.135",method:"POST",path:"/v1/daemon/admit",classes:["person","broker"],resource:"none"},{name:"human.components.list",method:"GET",path:"/v1/human/components",classes:["person","broker"],resource:"none"},{name:"human-requests.post.136",method:"POST",path:"/v1/human/requests",classes:["person","broker"],resource:"human",scope:"crtr:act"},{name:"human-requests.get.137",method:"GET",path:"/v1/human/requests/:request_id",classes:["person","broker"],resource:"human"},{name:"human-requests.post.138",method:"POST",path:"/v1/human/requests/:request_id/replace",classes:["person","broker"],resource:"human"},{name:"human-requests.post.139",method:"POST",path:"/v1/human/requests/:request_id/respond",classes:["person","broker"],resource:"human"},{name:"human-requests.post.140",method:"POST",path:"/v1/human/requests/:request_id/dismiss",classes:["person","broker"],resource:"human"},{name:"human-requests.post.141",method:"POST",path:"/v1/human/requests/:request_id/cancel",classes:["person","broker"],resource:"human"},{name:"focus.get.142",method:"GET",path:"/v1/focuses",classes:["person","broker"],resource:"none"},{name:"focus.post.143",method:"POST",path:"/v1/focuses",classes:["person","broker"],resource:"none"},{name:"focus.get.144",method:"GET",path:"/v1/focuses/by-node",classes:["person","broker"],resource:"none"},{name:"focus.get.145",method:"GET",path:"/v1/focuses/by-pane",classes:["person","broker"],resource:"none"},{name:"focus.patch.146",method:"PATCH",path:"/v1/focuses/:focus_id",classes:["person","broker"],resource:"none"},{name:"focus.delete.147",method:"DELETE",path:"/v1/focuses/:focus_id",classes:["person","broker"],resource:"none"},{name:"delivery.retry",method:"POST",path:"/v1/deliveries/:delivery_id/retry",classes:["person","broker"],resource:"none"},{name:"limits.show",method:"GET",path:"/v1/limits",classes:["person"],resource:"none"},{name:"limits.set",method:"PUT",path:"/v1/limits/apps/:app",classes:["person"],resource:"none"},{name:"limits.remove",method:"DELETE",path:"/v1/limits/apps/:app",classes:["person"],resource:"none"},{name:"space.list",method:"GET",path:"/v1/spaces",classes:["person","broker"],resource:"none"},{name:"kinds.list",method:"GET",path:"/v1/kinds",classes:["person","app","broker"],resource:"none"},{name:"grant.get",method:"GET",path:"/v1/grant",classes:["app"],resource:"none",stage:"v0.5"},{name:"usage.get",method:"GET",path:"/v1/usage",classes:["person","app","broker"],resource:"none",stage:"v1"},{name:"llm",method:"POST",path:"/v1/llm",classes:["app","person","broker"],scope:"crtr:llm",resource:"none",stage:"v1"},{name:"structured-request.create",method:"POST",path:"/v1/structured-requests",classes:["person","app","broker"],scope:"crtr:act",resource:"none"},{name:"structured-request.get",method:"GET",path:"/v1/structured-requests/:request_id",classes:["person","app","broker"],resource:"none"},{name:"structured-request.cancel",method:"POST",path:"/v1/structured-requests/:request_id/cancel",classes:["person","app","broker"],scope:"crtr:act",resource:"none"},{name:"run.start",method:"POST",path:"/v1/runs",classes:["app"],scope:"crtr:act",resource:"none",stage:"v0.5",idempotency:"24h"},{name:"run.list",method:"GET",path:"/v1/runs",classes:["app","person","broker","cron"],resource:"run",stage:"v0.5"},{name:"run.get",method:"GET",path:"/v1/runs/:run_id",classes:["app","person","broker","cron"],resource:"run",stage:"v0.5"},{name:"run.message",method:"POST",path:"/v1/runs/:run_id/messages",classes:["app","person","broker","cron"],scope:"crtr:act",resource:"run",stage:"v0.5",idempotency:"24h"},{name:"run.events",method:"GET",path:"/v1/runs/:run_id/events",classes:["app","person","broker","cron"],resource:"run",stage:"v0.5",stream:!0},{name:"run.interrupt",method:"POST",path:"/v1/runs/:run_id/interrupt",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.cancel",method:"POST",path:"/v1/runs/:run_id/cancel",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.delete",method:"DELETE",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.rename",method:"POST",path:"/v1/runs/:run_id/rename",classes:["app"],resource:"run",stage:"chat"},{name:"question.get",method:"GET",path:"/v1/questions/:question_id",classes:["app"],resource:"none",stage:"chat"},{name:"question.answer",method:"POST",path:"/v1/questions/:question_id/answer",classes:["app"],resource:"none",stage:"chat"},{name:"trace.get",method:"GET",path:"/v1/runs/:run_id/trace",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"upload.create",method:"POST",path:"/v1/uploads",classes:["app"],scope:"crtr:act",resource:"none",stage:"file-transfer"},{name:"attachment.link",method:"GET",path:"/v1/attachments/link",classes:["app"],resource:"none",stage:"file-transfer"},{name:"file.download",method:"GET",path:"/v1/files/download",classes:["app"],resource:"none",stage:"file-transfer",stream:"bytes"},{name:"share.create",method:"POST",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.list",method:"GET",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.delete",method:"DELETE",path:"/v1/shares/:share_id",classes:["app"],resource:"none",stage:"file-transfer"},{name:"memory.list",method:"GET",path:"/v1/memory",classes:["person","app","broker"],resource:"none",stage:"m13"},{name:"memory.get",method:"GET",path:"/v1/memory/document",classes:["person","app","broker"],resource:"none",stage:"m13"},{name:"audit.list",method:"GET",path:"/v1/audit",classes:["person","app"],resource:"none",stage:"v1"},{name:"provider.tools",method:"GET",path:"/v1/providers/tools",classes:["person","app","broker","cron"],resource:"none",stage:"v1"},{name:"provider.tools",method:"GET",path:"/v1/providers/:provider/tools",classes:["person","app","broker","cron"],resource:"none",stage:"v1"},{name:"provider.call",method:"POST",path:"/v1/provider/call",classes:["person","app","broker","cron"],resource:"none",stage:"v1"},{name:"peer.events",method:"POST",path:"/v1/peer/events",classes:["machine"],resource:"none"},{name:"peer.outbox.claim",method:"POST",path:"/v1/peer/outbox/claim",classes:["machine"],resource:"none"},{name:"peer.outbox.ack",method:"POST",path:"/v1/peer/outbox/ack",classes:["machine"],resource:"none"},{name:"peer.locate",method:"POST",path:"/v1/peer/locate",classes:["machine"],resource:"none"},{name:"runtime.sync-notice",method:"POST",path:"/v1/runtime/sync-notice",classes:["directory"],resource:"none",stage:"v1"},{name:"runtime.vendor-status",method:"GET",path:"/v1/runtime/vendor-status",classes:["directory"],resource:"none",stage:"v1"}];function c(e,s){return n.find(o=>o.method===e.toUpperCase()&&o.path===s)}r(c,"operationFor");export{n as OPERATIONS,c as operationFor};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Scope } from '@north-light/identity';
|
|
1
|
+
import { JwksCache, type Scope } from '@north-light/identity';
|
|
2
2
|
import { type ActiveGrant, type GrantDependencies, type GrantScope } from '../../core/grants/mirror.js';
|
|
3
3
|
export interface AppPrincipal {
|
|
4
4
|
sub: string;
|
|
@@ -30,6 +30,8 @@ export declare class AppPrincipalResolver {
|
|
|
30
30
|
}) => Promise<void>, jwksUrl?: string);
|
|
31
31
|
private load;
|
|
32
32
|
isReady(): boolean;
|
|
33
|
+
/** The directory key set, for the peer ingress's machine-token check. */
|
|
34
|
+
get jwks(): JwksCache;
|
|
33
35
|
close(): void;
|
|
34
36
|
/** jti → exp of every notice accepted within its lifetime. */
|
|
35
37
|
private readonly notices;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var p=Object.defineProperty;var o=(a,e)=>p(a,"name",{value:e,configurable:!0});import{covers as m,JwksCache as _,MissingRevClaimError as b,verifyAccessToken as k,verifySyncNotice as x}from"@north-light/identity";import{createLocalJWKSet as f,decodeProtectedHeader as w,jwtVerify as g}from"jose";import{emitEvent as
|
|
1
|
+
var p=Object.defineProperty;var o=(a,e)=>p(a,"name",{value:e,configurable:!0});import{covers as m,JwksCache as _,MissingRevClaimError as b,verifyAccessToken as k,verifySyncNotice as x}from"@north-light/identity";import{createLocalJWKSet as f,decodeProtectedHeader as w,jwtVerify as g}from"jose";import{emitEvent as j}from"../../core/events/emit.js";import{activeGrant as G,grantSyncState as d,grantsGeneration as S}from"../../core/grants/mirror.js";import{RunError as n}from"../../core/runs/operations.js";class B{static{o(this,"AppPrincipalResolver")}issuer;audience;syncGrants;cache;ready=!1;timer;constructor(e,t,r,i){this.issuer=e,this.audience=t,this.syncGrants=r,this.cache=new _(e,fetch,i),this.load(),this.timer=setInterval(()=>{this.ready||this.load()},5e3),this.timer.unref()}async load(){try{await this.cache.load(),this.ready=!0}catch{}}isReady(){return this.ready}get jwks(){return this.cache}close(){this.timer&&clearInterval(this.timer)}notices=new Map;async verifySyncNotice(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");if(!e?.startsWith("Bearer ")||e.length<=7)throw new n(401,"unauthorized","a directory sync notice token is required");let t;try{t=await x({token:e.slice(7),jwks:this.cache,issuer:this.issuer,audience:this.audience})}catch{throw new n(401,"unauthorized","invalid directory sync notice token")}const r=Math.floor(Date.now()/1e3);for(const[i,s]of this.notices)s+30<r&&this.notices.delete(i);return this.notices.has(t.jti)?!1:(this.notices.set(t.jti,t.exp),!0)}async verifyHandoff(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");const t=o(()=>new n(401,"unauthorized","invalid vendor sign-in handoff"),"refuse");if(!e)throw t();let r;try{const u=w(e);if(u.alg!=="ES256")throw t();const l=await this.cache.forKid(u.kid);({payload:r}=await g(e,f(l),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp","jti","sub"]}))}catch{throw t()}const{sub:i,jti:s,exp:c,purpose:h,aud:y}=r;if(h!=="vendor_sign_in"||y!==this.audience||typeof i!="string"||typeof s!="string"||s===""||typeof c!="number")throw t();return{sub:i,jti:s,exp:c}}async verifyDirectoryRead(e,t){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");const r=o(()=>new n(401,"unauthorized","invalid directory token"),"refuse");if(!e?.startsWith("Bearer ")||e.length<=7)throw r();const i=e.slice(7);let s;try{const c=w(i);if(c.alg!=="ES256")throw r();const h=await this.cache.forKid(c.kid);({payload:s}=await g(i,f(h),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp"]}))}catch{throw r()}if(s.purpose!==t||s.aud!==this.audience)throw r()}behind=new Map;behindGeneration=-1;behindRev(e){const t=S();return t!==this.behindGeneration&&(this.behind=new Map,this.behindGeneration=t),this.behind.get(e)}async ensureCovers(e){if(v(d(e.grant),e.rev))return;const t=this.behindRev(e.grant);if(t===void 0||e.rev>t){try{await this.syncGrants({fresh:!0})}catch{throw new n(503,"service_unavailable","grant sync failed")}const r=d(e.grant);if(v(r,e.rev))return;this.behindRev(e.grant),this.behind.set(e.grant,Math.max(e.rev,this.behind.get(e.grant)??0)),j({level:"error",event:"daemon.grants.behind_token",fields:{grant:e.grant,token_rev:e.rev,mirror_rev:r?.rev??0}})}throw d(e.grant)?new n(503,"service_unavailable","the directory answered grant sync below the access token's grant revision"):new n(401,"grant_revoked","grant is not active")}async resolve(e,t){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");if(!e?.startsWith("Bearer ")||e.length<=7)throw new n(401,"unauthorized","a directory access token is required");let r;try{r=await k({token:e.slice(7),jwks:this.cache,issuer:this.issuer,audience:this.audience})}catch(s){throw s instanceof b?new n(401,"unauthorized",s.message):new n(401,"unauthorized","invalid directory access token")}await this.ensureCovers(r);const i=R(r);if(t&&!i.resolved.some(s=>m(s,t)))throw new n(403,"scope_missing",`missing scope ${t}`,void 0,void 0,t);return{sub:r.sub,grantee:r.grantee,client_id:r.client_id,grant:r.grant,rev:i.rev,resolved:i.resolved,resolved_scopes:i.resolved_scopes,spend_cap:i.spend_cap,dependencies:i.dependencies??{},exp:r.exp}}}function R(a){const e=G(a.grant);if(!e||e.sub!==a.sub||e.grantee!==a.grantee||e.expires_at!==null&&!(Date.parse(e.expires_at)>Date.now()))throw new n(401,"grant_revoked","grant is not active");return e}o(R,"callerGrant");function v(a,e){return a!==null&&a.rev>=e}o(v,"covered");export{B as AppPrincipalResolver,R as callerGrant};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
2
|
import { ApiError } from '../../api/errors.js';
|
|
3
|
+
import { type RunPlace } from '../../core/runs/confinement.js';
|
|
3
4
|
import type { AppPrincipal } from './principal.js';
|
|
4
5
|
import { type Operation } from './operations.js';
|
|
5
6
|
/** What the caller's bearer token may reach: `null` is the owner (every scope,
|
|
@@ -31,7 +32,30 @@ export type RequestPrincipal = {
|
|
|
31
32
|
grant: string | null;
|
|
32
33
|
client_id: string | null;
|
|
33
34
|
scopes: string[] | null;
|
|
34
|
-
} | CronPrincipalClass;
|
|
35
|
+
} | CronPrincipalClass | ForwardedPrincipal | MachinePrincipal;
|
|
36
|
+
/** A call another of the account's machines makes on behalf of a person or an app node (the `Crtr-Envelope` names which). `via` is the calling
|
|
37
|
+
* machine (`runtime:<id>`), `sub` the account owner. An app actor reads and writes as its app, bounded by its mirrored grant and the node's
|
|
38
|
+
* `node_scopes`, confined to `place`; a person actor is treated as the person. Only the rows that list `forwarded` admit it. */
|
|
39
|
+
export type ForwardedPrincipal = {
|
|
40
|
+
class: 'forwarded';
|
|
41
|
+
via: string;
|
|
42
|
+
sub: string;
|
|
43
|
+
actor: {
|
|
44
|
+
kind: 'person';
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'app';
|
|
47
|
+
app: string;
|
|
48
|
+
node: string | null;
|
|
49
|
+
node_scopes: string[] | null;
|
|
50
|
+
place: RunPlace;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
/** A machine token with no envelope: the calling machine itself (`peer.*` rows only), never a person or an app. */
|
|
54
|
+
export type MachinePrincipal = {
|
|
55
|
+
class: 'machine';
|
|
56
|
+
via: string;
|
|
57
|
+
sub: string;
|
|
58
|
+
};
|
|
35
59
|
/** A cron's command calling through its per-execution socket (design-cron-authority "Router authorization").
|
|
36
60
|
* Identity is the stored cron principal; there is no node. `scopes` is the stored bound (null = whole grant). */
|
|
37
61
|
export type CronPrincipalClass = {
|
|
@@ -47,6 +71,10 @@ export type CronPrincipalClass = {
|
|
|
47
71
|
anchor: string | null;
|
|
48
72
|
uid: number;
|
|
49
73
|
};
|
|
74
|
+
/** The app a non-person caller acts as: a forwarded app actor's app, a forwarded person's terminal, null for the anonymous, a machine and the person. */
|
|
75
|
+
export declare function appOf(principal: RequestPrincipal): string | null;
|
|
76
|
+
/** Whether the caller is the person (a local person, or a forwarded call the envelope makes for the person). */
|
|
77
|
+
export declare function actsAsPerson(principal: RequestPrincipal): boolean;
|
|
50
78
|
export declare function resolvedScopes(principal: RequestPrincipal): readonly string[];
|
|
51
79
|
export declare function runCallerApp(principal: RequestPrincipal | AppPrincipal): string | null;
|
|
52
80
|
/** Run confinement (Silas, 2026-09-30): a broker caller reaches a same-app node or
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var O=Object.defineProperty;var a=(e,o)=>O(e,"name",{value:o,configurable:!0});import{toErrorBody as $}from"./map.js";import{emitEvent as T}from"../../core/events/emit.js";import{scopeAllowed as f,ScopeDeniedError as A}from"../../core/scopes.js";import{ApiError as d}from"../../api/errors.js";import{activeGrant as k,grantFor as U}from"../../core/grants/mirror.js";import{getNode as _}from"../../core/canvas/canvas.js";import{ownedRun as N,RunError as g}from"../../core/runs/operations.js";import{nodeMayReach as W,placeMayReach as j}from"../../core/runs/confinement.js";import{checkCronFire as G}from"../cron/authority.js";import{readConfig as J}from"../../core/config.js";import{SCOPE_VOCABULARY as z}from"../../core/scopes.js";import{operationFor as H}from"./operations.js";import{CONTROL_BODY_MAX_BYTES as I}from"../../core/llm/body-limits.js";import{getRequest as L,getRequestByInboxTicket as M}from"../../core/human/requests.js";import{requireVisibleReview as B}from"../../core/review/store.js";import{getComment as E}from"../../core/review/comments.js";function P(e,o,t,s,n){const r=e.path,u=n&&typeof n=="object"&&!Array.isArray(n)?n:{};if(r==="/v1/human/requests"||r==="/v1/human/reviews"){if((r.endsWith("/reviews")?u.origin_node_id:u.requester_node_id)!==o.node)throw new d(403,"other_app_run","a broker may create a human request only for its own node");const h=u.source;if(h&&typeof h=="object"&&"nodeId"in h&&h.nodeId!==o.node)throw new d(403,"other_app_run","request source must name the calling node")}if(r==="/v1/human/reviews/self/comments"&&e.method==="GET"&&s.get("actor_node_id")!==o.node)throw new d(403,"other_app_run","self review requires the calling node");if(r.includes("/comments")&&e.method!=="GET"&&u.actor_node_id!==o.node)throw new d(403,"other_app_run","comment author must be the calling node");if(t.comment_id&&!E(t.comment_id))throw new d(404,"not_found","comment not found")}a(P,"authorizeHumanBody");function y(e){return e.class==="broker"||e.class==="cron"}a(y,"boundedByStoredScopes");function b(e){if(e.class==="person"||e.class==="anonymous")return[];if(e.class==="app")return e.scopes;if(e.class==="cron"){const t=G({grantee:e.app,sub:e.sub,grant_id:e.grant,scopes:e.scopes});if(t.allowed)return t.effectiveScopes;throw t.reason==="grant_missing"||t.reason==="grant_revoked"?new d(401,"grant_revoked",t.message):new d(403,"scope_missing",t.message)}const o=e.grant?k(e.grant):U(e.app,e.sub);if(o&&o.grantee===e.app&&o.sub===e.sub)return o.resolved;if(e.app==="app:terminal"&&!J("user").runtime?.issuer)return z;throw new d(401,"grant_revoked","the node grant is not active")}a(b,"resolvedScopes");function v(e){return"class"in e?e.class==="person"||e.class==="anonymous"?null:e.app:e.grantee}a(v,"runCallerApp");function l(e,o,t){return o===void 0||!("class"in e)?!0:e.class==="cron"?j({run:e.origin_run??"",isolated:e.isolated},e.app,o,t):e.class!=="broker"?!0:W(e.node,e.app,o,t)}a(l,"brokerMayReach");function F(e,o,t){const s=v(e);if(s===o)return l(e,t,o);if(s===null)return!0;const n="class"in e?null:k(e.grant),r="class"in e?b(e):n?.sub===e.sub&&n.grantee===e.grantee?n.resolved:[];return f(r,`crtr:conversations:read:${o}`)&&(!("class"in e)||!y(e)||f(e.scopes,`crtr:conversations:read:${o}`))}a(F,"canReadRun");function ge(e,o,t=!1,s=!1){const n=_(o);if(!n||n.parent!==null||n.run_id!==o||!n.grantee||n.deleting_at&&!s)throw new g(404,"not_found","run not found");if(!F(e,n.grantee,o))throw new g(404,"not_found","run not found");if(t&&v(e)!==null&&v(e)!==n.grantee)throw new g(403,"other_app_run","cannot change another app's run");return N(o,n.grantee,s)}a(ge,"requireRun");function x(e,o,t){return e.class!=="person"&&e.class!=="anonymous"&&e.app===o?l(e,t,o):e.class==="person"||e.class!=="anonymous"&&(e.app===o||f(b(e),`crtr:objects:read:${o}`)&&(!y(e)||f(e.scopes,`crtr:objects:read:${o}`)))}a(x,"canReadNode");function Y(e,o,t){if(!e.classes.includes(o.class)&&!(o.class!=="anonymous"&&e.classes.includes("anonymous")))throw new d(403,"permission_error","this operation is not available to the caller");if(o.class==="person"||o.class==="anonymous")return;const s=b(o);if(e.scope&&(!f(s,e.scope)||y(o)&&!f(o.scopes,e.scope)))throw new d(403,"scope_missing",`missing scope ${e.scope}`);if(o.class==="app")return;o.class==="broker"&&V(e,o,t,s);const n=t.id;if((e.resource==="node-read"||e.resource==="node-write")&&n!==void 0){const r=_(n);if(!r)return;if(e.resource==="node-write"&&r.grantee!==o.app)throw new d(403,"other_app_run","cannot change another app's node");if(e.resource==="node-write"&&!l(o,n,r.grantee??"app:terminal"))throw new d(404,"not_found","node not found");if(e.resource==="node-read"&&!x(o,r.grantee??"app:terminal",n))throw new d(404,"not_found","node not found")}}a(Y,"authorizeOperation");function V(e,o,t,s){if(e.resource==="daemon-bash"&&(!f(s,"crtr:files:rw:user:.")||!f(o.scopes,"crtr:files:rw:user:.")))throw new d(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const r=e.path,u=e.method==="GET";if(!u&&(r.endsWith("/respond")||r.endsWith("/submit")||r.endsWith("/dismiss")||r.endsWith("/progress")||r.endsWith("/comment-ranges")||r.includes("/feedback-comments")))throw new d(403,"permission_error","only the person may answer or edit the human inbox");const c=t.request_id?L(t.request_id):t.ticket_id?M(t.ticket_id):null,h=t.comment_id?E(t.comment_id):null,w=t.review_id?B(t.review_id):h?B(h.review_id):null,m=c?.requester_node_id??w?.origin_node_id;if(m!=null){const i=_(m);if(i&&(u?!x(o,i.grantee??"app:terminal",m):i.grantee!==o.app))throw new d(u?404:403,u?"not_found":"other_app_run","human request belongs to another app");if(i&&!u&&!l(o,m,i.grantee??"app:terminal"))throw new d(404,"not_found","human request not found")}else if(c||w)throw new d(403,"permission_error","only the person may access a request without a node")}const n=t.id;if(e.resource==="node-own"&&n!==void 0&&n!==o.node)throw new d(403,"other_app_run","the operation requires the calling node")}a(V,"authorizeBrokerOnly");function D(e,o){if(!f(e,o))throw new A("the bearer token",o)}a(D,"assertCeiling");function X(){return new d(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}a(X,"ownerOnlyError");function ye(e){return e.map(o=>({...o,ownerOnly:!0}))}a(ye,"ownerOnly");class be{static{a(this,"Router")}routes=[];register(o){const t=H(o.method,o.pattern);if(!t)throw new Error(`route has no operation row: ${o.method} ${o.pattern}`);if(this.routes.some(s=>s.method===o.method.toUpperCase()&&s.operation.path===o.pattern))throw new Error(`duplicate route: ${o.method} ${o.pattern}`);return this.routes.push({operation:t,method:o.method.toUpperCase(),segments:R(o.pattern),handler:o.handler,maxBodyBytes:o.maxBodyBytes??I}),this}registerAll(o){for(const t of o)this.register(t);return this}match(o,t){const s=o.toUpperCase(),n=R(t);for(const r of this.routes){if(r.method!==s)continue;const u=K(r.segments,n);if(u!==null)return{handler:r.handler,params:u,operation:r.operation,maxBodyBytes:r.maxBodyBytes}}return null}async handle(o,t,s,n={class:"person"}){try{const r=new URL(o.url??"/","http://127.0.0.1"),u=(o.method??"GET").toUpperCase(),c=this.match(u,r.pathname);if(c===null){C(t,404,"not_found",`no route for ${u} ${r.pathname}`);return}if(Y(c.operation,n,c.params),s!==null){if(c.operation.classes.length===1&&c.operation.classes[0]==="person")throw X();c.operation.scope&&D(s,c.operation.scope)}let h;try{h=await Q(o,c.maxBodyBytes)}catch(i){const p=i instanceof S?"payload_too_large":"invalid_request";C(t,p==="payload_too_large"?413:400,p,i.message);return}n.class==="broker"&&c.operation.resource==="human"&&P(c.operation,n,c.params,r.searchParams,h);const w={method:u,path:r.pathname,params:c.params,query:r.searchParams,body:h,ceiling:s,principal:n,...n.class==="anonymous"&&typeof o.headers.authorization=="string"?{publishToken:o.headers.authorization.slice(7)}:{},req:o,res:t},m=await c.handler(w);t.writableEnded||Z(t,m)}catch(r){const{status:u,body:c}=$(r);u>=500&&T({event:"api.request.failed",level:"error",error:r instanceof Error?r:new Error(String(r)),...n.class==="broker"?{node_id:n.node}:{},fields:{method:(o.method??"GET").toUpperCase(),path:o.url??""}}),q(t,u,c)}}}function R(e){return e.split("/").filter(o=>o.length>0)}a(R,"splitPath");function K(e,o){if(e.length!==o.length)return null;const t={};for(let s=0;s<e.length;s++){const n=e[s],r=o[s];if(n.startsWith(":"))t[n.slice(1)]=decodeURIComponent(r);else if(n!==r)return null}return t}a(K,"matchSegments");class S extends Error{static{a(this,"BodyTooLargeError")}}async function Q(e,o){const t=[];let s=0;for await(const r of e){const u=r;if(s+=u.length,s>o)throw new S(`request body exceeds ${o} bytes`);t.push(u)}if(s===0)return;const n=Buffer.concat(t).toString("utf8").trim();if(n!=="")try{return JSON.parse(n)}catch{throw new Error("request body is not valid JSON")}}a(Q,"readJsonBody");function Z(e,o){if(e.headersSent)return;const t={...o.headers??{}};if(o.rawBody!==void 0){e.writeHead(o.status,t),e.end(o.rawBody);return}if(o.status===204||o.body===void 0){e.writeHead(o.status,t),e.end();return}t["content-type"]===void 0&&(t["content-type"]="application/json; charset=utf-8"),e.writeHead(o.status,t),e.end(JSON.stringify(o.body))}a(Z,"writeResult");function q(e,o,t){if(e.headersSent){e.end();return}e.writeHead(o,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(t))}a(q,"writeJson");function C(e,o,t,s){q(e,o,{error:{code:t,message:s}})}a(C,"writeError");export{be as Router,D as assertCeiling,l as brokerMayReach,x as canReadNode,F as canReadRun,ye as ownerOnly,X as ownerOnlyError,ge as requireRun,b as resolvedScopes,v as runCallerApp};
|
|
1
|
+
var W=Object.defineProperty;var a=(e,t)=>W(e,"name",{value:t,configurable:!0});import{toErrorBody as j}from"./map.js";import{emitEvent as N}from"../../core/events/emit.js";import{scopeAllowed as h,ScopeDeniedError as p}from"../../core/scopes.js";import{coveredByAny as J}from"../../shared/env.js";import{ApiError as d}from"../../api/errors.js";import{activeGrant as B,grantFor as x}from"../../core/grants/mirror.js";import{getNode as _}from"../../core/canvas/canvas.js";import{ownedRun as z,RunError as g}from"../../core/runs/operations.js";import{nodeMayReach as H,placeMayReach as S}from"../../core/runs/confinement.js";import{checkCronFire as M}from"../cron/authority.js";import{readConfig as P}from"../../core/config.js";import{SCOPE_VOCABULARY as I}from"../../core/scopes.js";import{operationFor as L}from"./operations.js";import{CONTROL_BODY_MAX_BYTES as F}from"../../core/llm/body-limits.js";import{getRequest as Y,getRequestByInboxTicket as V}from"../../core/human/requests.js";import{requireVisibleReview as R}from"../../core/review/store.js";import{getComment as O}from"../../core/review/comments.js";function D(e,t,o,s,r){const n=e.path,u=r&&typeof r=="object"&&!Array.isArray(r)?r:{};if(n==="/v1/human/requests"||n==="/v1/human/reviews"){if((n.endsWith("/reviews")?u.origin_node_id:u.requester_node_id)!==t.node)throw new d(403,"other_app_run","a broker may create a human request only for its own node");const f=u.source;if(f&&typeof f=="object"&&"nodeId"in f&&f.nodeId!==t.node)throw new d(403,"other_app_run","request source must name the calling node")}if(n==="/v1/human/reviews/self/comments"&&e.method==="GET"&&s.get("actor_node_id")!==t.node)throw new d(403,"other_app_run","self review requires the calling node");if(n.includes("/comments")&&e.method!=="GET"&&u.actor_node_id!==t.node)throw new d(403,"other_app_run","comment author must be the calling node");if(o.comment_id&&!O(o.comment_id))throw new d(404,"not_found","comment not found")}a(D,"authorizeHumanBody");function y(e){return e.class==="broker"||e.class==="cron"}a(y,"boundedByStoredScopes");function b(e){return e.class==="person"||e.class==="anonymous"||e.class==="machine"?null:e.class==="forwarded"?e.actor.kind==="app"?e.actor.app:null:e.app}a(b,"appOf");function q(e){return e.class==="person"||e.class==="forwarded"&&e.actor.kind==="person"}a(q,"actsAsPerson");function $(e){const t=x(e.actor.app,e.sub);if(!t)throw new d(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);return t}a($,"forwardedGrant");function v(e){if(e.class==="person"||e.class==="anonymous"||e.class==="machine")return[];if(e.class==="forwarded"){if(e.actor.kind==="person")return[];const{resolved:o}=$(e),s=e.actor.node_scopes;return s===null?o:s.filter(r=>J(o,r))}if(e.class==="app")return e.scopes;if(e.class==="cron"){const o=M({grantee:e.app,sub:e.sub,grant_id:e.grant,scopes:e.scopes});if(o.allowed)return o.effectiveScopes;throw o.reason==="grant_missing"||o.reason==="grant_revoked"?new d(401,"grant_revoked",o.message):new d(403,"scope_missing",o.message)}const t=e.grant?B(e.grant):x(e.app,e.sub);if(t&&t.grantee===e.app&&t.sub===e.sub)return t.resolved;if(e.app==="app:terminal"&&!P("user").runtime?.issuer)return I;throw new d(401,"grant_revoked","the node grant is not active")}a(v,"resolvedScopes");function k(e){return"class"in e?b(e):e.grantee}a(k,"runCallerApp");function l(e,t,o){return t===void 0||!("class"in e)?!0:e.class==="cron"?S({run:e.origin_run??"",isolated:e.isolated},e.app,t,o):e.class==="forwarded"?e.actor.kind!=="app"||S(e.actor.place,e.actor.app,t,o):e.class!=="broker"?!0:H(e.node,e.app,t,o)}a(l,"brokerMayReach");function X(e,t,o){const s=k(e);if(s===t)return l(e,o,t);if(s===null)return!0;const r="class"in e?null:B(e.grant),n="class"in e?v(e):r?.sub===e.sub&&r.grantee===e.grantee?r.resolved:[];return h(n,`crtr:conversations:read:${t}`)&&(!("class"in e)||!y(e)||h(e.scopes,`crtr:conversations:read:${t}`))}a(X,"canReadRun");function Be(e,t,o=!1,s=!1){const r=_(t);if(!r||r.parent!==null||r.run_id!==t||!r.grantee||r.deleting_at&&!s)throw new g(404,"not_found","run not found");if(!X(e,r.grantee,t))throw new g(404,"not_found","run not found");if(o&&k(e)!==null&&k(e)!==r.grantee)throw new g(403,"other_app_run","cannot change another app's run");return z(t,r.grantee,s)}a(Be,"requireRun");function C(e,t,o){return q(e)?!0:e.class==="anonymous"||e.class==="machine"?!1:b(e)===t?l(e,o,t):h(v(e),`crtr:objects:read:${t}`)&&(!y(e)||h(e.scopes,`crtr:objects:read:${t}`))}a(C,"canReadNode");const K=new Set(["messages.post.58","messages.post.59"]);function Q(e,t,o){if(!e.classes.includes(t.class)&&!(t.class!=="anonymous"&&t.class!=="machine"&&t.class!=="forwarded"&&e.classes.includes("anonymous")))throw new d(403,"permission_error","this operation is not available to the caller");if(t.class==="forwarded"&&t.actor.kind==="app"&&$(t),t.class==="person"||t.class==="anonymous"||t.class==="machine"||q(t))return;const s=v(t);if(e.scope&&(!h(s,e.scope)||y(t)&&!h(t.scopes,e.scope)))throw new d(403,"scope_missing",`missing scope ${e.scope}`);if(t.class==="app")return;const r=b(t);t.class==="broker"&&Z(e,t,o,s);const n=o.id;if((e.resource==="node-read"||e.resource==="node-write")&&n!==void 0){const u=_(n);if(!u)return;if(e.resource==="node-write"&&u.grantee!==r&&!(K.has(e.name)&&h(s,`crtr:objects:message:${u.grantee??"app:terminal"}`)))throw new d(403,"other_app_run","cannot change another app's node");if(e.resource==="node-write"&&!l(t,n,u.grantee??"app:terminal"))throw new d(404,"not_found","node not found");if(e.resource==="node-read"&&!C(t,u.grantee??"app:terminal",n))throw new d(404,"not_found","node not found")}}a(Q,"authorizeOperation");function Z(e,t,o,s){if(e.resource==="daemon-bash"&&(!h(s,"crtr:files:rw:user:.")||!h(t.scopes,"crtr:files:rw:user:.")))throw new d(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const n=e.path,u=e.method==="GET";if(!u&&(n.endsWith("/respond")||n.endsWith("/submit")||n.endsWith("/dismiss")||n.endsWith("/progress")||n.endsWith("/comment-ranges")||n.includes("/feedback-comments")))throw new d(403,"permission_error","only the person may answer or edit the human inbox");const c=o.request_id?Y(o.request_id):o.ticket_id?V(o.ticket_id):null,f=o.comment_id?O(o.comment_id):null,w=o.review_id?R(o.review_id):f?R(f.review_id):null,i=c?.requester_node_id??w?.origin_node_id;if(i!=null){const m=_(i);if(m&&(u?!C(t,m.grantee??"app:terminal",i):m.grantee!==t.app))throw new d(u?404:403,u?"not_found":"other_app_run","human request belongs to another app");if(m&&!u&&!l(t,i,m.grantee??"app:terminal"))throw new d(404,"not_found","human request not found")}else if(c||w)throw new d(403,"permission_error","only the person may access a request without a node")}const r=o.id;if(e.resource==="node-own"&&r!==void 0&&r!==t.node)throw new d(403,"other_app_run","the operation requires the calling node")}a(Z,"authorizeBrokerOnly");function ee(e,t){if(!h(e,t))throw new p("the bearer token",t)}a(ee,"assertCeiling");function te(){return new d(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}a(te,"ownerOnlyError");function xe(e){return e.map(t=>({...t,ownerOnly:!0}))}a(xe,"ownerOnly");class Se{static{a(this,"Router")}routes=[];register(t){const o=L(t.method,t.pattern);if(!o)throw new Error(`route has no operation row: ${t.method} ${t.pattern}`);if(this.routes.some(s=>s.method===t.method.toUpperCase()&&s.operation.path===t.pattern))throw new Error(`duplicate route: ${t.method} ${t.pattern}`);return this.routes.push({operation:o,method:t.method.toUpperCase(),segments:A(t.pattern),handler:t.handler,maxBodyBytes:t.maxBodyBytes??F}),this}registerAll(t){for(const o of t)this.register(o);return this}match(t,o){const s=t.toUpperCase(),r=A(o);for(const n of this.routes){if(n.method!==s)continue;const u=oe(n.segments,r);if(u!==null)return{handler:n.handler,params:u,operation:n.operation,maxBodyBytes:n.maxBodyBytes}}return null}async handle(t,o,s,r={class:"person"}){try{const n=new URL(t.url??"/","http://127.0.0.1"),u=(t.method??"GET").toUpperCase(),c=this.match(u,n.pathname);if(c===null){U(o,404,"not_found",`no route for ${u} ${n.pathname}`);return}if(Q(c.operation,r,c.params),s!==null){if(c.operation.classes.length===1&&c.operation.classes[0]==="person")throw te();c.operation.scope&&ee(s,c.operation.scope)}let f;try{f=await re(t,c.maxBodyBytes)}catch(m){const E=m instanceof T?"payload_too_large":"invalid_request";U(o,E==="payload_too_large"?413:400,E,m.message);return}r.class==="broker"&&c.operation.resource==="human"&&D(c.operation,r,c.params,n.searchParams,f);const w={method:u,path:n.pathname,params:c.params,query:n.searchParams,body:f,ceiling:s,principal:r,...r.class==="anonymous"&&typeof t.headers.authorization=="string"?{publishToken:t.headers.authorization.slice(7)}:{},req:t,res:o},i=await c.handler(w);o.writableEnded||ne(o,i)}catch(n){const{status:u,body:c}=j(n);u>=500&&N({event:"api.request.failed",level:"error",error:n instanceof Error?n:new Error(String(n)),...r.class==="broker"?{node_id:r.node}:{},fields:{method:(t.method??"GET").toUpperCase(),path:t.url??""}}),G(o,u,c)}}}function A(e){return e.split("/").filter(t=>t.length>0)}a(A,"splitPath");function oe(e,t){if(e.length!==t.length)return null;const o={};for(let s=0;s<e.length;s++){const r=e[s],n=t[s];if(r.startsWith(":"))o[r.slice(1)]=decodeURIComponent(n);else if(r!==n)return null}return o}a(oe,"matchSegments");class T extends Error{static{a(this,"BodyTooLargeError")}}async function re(e,t){const o=[];let s=0;for await(const n of e){const u=n;if(s+=u.length,s>t)throw new T(`request body exceeds ${t} bytes`);o.push(u)}if(s===0)return;const r=Buffer.concat(o).toString("utf8").trim();if(r!=="")try{return JSON.parse(r)}catch{throw new Error("request body is not valid JSON")}}a(re,"readJsonBody");function ne(e,t){if(e.headersSent)return;const o={...t.headers??{}};if(t.rawBody!==void 0){e.writeHead(t.status,o),e.end(t.rawBody);return}if(t.status===204||t.body===void 0){e.writeHead(t.status,o),e.end();return}o["content-type"]===void 0&&(o["content-type"]="application/json; charset=utf-8"),e.writeHead(t.status,o),e.end(JSON.stringify(t.body))}a(ne,"writeResult");function G(e,t,o){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}a(G,"writeJson");function U(e,t,o,s){G(e,t,{error:{code:o,message:s}})}a(U,"writeError");export{Se as Router,q as actsAsPerson,b as appOf,ee as assertCeiling,l as brokerMayReach,C as canReadNode,X as canReadRun,xe as ownerOnly,te as ownerOnlyError,Be as requireRun,v as resolvedScopes,k as runCallerApp};
|