@north-light/cli 0.3.549 → 0.3.550

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/api/contract.d.ts +1 -1
  2. package/dist/api/contract.js +1 -1
  3. package/dist/api/dto/custom-objects.d.ts +1 -1
  4. package/dist/api/dto/docs.d.ts +12 -0
  5. package/dist/api/dto/objects.d.ts +17 -1
  6. package/dist/api/dto/objects.js +1 -1
  7. package/dist/api/dto/permissions.d.ts +76 -0
  8. package/dist/api/dto/permissions.js +1 -0
  9. package/dist/api/index.d.ts +3 -2
  10. package/dist/api/index.js +1 -1
  11. package/dist/api/routes.d.ts +4 -0
  12. package/dist/api/routes.js +1 -1
  13. package/dist/builtin-memory/crouter-concepts/documents.md +1 -1
  14. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +2 -2
  15. package/dist/builtin-memory/crouter-sdk/release-notes.md +11 -0
  16. package/dist/builtin-memory/internal/INDEX.md +2 -1
  17. package/dist/builtin-memory/internal/agent-shaping.md +1 -1
  18. package/dist/builtin-memory/internal/storage-tiers.md +1 -1
  19. package/dist/builtin-memory/northlight-apps/guides/files-and-documents.md +3 -3
  20. package/dist/builtin-memory/northlight-apps/guides/many-users.md +1 -1
  21. package/dist/builtin-memory/northlight-apps/guides/test-your-app.md +1 -1
  22. package/dist/clients/attach/viewer.js +9 -9
  23. package/dist/commands/canvas/list.js +2 -2
  24. package/dist/commands/canvas/share.d.ts +2 -0
  25. package/dist/commands/canvas/share.js +2 -0
  26. package/dist/commands/canvas.js +1 -1
  27. package/dist/commands/doc/edit.js +1 -1
  28. package/dist/commands/doc/shared.js +1 -1
  29. package/dist/commands/doc/write.js +1 -1
  30. package/dist/commands/sys/sync-skills.js +2 -2
  31. package/dist/core/canvas/canvas.js +20 -20
  32. package/dist/core/canvas/db.js +4 -4
  33. package/dist/core/canvas/export-sqlite.js +2 -2
  34. package/dist/core/canvas/import-sqlite.js +5 -5
  35. package/dist/core/canvas/outcome-actions.js +3 -3
  36. package/dist/core/canvas/person.js +11 -9
  37. package/dist/core/canvas/schema-pg.sql +49 -5
  38. package/dist/core/environments.js +1 -1
  39. package/dist/core/feed/feed.js +1 -1
  40. package/dist/core/grants/mirror.d.ts +9 -1
  41. package/dist/core/grants/mirror.js +2 -2
  42. package/dist/core/grants/sync.js +1 -1
  43. package/dist/core/graph/access.d.ts +8 -49
  44. package/dist/core/graph/access.js +4 -7
  45. package/dist/core/graph/custom.d.ts +5 -2
  46. package/dist/core/graph/custom.js +9 -9
  47. package/dist/core/graph/deletion.js +5 -4
  48. package/dist/core/graph/documents.d.ts +12 -3
  49. package/dist/core/graph/documents.js +13 -7
  50. package/dist/core/graph/edges.js +3 -3
  51. package/dist/core/graph/events.js +12 -8
  52. package/dist/core/graph/kinds/document.js +4 -4
  53. package/dist/core/graph/kinds/kind.js +1 -1
  54. package/dist/core/graph/kinds/node.js +5 -5
  55. package/dist/core/graph/names.d.ts +16 -1
  56. package/dist/core/graph/names.js +11 -3
  57. package/dist/core/graph/objects.d.ts +19 -2
  58. package/dist/core/graph/objects.js +16 -10
  59. package/dist/core/graph/package-docs.js +5 -5
  60. package/dist/core/graph/package-files.js +2 -2
  61. package/dist/core/graph/reader.js +3 -3
  62. package/dist/core/graph/repo-sync/exchange.js +2 -2
  63. package/dist/core/graph/rules.d.ts +7 -5
  64. package/dist/core/graph/rules.js +3 -3
  65. package/dist/core/graph/types.d.ts +12 -1
  66. package/dist/core/graph/types.js +1 -1
  67. package/dist/core/graph/watches.d.ts +1 -1
  68. package/dist/core/graph/watches.js +9 -8
  69. package/dist/core/peer/envelope.d.ts +1 -1
  70. package/dist/core/peer/envelope.js +1 -1
  71. package/dist/core/peer/stubs.d.ts +1 -1
  72. package/dist/core/peer/stubs.js +1 -1
  73. package/dist/core/permissions/boot.d.ts +17 -0
  74. package/dist/core/permissions/boot.js +18 -0
  75. package/dist/core/permissions/builtin.d.ts +8 -0
  76. package/dist/core/permissions/builtin.js +20 -0
  77. package/dist/core/permissions/ceiling.d.ts +57 -0
  78. package/dist/core/permissions/ceiling.js +22 -0
  79. package/dist/core/permissions/compile.d.ts +14 -0
  80. package/dist/core/permissions/compile.js +1 -0
  81. package/dist/core/permissions/errors.d.ts +7 -0
  82. package/dist/core/permissions/errors.js +1 -0
  83. package/dist/core/permissions/evaluator.d.ts +28 -0
  84. package/dist/core/permissions/evaluator.js +6 -0
  85. package/dist/core/permissions/facts.d.ts +56 -0
  86. package/dist/core/permissions/facts.js +2 -0
  87. package/dist/core/permissions/schema-parser.d.ts +29 -0
  88. package/dist/core/permissions/schema-parser.js +2 -0
  89. package/dist/core/permissions/schemas.d.ts +21 -0
  90. package/dist/core/permissions/schemas.js +2 -0
  91. package/dist/core/permissions/sql.d.ts +16 -0
  92. package/dist/core/permissions/sql.js +1 -0
  93. package/dist/core/runtime/broker/frame-client.d.ts +1 -1
  94. package/dist/core/runtime/broker/frame-client.js +1 -1
  95. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  96. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  97. package/dist/core/runtime/broker/frame-read.d.ts +4 -3
  98. package/dist/core/runtime/broker/frame-read.js +1 -1
  99. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  100. package/dist/core/runtime/host.js +3 -3
  101. package/dist/core/runtime/placement.js +1 -1
  102. package/dist/core/runtime/roadmap.js +1 -1
  103. package/dist/core/substrate/delivery/corpus.d.ts +2 -2
  104. package/dist/core/substrate/delivery/corpus.js +3 -3
  105. package/dist/core/substrate/delivery/deliver.js +2 -2
  106. package/dist/core/substrate/delivery/render-event.js +6 -6
  107. package/dist/core/substrate/subject-fields.d.ts +2 -0
  108. package/dist/core/substrate/subject.js +1 -1
  109. package/dist/daemon/api/app-listener.js +12 -12
  110. package/dist/daemon/api/bridge.d.ts +1 -1
  111. package/dist/daemon/api/bridge.js +4 -4
  112. package/dist/daemon/api/handlers/attach.d.ts +4 -1
  113. package/dist/daemon/api/handlers/attach.js +1 -1
  114. package/dist/daemon/api/handlers/canvas.js +5 -5
  115. package/dist/daemon/api/handlers/check.d.ts +2 -0
  116. package/dist/daemon/api/handlers/check.js +1 -0
  117. package/dist/daemon/api/handlers/custom-objects.js +2 -2
  118. package/dist/daemon/api/handlers/docs.js +1 -1
  119. package/dist/daemon/api/handlers/files.js +1 -1
  120. package/dist/daemon/api/handlers/memory.js +7 -6
  121. package/dist/daemon/api/handlers/nodes.js +1 -1
  122. package/dist/daemon/api/handlers/objects.js +3 -3
  123. package/dist/daemon/api/handlers/relations.d.ts +2 -0
  124. package/dist/daemon/api/handlers/relations.js +1 -0
  125. package/dist/daemon/api/handlers/schemas.d.ts +12 -0
  126. package/dist/daemon/api/handlers/schemas.js +1 -0
  127. package/dist/daemon/api/handlers/shares.d.ts +2 -0
  128. package/dist/daemon/api/handlers/shares.js +1 -0
  129. package/dist/daemon/api/operations.js +1 -1
  130. package/dist/daemon/api/router.d.ts +10 -6
  131. package/dist/daemon/api/router.js +1 -1
  132. package/dist/daemon/api/server.js +1 -1
  133. package/dist/daemon/crtrd.js +12 -12
  134. package/dist/daemon/reconcilers/delivery-lane.js +2 -2
  135. package/dist/migrations/004-canvas-documents/fields.d.ts +1 -1
  136. package/dist/migrations/004-canvas-documents/fields.js +2 -2
  137. package/docs/apps/guides/files-and-documents.md +3 -3
  138. package/docs/apps/guides/many-users.md +1 -1
  139. package/docs/apps/guides/test-your-app.md +1 -1
  140. package/docs/cli/documents-and-preferences.md +1 -1
  141. package/docs/concepts/documents.md +1 -1
  142. package/docs/concepts/scopes-and-trust.md +2 -2
  143. package/docs/sdk/release-notes.md +11 -0
  144. package/package.json +2 -2
  145. package/packages/crouter-identity/dist/index.js +14 -1
  146. package/packages/crouter-identity/package.json +1 -1
  147. package/runtime.lock.json +13 -13
  148. package/dist/core/graph/spaces/app.d.ts +0 -3
  149. package/dist/core/graph/spaces/app.js +0 -1
  150. package/dist/core/graph/spaces/index.d.ts +0 -18
  151. package/dist/core/graph/spaces/index.js +0 -1
  152. package/dist/core/graph/spaces/own-memory.d.ts +0 -18
  153. package/dist/core/graph/spaces/own-memory.js +0 -1
  154. package/dist/core/graph/spaces/person.d.ts +0 -5
  155. package/dist/core/graph/spaces/person.js +0 -3
  156. package/dist/core/graph/spaces/repo.d.ts +0 -14
  157. package/dist/core/graph/spaces/repo.js +0 -1
  158. package/dist/core/runs/confinement.d.ts +0 -25
  159. package/dist/core/runs/confinement.js +0 -2
@@ -1,3 +1,3 @@
1
- var Ne=Object.defineProperty;var l=(e,t)=>Ne(e,"name",{value:t,configurable:!0});import{ApiError as p}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as $e}from"../../../api/dto/objects.js";import{openDb as E,withCanvasWrite as j}from"../../../core/canvas/db.js";import{actorOf as ne}from"../../../core/graph/documents.js";import{readerForObject as L,readerFor as Ae}from"../../../core/graph/reader.js";import{resolveName as Fe,stubsNamed as Se,unwrapRef as ae}from"../../../core/graph/names.js";import{canRead as P,customReachable as We,holdsObjectsScope as Le,mayActAs as ie,spaceOf as Pe}from"../../../core/graph/access.js";import{customObjectRef as re,authorizeCustom as oe,fenceArgv as H}from"./custom-objects.js";import{edgesOf as Ce}from"../../../core/graph/edges.js";import{publish as V}from"../../../core/graph/events.js";import{objectDTO as b}from"../../../core/graph/kinds/dto.js";import{isKind as De,kindNames as Me,kindOf as B}from"../../../core/graph/kinds/registry.js";import{listObjects as Ge,searchObjects as se}from"../../../core/graph/objects.js";import{checkoutsForCwd as Ue}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as C,unwatch as ze,watchersOf as He,watchesOf as Ve}from"../../../core/graph/watches.js";import{armObjectWaitForWatch as D,settleObjectWaitForUnwatch as Be}from"../../../core/graph/object-waits.js";import{readerFor as O,resolveRef as K}from"../reader.js";import{readDelegationFor as ue,runReadLeaf as Ke}from"../../plugin-objects/read-leaf.js";import{invalidRequest as M,isRecord as N}from"./validate.js";import{callerNode as ce,callerStub as Z,forwardNamed as Ze,forwardVerb as le,originates as fe,queryWithoutMachine as G,relayError as U,remoteStub as Je,unknownError as de,forwarding as W,withMachine as J}from"../../peer/forward.js";import{getById as T}from"../../../core/graph/objects.js";import{ensureNodeStub as Qe,isStub as Q,stubOf as Ye,withKindDecl as $}from"../../../core/peer/stubs.js";import{isUnreachable as Xe}from"../../../core/peer/client.js";import{normalizeMachineId as A}from"../../../core/peer/directory.js";import{mapAsync as we}from"../../../core/async-array.js";const F=l(async e=>async t=>await Ue(e,t),"reposFnFor");async function me(e,t){return{...await b(e,t),...await(await B(e,t.type)).listItem?.(e,t)}}l(me,"listItem");function xe(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}l(xe,"remoteMessage");async function he(e,t,n){try{return await R(e,t,n)}catch(a){if(a instanceof p&&a.code==="not_found"&&!a.details?.deleted)return null;throw a}}l(he,"ownerFilter");async function R(e,t,n){const a=await K(e,t,n);if("remote"in a)throw new p(404,"not_found",xe(a.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in a)throw new p(404,"not_found",`${a.deleted.name} is deleted`,{id:a.deleted.id,deleted:!0});return a}l(R,"liveRef");const _=l(e=>decodeURIComponent(e.params.ref),"refParam"),pe=l(e=>{const t=ae(e),n=t.indexOf("/");return n>0?t.slice(0,n):t},"idOf");async function ye(e){const t=await T(await E(),pe(e));return t!==null&&await Q(await E(),t)?t.id:null}l(ye,"stubIdOf");async function et(e,t){const n=await ye(e);return n!==null?{stub:n,hit:!0}:await j(async a=>{try{const i=await O(a,t),o=l(async()=>{const s=await Se(a,i,e);if(s.length>1)throw new p(409,"ambiguous_name",`'${e}' names more than one remote object`,{candidates:s.map(c=>c.id),next:"Read one by its object id."});return{stub:s[0]?.id??null,hit:!1}},"named");let r;try{r=await K(a,i,e)}catch(s){if(s instanceof p&&s.code==="not_found")return await o();throw s}if("remote"in r)return await o();if("deleted"in r){const s=await o();return s.stub===null?{stub:null,hit:!0}:s}return{stub:await Q(a,r)?r.id:null,hit:!0}}catch(i){if(i instanceof p&&i.code==="ambiguous_name")throw i;return{stub:null,hit:!1}}})}l(et,"resolvedLocally");async function Y(e,t,n){const a=await et(t,e);if(a.stub!==null)return le(e,a.stub,n);if(a.hit||!fe(e.principal))return{kind:"local"};const i=await le(e,pe(t),n);return i.kind==="local"&&ae(t).includes("/")?Ze(e,n,{method:"GET",path:z(t),query:G(e)}):i}l(Y,"forwardRef");const z=l(e=>`/v1/objects/${encodeURIComponent(e)}`,"objectPath");async function be(e,t,n,a,i){const o=t?.object;!o?.id||!o.type||await j(async r=>{const s=await ce(r,e);if(s===null)return;const c=await Je(r,o.id,o.type,n,{kind:o.kind??null,name:o.name??o.id,...o.preview===void 0?{}:{preview:o.preview},owner:o.owner??null,...o.kind_decl===void 0?{}:{kind_decl:o.kind_decl},...o.privacy===void 0?{}:{privacy:o.privacy}});await C(r,s,c,a,i===void 0?{}:{patterns:i}),a==="ask"&&await D(r,s,c)})}l(be,"watchRemote");async function tt(e){const t=_(e),n=["1","true"].includes(e.query.get("fields")??""),a=await Y(e,t,{method:"GET",path:z(t),query:G(e)});if(a.kind==="unknown")return{state:"unknown",ref:t,unreachable:a.unreachable};if(a.kind==="remote"){if(a.status>=400)throw U(a.status,a.body);return await be(e,a.body,a.machine.id,"read"),J(a.body,a.machine)}const i=l(async s=>{const c=await Z(s,e);return c===null?await O(s,e):await L(s,c,await F(s))},"readerOf"),o=await j(async s=>{const c=await i(s),u=await K(s,c,t);if("remote"in u)return{state:"remote",remote:u.remote};if("deleted"in u)return{state:"deleted",deleted:await b(s,u.deleted)};const w=await ue(s,u);if(w!==null)return{delegate:w,hitId:u.id};const{data:h,text:y}=await(await B(s,u.type)).read(s,c,u,{fields:n,reposFn:await F(s)});return{state:"object",type:u.type,object:await $(s,u,await b(s,u)),text:y,data:h}});if(!("delegate"in o))return o;const r=await Ke(o.delegate,e.principal);return await j(async s=>{const c=await i(s),u=await T(s,o.hitId);if(u===null)throw new p(404,"not_found","object not found");if(u.deleted_at!==null)return{state:"deleted",deleted:await b(s,u)};if(!await P(s,c,u))throw new p(404,"not_found","object not found");const{data:w,text:h}=await(await B(s,u.type)).read(s,c,u,{fields:n,reposFn:await F(s)});return await ue(s,u)===null?{state:"object",type:u.type,object:await $(s,u,await b(s,u)),text:h,data:w}:{state:"object",type:u.type,object:await $(s,u,await b(s,u)),text:"markdown"in r?r.markdown:`${h}
2
- content unavailable: ${r.unavailable}`,data:{...w,content:"markdown"in r?"live":"unavailable"}}})}l(tt,"read");function X(e,t,n,a){if(e!=null){if(!n.includes(e)){a.push({field:t,problem:`must be one of ${n.join(", ")}`,received:e});return}return e}}l(X,"oneOf");async function ge(e,t,n){if(t!=null){if(typeof t!="string"||!await De(e,t)){n.push({field:"type",problem:`must be a kind: one of ${(await Me(e)).join(", ")}`,received:t});return}return t}}l(ge,"kindName");function je(e,t,n,a){if(e==null)return a;const i=Number(e);return!Number.isInteger(i)||i<1||i>100?(n.push({field:t,problem:"must be an integer from 1 to 100",received:e}),a):i}l(je,"limitOf");async function _e(e){const t=e.query,n=[],a=await ge(await E(),t.get("type"),n),i=X(t.get("privacy"),"privacy",$e,n),o=je(t.get("limit"),"limit",n,50),r=t.get("cursor");r!==null&&!/^\d+$/.test(r)&&n.push({field:"cursor",problem:"is not a cursor from a previous page",received:r});const s=t.get("deleted");return s!==null&&!["0","1","true","false"].includes(s)&&n.push({field:"deleted",problem:"must be true or false",received:s}),n.length>0&&M("object list request",n),await j(async c=>{const u=await O(c,e),w={...a?{type:a}:{},...i?{privacy:i}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...s==="1"||s==="true"?{deleted:!0}:{}},h=t.get("owner");if(h!==null){const m=await he(c,u,h);if(m===null)return{items:[],next_cursor:null};w.owner=m}const y=t.get("name"),g=[];let v=r===null?0:Number(r),f=!0;for(;g.length<o&&f;){const m=await Ge(c,u,w,{limit:100,after_seq:v});f=m.length===100;for(const q of m)if(v=q.seq,(y===null||q.name.startsWith(y))&&g.push(q),g.length===o)break}const d=g.at(-1);return{items:await we(g,async m=>await me(c,m)),next_cursor:g.length===o&&d?String(d.seq):null}})}l(_e,"listLocal");const nt={ms:3e4},at="self",x=l((e,t)=>e.map(n=>({...n,machine:t})),"labelItems");async function ke(e,t,n,a){const i=W.current;try{const o=await i.call(t.id,{method:"GET",path:"/v1/objects",query:n},await i.envelope(e.principal),a);if(Xe(o))return{state:"unreachable",items:[],next:null};if(o.status===426)return{state:"too_old",items:[],next:null};const r=o.body;return o.status!==200||!Array.isArray(r?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:x(r.items,t),next:r.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}l(ke,"remotePage");async function it(e){const t=new Promise(n=>e.addEventListener("abort",()=>n(null),{once:!0}));return Promise.race([W.current.machines().catch(()=>null),t])}l(it,"machinesWithin");async function rt(e){const t=e.query.get("machine");if(!fe(e.principal)||!W.current.joined()||t===at)return await _e(ve(e));const a=W.current.self(),i=t!==null&&A(t)!==a,o=i?null:await _e(ve(e)),r=new AbortController,s=setTimeout(()=>r.abort(),nt.ms);s.unref?.();try{const c=await it(r.signal);if(c===null){if(i)throw new p(503,"runtime_unreachable",`The directory did not answer, so ${A(t)} cannot be listed.`,{machine:A(t)});return o}const u=l(d=>({id:d,name:c.find(m=>m.machine_id===d)?.name??d}),"labelOf"),w=u(a),h=c.filter(d=>d.machine_id!==a&&d.kind!=="device"),y=G(e);if(t!==null){if(!i)return{items:x(o.items,w),next_cursor:o.next_cursor,machines:[{machine_id:a,name:w.name,state:"ok",more:o.next_cursor!==null}]};const d=A(t);if(!h.some(q=>q.machine_id===d))throw new p(404,"not_found",`no machine ${d} on your account`,{machine:d});const m=await ke(e,u(d),y,r.signal);return{items:m.items,next_cursor:m.next,machines:[{machine_id:d,name:u(d).name,state:m.state,more:m.next!==null}]}}const{cursor:g,...v}=y,f=await Promise.all(h.map(d=>ke(e,u(d.machine_id),v,r.signal)));return{items:[...x(o.items,w),...f.flatMap(d=>d.items)],next_cursor:o.next_cursor,machines:[{machine_id:a,name:w.name,state:"ok",more:o.next_cursor!==null},...h.map((d,m)=>({machine_id:d.machine_id,name:d.name,state:f[m].state,more:f[m].next!==null}))]}}finally{clearTimeout(s)}}l(rt,"list");function ve(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}l(ve,"withoutMachine");async function ot(e){const t=[],n=N(e.body)?e.body:{};N(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const a=n.text;(typeof a!="string"||a.trim()==="")&&t.push({field:"text",problem:"is required",received:a});const i=n.grep;if(i!==void 0)if(typeof i!="string")t.push({field:"grep",problem:"must be a regular expression string",received:i});else try{new RegExp(i)}catch(f){t.push({field:"grep",problem:`is not a valid regular expression: ${f.message}`,received:i})}n.body!==void 0&&typeof n.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:n.body});const o=await ge(await E(),n.type,t);n.kind!==void 0&&typeof n.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:n.kind}),n.owner!==void 0&&typeof n.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:n.owner});const r=je(n.limit,"limit",t,50);t.length>0&&M("object search request",t);const s=await j(async f=>{const d=await O(f,e),m=typeof n.owner=="string"?await he(f,d,n.owner):null;return{reader:d,owner:m}}),{reader:c,owner:u}=s;if(typeof n.owner=="string"&&u===null)return{items:[]};const w=await E(),h=await se(w,c,{text:a,body:n.body===!0||typeof i=="string"}),y=new Set(h.map(f=>f.object.id)),v=(typeof i=="string"?(await se(w,c,{text:i,grep:!0})).filter(f=>y.has(f.object.id)):h).filter(f=>(!o||f.object.type===o)&&(n.kind===void 0||f.object.kind===n.kind)&&(!u||f.object.owner===u.id));return{items:await we(v.slice(0,r),async f=>({object:await me(w,f.object),...f.line!==void 0?{matches:[{line:f.line,text:f.text??""}]}:{}}))}}l(ot,"search");const Oe=["interrupt","steer","after-turn","next-turn"],st=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function ut(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(n=>typeof n!="string"||!st.test(n)||n.includes(">")&&!n.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}l(ut,"patternsOf");function ct(e,t){if(e===void 0)return;if(!N(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const n=[];for(const[a,i]of Object.entries(e)){const o=Number(a);!Number.isInteger(o)||o<1||o>10?t.push({field:`config.${a}`,problem:"level must be an integer from 1 to 10"}):Oe.includes(i)?n.push({threshold:o,delivery:i}):t.push({field:`config.${a}`,problem:`delivery must be one of ${Oe.join(", ")}`,received:i})}return n.sort((a,i)=>i.threshold-a.threshold)}l(ct,"configOf");async function qe(e){const t=await ye(e);if(t!==null)throw new p(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}l(qe,"refuseStubWatch");async function ee(e,t){const n=await T(e,t)??await(async()=>{const a=await Fe(e,await Ae(e,{class:"person"},async()=>[]),t);return"object"in a?a.object:null})();return n===null||n.deleted_at!==null||!(n.type.includes(".")||n.type==="node")?null:n}l(ee,"findWatcher");const k=l(()=>{throw new p(404,"not_found","watcher not found")},"watcherNotFound");async function Ee(e,t,n){if(typeof t!="string"||n===void 0||n===null)return null;if(typeof n!="string")throw new p(400,"invalid_request","invalid watcher_machine");if(await ee(e,t)!==null)return null;const a=W.current;let i;try{i=await a.machines()}catch{throw new p(503,"runtime_unreachable","The directory did not answer, so the watcher machine cannot be checked.")}const o=A(n);return(o===a.self()||!i.some(r=>A(r.machine_id)===o))&&k(),o}l(Ee,"remoteWatcherMachine");async function Te(e,t,n,a){if(t.publishToken||t.principal.class==="anonymous")return k();const i=await O(e,t);if(i.class==="person")return k();let o;try{o=await R(e,i,a)}catch{return k()}const r=o.owner===null?null:await T(e,o.owner);return r===null||!await ie(e,i,r)||!await Le(e,i,"link",n)||(await Pe(e,n)).id===i.app.id&&!(await P(e,i,n)&&await P(e,await L(e,n),o))?k():(await H(e,t,n),{actor:i.app,object:o})}l(Te,"linkWatcher");async function Re(e,t,n){if(t.publishToken)return!0;if(t.principal.class==="anonymous"||!n.type.includes("."))return!1;const a=await O(e,t),i=n.owner===null?null:await T(e,n.owner);return i!==null&&await ie(e,a,i)&&await We(e,a,n)}l(Re,"ownsWatcher");async function lt(e){const t=_(e),n=N(e.body)?e.body:{};if(typeof n.watcher=="string"&&await qe(t),typeof n.watcher!="string"){const i=await Y(e,t,{method:"POST",path:`${z(t)}/watch`,body:e.body});if(i.kind==="unknown")throw de(t,i.unreachable);if(i.kind==="remote"){if(i.status>=400)throw U(i.status,i.body);const o=i.body.patterns;return await be(e,i.body,i.machine.id,"ask",o),J(i.body,i.machine)}}const a=await Ee(await E(),n.watcher,n.watcher_machine);return await ft(e,a)}l(lt,"watch");async function ft(e,t=null){const n=[],a=e.body===void 0?{}:N(e.body)?e.body:(n.push({field:"body",problem:"must be an object"}),{}),i=ut(a.patterns,n),o=ct(a.config,n);return a.filter!==void 0&&!N(a.filter)&&n.push({field:"filter",problem:"must be an object",received:a.filter}),a.watcher!==void 0&&typeof a.watcher!="string"&&n.push({field:"watcher",problem:"must be a custom-object ref",received:a.watcher}),a.watcher_machine!==void 0&&typeof a.watcher_machine!="string"&&n.push({field:"watcher_machine",problem:"must be a machine id",received:a.watcher_machine}),n.length>0&&M("watch request",n),await j(async r=>{const s=typeof a.watcher=="string";if((e.publishToken||e.principal.class==="anonymous")&&!s)throw new p(404,"not_found","watcher not found");const c=i??[">"],u={patterns:c,...o?{config:o}:{},...a.filter!==void 0?{filter:a.filter}:{}};if(s){const g=a.watcher,v=t===null?null:await dt(r,e,g,t),f=v??(e.publishToken?await re(r,g):await ee(r,g));if(f===null)return k();if(v===null&&await Re(r,e,f)){const q=await oe(r,e,f);await H(r,e,f);const te=await L(r,f),I=await R(r,te,_(e));if(!await P(r,te,I))throw new p(404,"not_found","object not found");return await C(r,f,I,"act",u),await D(r,f,I),await V(r,{event:"watched",object:I,actor:q,attrs:{}},await F(r)),{object:await $(r,I,await b(r,I)),patterns:c}}const{actor:d,object:m}=await Te(r,e,f,_(e));return await C(r,f,m,"act",{...u,linkApp:d}),await D(r,f,m),await V(r,{event:"watched",object:m,actor:d,attrs:{}},await F(r)),{object:await $(r,m,await b(r,m)),patterns:c}}const w=await O(r,e),h=await Z(r,e)??ne(w),y=await R(r,w,_(e));return await C(r,h,y,"ask",u),await D(r,h,y),await V(r,{event:"watched",object:y,actor:h,attrs:{}},await F(r)),{object:await $(r,y,await b(r,y)),patterns:c}})}l(ft,"watchLocal");async function dt(e,t,n,a){return t.publishToken||t.principal.class==="anonymous"?k():await Qe(e,n,a)}l(dt,"ensureNodeStubFor");async function Ie(e,t,n,a){const i=l(async()=>(await e.prepare(`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.watch_id = s.watch
3
- WHERE w.watcher = ? AND w.object = ?`).get(t.id,n.id)).n,"count"),o=await i();await ze(e,t,n,a??void 0);const r=await i();return r===0&&await Be(e,t,n),{object:await b(e,n),removed:o-r}}l(Ie,"dropWatch");async function wt(e){const t=_(e);if(e.query.get("watcher")&&await qe(t),!e.query.get("watcher")){const a=await Y(e,t,{method:"DELETE",path:`${z(t)}/watch`,query:G(e)});if(a.kind==="unknown")throw de(t,a.unreachable);if(a.kind==="remote"){const i=a.status===404?a.body.error?.details:void 0,o=i?.deleted===!0?i.id:void 0;if(a.status>=400&&o===void 0)throw U(a.status,a.body);const r=o??a.body.object?.id,s=await j(async c=>{const u=await ce(c,e),w=r===void 0?null:await T(c,r);return u===null||w===null||!await Q(c,w)?null:await Ie(c,u,w,e.query.get("pattern"))});if(o!==void 0){if(s===null)throw U(a.status,a.body);return{...s,machine:a.machine}}return J(a.body,a.machine)}}const n=await Ee(await E(),e.query.get("watcher")??void 0,e.query.get("watcher_machine")??void 0);return await mt(e,n)}l(wt,"unwatchRoute");async function mt(e,t=null){const n=e.query.get("pattern"),a=e.query.get("watcher");return await j(async i=>{if((e.publishToken||e.principal.class==="anonymous")&&!a)throw new p(404,"not_found","watcher not found");const o=l(async(c,u)=>await Ie(i,c,u,n),"drop");if(a){const c=t===null?null:await(async()=>{const w=await T(i,a);return w!==null&&await Ye(i,w)!==null?w:null})();if(t!==null&&c===null)return k();const u=c??(e.publishToken?await re(i,a):await ee(i,a));return u===null?k():c===null&&await Re(i,e,u)?(await oe(i,e,u),await H(i,e,u),await o(u,await R(i,await L(i,u),_(e)))):await o(u,(await Te(i,e,u,_(e))).object)}const r=await O(i,e),s=await Z(i,e)??ne(r);return await o(s,await R(i,r,_(e)))})}l(mt,"unwatchLocal");async function ht(e){const t=[],n=X(e.query.get("type"),"type",["acted-on","links-to","watches"],t),a=X(e.query.get("direction"),"direction",["out","in"],t);return t.length>0&&M("edges request",t),await j(async i=>{const o=await O(i,e),r=await R(i,o,_(e)),s=[];if(n!=="watches")for(const c of await Ce(i,o,r,{...n?{type:n}:{},direction:a??"both"}))s.push({type:c.type,src:await b(i,c.src),dst:await b(i,c.dst),...c.written_as?{written_as:c.written_as}:{}});if(n===void 0||n==="watches"){const c=[...a!=="in"?await Ve(i,o,r):[],...a!=="out"?await He(i,o,r):[]];for(const u of c)s.push({type:"watches",src:await b(i,u.watcher),dst:await b(i,u.object)})}return{items:s}})}l(ht,"edges");const S=l(e=>async t=>({status:200,body:await e(t)}),"ok"),Ut=[{method:"POST",pattern:"/v1/objects/search",handler:S(ot)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:S(ht)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:S(lt)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:S(wt)},{method:"GET",pattern:"/v1/objects/:ref",handler:S(tt)},{method:"GET",pattern:"/v1/objects",handler:S(rt)}];export{nt as listBudget,Ut as objectRoutes};
1
+ var $e=Object.defineProperty;var l=(e,t)=>$e(e,"name",{value:t,configurable:!0});import{ApiError as y}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as Fe}from"../../../api/dto/objects.js";import{openDb as R,withCanvasWrite as v}from"../../../core/canvas/db.js";import{actorOf as ne}from"../../../core/graph/documents.js";import{readerForObject as P,readerFor as Ae}from"../../../core/graph/reader.js";import{resolveName as We,stubsNamed as Le,unwrapRef as ae}from"../../../core/graph/names.js";import{canRead as C,holdsObjectsScope as Pe,spaceOf as Ce}from"../../../core/graph/access.js";import{customReachable as De,mayActAs as ie}from"../../../core/graph/custom.js";import{customObjectRef as re,authorizeCustom as oe,fenceArgv as V}from"./custom-objects.js";import{edgesOf as Me}from"../../../core/graph/edges.js";import{publish as J}from"../../../core/graph/events.js";import{objectDTO as Ge}from"../../../core/graph/kinds/dto.js";import{isKind as Ue,kindNames as He,kindOf as B}from"../../../core/graph/kinds/registry.js";import{listObjects as ze,searchObjects as se}from"../../../core/graph/objects.js";import{checkoutsForCwd as Ve}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as D,unwatch as Je,watchersOf as Be,watchesOf as Ke}from"../../../core/graph/watches.js";import{armObjectWaitForWatch as M,settleObjectWaitForUnwatch as Ze}from"../../../core/graph/object-waits.js";import{readerFor as T,resolveRef as K}from"../reader.js";import{readDelegationFor as ue,runReadLeaf as Qe}from"../../plugin-objects/read-leaf.js";import{invalidRequest as G,isRecord as q}from"./validate.js";import{callerNode as ce,callerStub as Z,forwardNamed as Ye,forwardVerb as le,originates as fe,queryWithoutMachine as U,relayError as H,remoteStub as Xe,unknownError as de,forwarding as L,withMachine as Q}from"../../peer/forward.js";import{getById as N}from"../../../core/graph/objects.js";import{ensureNodeStub as xe,isStub as Y,stubOf as et,withKindDecl as S}from"../../../core/peer/stubs.js";import{isUnreachable as tt}from"../../../core/peer/client.js";import{normalizeMachineId as $}from"../../../core/peer/directory.js";import{mapAsync as nt}from"../../../core/async-array.js";const F=l(async e=>async t=>await Ve(e,t),"reposFnFor");async function g(e,t){return{...await Ge(e,t),...t.type==="document"?{schema_type:t.schema_type??null}:{}}}l(g,"objectDTO");async function at(e,t){const n=t.filter(r=>r.type==="document").map(r=>r.id),a=new Map;if(n.length===0)return a;const i=await e.prepareUncached(`SELECT object, extensions_json FROM documents WHERE object IN (${n.map(()=>"?").join(", ")})`).all(...n);for(const r of i)r.extensions_json!==null&&a.set(r.object,JSON.parse(r.extensions_json));return a}l(at,"extensionsOf");async function we(e,t){const n=await at(e,t);return await nt(t,async a=>({...await g(e,a),...await(await B(e,a.type)).listItem?.(e,a),...a.type==="document"?{extensions:n.get(a.id)??{}}:{}}))}l(we,"listItems");function it(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}l(it,"remoteMessage");async function me(e,t,n){try{return await I(e,t,n)}catch(a){if(a instanceof y&&a.code==="not_found"&&!a.details?.deleted)return null;throw a}}l(me,"ownerFilter");async function I(e,t,n){const a=await K(e,t,n);if("remote"in a)throw new y(404,"not_found",it(a.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in a)throw new y(404,"not_found",`${a.deleted.name} is deleted`,{id:a.deleted.id,deleted:!0});return a}l(I,"liveRef");const O=l(e=>decodeURIComponent(e.params.ref),"refParam"),he=l(e=>{const t=ae(e),n=t.indexOf("/");return n>0?t.slice(0,n):t},"idOf");async function pe(e){const t=await N(await R(),he(e));return t!==null&&await Y(await R(),t)?t.id:null}l(pe,"stubIdOf");async function rt(e,t){const n=await pe(e);return n!==null?{stub:n,hit:!0}:await v(async a=>{try{const i=await T(a,t),r=l(async()=>{const s=await Le(a,i,e);if(s.length>1)throw new y(409,"ambiguous_name",`'${e}' names more than one remote object`,{candidates:s.map(c=>c.id),next:"Read one by its object id."});return{stub:s[0]?.id??null,hit:!1}},"named");let o;try{o=await K(a,i,e)}catch(s){if(s instanceof y&&s.code==="not_found")return await r();throw s}if("remote"in o)return await r();if("deleted"in o){const s=await r();return s.stub===null?{stub:null,hit:!0}:s}return{stub:await Y(a,o)?o.id:null,hit:!0}}catch(i){if(i instanceof y&&i.code==="ambiguous_name")throw i;return{stub:null,hit:!1}}})}l(rt,"resolvedLocally");async function X(e,t,n){const a=await rt(t,e);if(a.stub!==null)return le(e,a.stub,n);if(a.hit||!fe(e.principal))return{kind:"local"};const i=await le(e,he(t),n);return i.kind==="local"&&ae(t).includes("/")?Ye(e,n,{method:"GET",path:z(t),query:U(e)}):i}l(X,"forwardRef");const z=l(e=>`/v1/objects/${encodeURIComponent(e)}`,"objectPath");async function ye(e,t,n,a,i){const r=t?.object;!r?.id||!r.type||await v(async o=>{const s=await ce(o,e);if(s===null)return;const c=await Xe(o,r.id,r.type,n,{kind:r.kind??null,name:r.name??r.id,...r.preview===void 0?{}:{preview:r.preview},owner:r.owner??null,...r.kind_decl===void 0?{}:{kind_decl:r.kind_decl},...r.privacy===void 0?{}:{privacy:r.privacy}});await D(o,s,c,a,i===void 0?{}:{patterns:i}),a==="ask"&&await M(o,s,c)})}l(ye,"watchRemote");async function ot(e){const t=O(e),n=["1","true"].includes(e.query.get("fields")??""),a=await X(e,t,{method:"GET",path:z(t),query:U(e)});if(a.kind==="unknown")return{state:"unknown",ref:t,unreachable:a.unreachable};if(a.kind==="remote"){if(a.status>=400)throw H(a.status,a.body);return await ye(e,a.body,a.machine.id,"read"),Q(a.body,a.machine)}const i=l(async s=>{const c=await Z(s,e);return c===null?await T(s,e):await P(s,c,await F(s))},"readerOf"),r=await v(async s=>{const c=await i(s),u=await K(s,c,t);if("remote"in u)return{state:"remote",remote:u.remote};if("deleted"in u)return{state:"deleted",deleted:await g(s,u.deleted)};const f=await ue(s,u);if(f!==null)return{delegate:f,hitId:u.id};const{data:w,text:b}=await(await B(s,u.type)).read(s,c,u,{fields:n,reposFn:await F(s)});return{state:"object",type:u.type,object:await S(s,u,await g(s,u)),text:b,data:w}});if(!("delegate"in r))return r;const o=await Qe(r.delegate,e.principal);return await v(async s=>{const c=await i(s),u=await N(s,r.hitId);if(u===null)throw new y(404,"not_found","object not found");if(u.deleted_at!==null)return{state:"deleted",deleted:await g(s,u)};if(!await C(s,c,u))throw new y(404,"not_found","object not found");const{data:f,text:w}=await(await B(s,u.type)).read(s,c,u,{fields:n,reposFn:await F(s)});return await ue(s,u)===null?{state:"object",type:u.type,object:await S(s,u,await g(s,u)),text:w,data:f}:{state:"object",type:u.type,object:await S(s,u,await g(s,u)),text:"markdown"in o?o.markdown:`${w}
2
+ content unavailable: ${o.unavailable}`,data:{...f,content:"markdown"in o?"live":"unavailable"}}})}l(ot,"read");function x(e,t,n,a){if(e!=null){if(!n.includes(e)){a.push({field:t,problem:`must be one of ${n.join(", ")}`,received:e});return}return e}}l(x,"oneOf");async function be(e,t,n){if(t!=null){if(typeof t!="string"||!await Ue(e,t)){n.push({field:"type",problem:`must be a kind: one of ${(await He(e)).join(", ")}`,received:t});return}return t}}l(be,"kindName");function ge(e,t,n,a){if(e==null)return a;const i=Number(e);return!Number.isInteger(i)||i<1||i>100?(n.push({field:t,problem:"must be an integer from 1 to 100",received:e}),a):i}l(ge,"limitOf");function je(e,t){if(e==null)return;let n=e;if(typeof e=="string")try{n=JSON.parse(e)}catch{n=null}if(!q(n)||Object.values(n).some(a=>!q(a))){t.push({field:"extensions",problem:'must be an object of objects, e.g. {"firstlight":{"state":"active"}}',received:e});return}return n}l(je,"extensionsParam");function _e(e,t){if(e!=null){if(typeof e!="string"||e===""){t.push({field:"schema_type",problem:"must be a non-empty string",received:e});return}return e}}l(_e,"schemaTypeParam");async function ke(e){const t=e.query,n=[],a=await be(await R(),t.get("type"),n),i=x(t.get("privacy"),"privacy",Fe,n),r=ge(t.get("limit"),"limit",n,50),o=t.get("cursor");o!==null&&!/^\d+$/.test(o)&&n.push({field:"cursor",problem:"is not a cursor from a previous page",received:o});const s=t.get("deleted");s!==null&&!["0","1","true","false"].includes(s)&&n.push({field:"deleted",problem:"must be true or false",received:s});const c=t.get("shared");c!==null&&!["0","1","true","false"].includes(c)&&n.push({field:"shared",problem:"must be true or false",received:c});const u=je(t.get("extensions"),n),f=_e(t.get("schema_type"),n);return n.length>0&&G("object list request",n),await v(async w=>{const b=await T(w,e),j={...a?{type:a}:{},...i?{privacy:i}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...s==="1"||s==="true"?{deleted:!0}:{},...c==="1"||c==="true"?{shared:!0}:{},...u?{extensions:u}:{},...f?{schemaType:f}:{},...t.get("name")!==null?{namePrefix:t.get("name")}:{}},k=t.get("owner");if(k!==null){const m=await me(w,b,k);if(m===null)return{items:[],next_cursor:null};j.owner=m}const h=await ze(w,b,j,{limit:r,after_seq:o===null?0:Number(o)}),d=h.at(-1);return{items:await we(w,h),next_cursor:h.length===r&&d?String(d.seq):null}})}l(ke,"listLocal");const st={ms:3e4},ut="self",ee=l((e,t)=>e.map(n=>({...n,machine:t})),"labelItems");async function ve(e,t,n,a){const i=L.current;try{const r=await i.call(t.id,{method:"GET",path:"/v1/objects",query:n},await i.envelope(e.principal),a);if(tt(r))return{state:"unreachable",items:[],next:null};if(r.status===426)return{state:"too_old",items:[],next:null};const o=r.body;return r.status!==200||!Array.isArray(o?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:ee(o.items,t),next:o.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}l(ve,"remotePage");async function ct(e){const t=new Promise(n=>e.addEventListener("abort",()=>n(null),{once:!0}));return Promise.race([L.current.machines().catch(()=>null),t])}l(ct,"machinesWithin");async function lt(e){const t=e.query.get("machine");if(!fe(e.principal)||!L.current.joined()||t===ut)return await ke(Oe(e));const a=L.current.self(),i=t!==null&&$(t)!==a,r=i?null:await ke(Oe(e)),o=new AbortController,s=setTimeout(()=>o.abort(),st.ms);s.unref?.();try{const c=await ct(o.signal);if(c===null){if(i)throw new y(503,"runtime_unreachable",`The directory did not answer, so ${$(t)} cannot be listed.`,{machine:$(t)});return r}const u=l(d=>({id:d,name:c.find(m=>m.machine_id===d)?.name??d}),"labelOf"),f=u(a),w=c.filter(d=>d.machine_id!==a&&d.kind!=="device"),b=U(e);if(t!==null){if(!i)return{items:ee(r.items,f),next_cursor:r.next_cursor,machines:[{machine_id:a,name:f.name,state:"ok",more:r.next_cursor!==null}]};const d=$(t);if(!w.some(W=>W.machine_id===d))throw new y(404,"not_found",`no machine ${d} on your account`,{machine:d});const m=await ve(e,u(d),b,o.signal);return{items:m.items,next_cursor:m.next,machines:[{machine_id:d,name:u(d).name,state:m.state,more:m.next!==null}]}}const{cursor:j,...k}=b,h=await Promise.all(w.map(d=>ve(e,u(d.machine_id),k,o.signal)));return{items:[...ee(r.items,f),...h.flatMap(d=>d.items)],next_cursor:r.next_cursor,machines:[{machine_id:a,name:f.name,state:"ok",more:r.next_cursor!==null},...w.map((d,m)=>({machine_id:d.machine_id,name:d.name,state:h[m].state,more:h[m].next!==null}))]}}finally{clearTimeout(s)}}l(lt,"list");function Oe(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}l(Oe,"withoutMachine");async function ft(e){const t=[],n=q(e.body)?e.body:{};q(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const a=n.text;(typeof a!="string"||a.trim()==="")&&t.push({field:"text",problem:"is required",received:a});const i=n.grep;if(i!==void 0)if(typeof i!="string")t.push({field:"grep",problem:"must be a regular expression string",received:i});else try{new RegExp(i)}catch(p){t.push({field:"grep",problem:`is not a valid regular expression: ${p.message}`,received:i})}n.body!==void 0&&typeof n.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:n.body});const r=await be(await R(),n.type,t);n.kind!==void 0&&typeof n.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:n.kind}),n.owner!==void 0&&typeof n.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:n.owner});const o=ge(n.limit,"limit",t,50),s=je(n.extensions,t),c=_e(n.schema_type,t);t.length>0&&G("object search request",t);const u=await v(async p=>{const _=await T(p,e),Se=typeof n.owner=="string"?await me(p,_,n.owner):null;return{reader:_,owner:Se}}),{reader:f,owner:w}=u;if(typeof n.owner=="string"&&w===null)return{items:[]};const b={...s?{extensions:s}:{},...c?{schemaType:c}:{},...r?{type:r}:{},...typeof n.kind=="string"?{kind:n.kind}:{},...w?{owner:w}:{}},j=await R(),k=await se(j,f,{text:a,body:n.body===!0||typeof i=="string",...b}),h=new Set(k.map(p=>p.object.id)),m=(typeof i=="string"?(await se(j,f,{text:i,grep:!0,...b})).filter(p=>h.has(p.object.id)):k).slice(0,o),W=await we(j,m.map(p=>p.object));return{items:m.map((p,_)=>({object:W[_],...p.line!==void 0?{matches:[{line:p.line,text:p.text??""}]}:{}}))}}l(ft,"search");const Ee=["interrupt","steer","after-turn","next-turn"],dt=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function wt(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(n=>typeof n!="string"||!dt.test(n)||n.includes(">")&&!n.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}l(wt,"patternsOf");function mt(e,t){if(e===void 0)return;if(!q(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const n=[];for(const[a,i]of Object.entries(e)){const r=Number(a);!Number.isInteger(r)||r<1||r>10?t.push({field:`config.${a}`,problem:"level must be an integer from 1 to 10"}):Ee.includes(i)?n.push({threshold:r,delivery:i}):t.push({field:`config.${a}`,problem:`delivery must be one of ${Ee.join(", ")}`,received:i})}return n.sort((a,i)=>i.threshold-a.threshold)}l(mt,"configOf");async function Te(e){const t=await pe(e);if(t!==null)throw new y(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}l(Te,"refuseStubWatch");async function te(e,t){const n=await N(e,t)??await(async()=>{const a=await We(e,await Ae(e,{class:"person"},async()=>[]),t);return"object"in a?a.object:null})();return n===null||n.deleted_at!==null||!(n.type.includes(".")||n.type==="node")?null:n}l(te,"findWatcher");const E=l(()=>{throw new y(404,"not_found","watcher not found")},"watcherNotFound");async function qe(e,t,n){if(typeof t!="string"||n===void 0||n===null)return null;if(typeof n!="string")throw new y(400,"invalid_request","invalid watcher_machine");if(await te(e,t)!==null)return null;const a=L.current;let i;try{i=await a.machines()}catch{throw new y(503,"runtime_unreachable","The directory did not answer, so the watcher machine cannot be checked.")}const r=$(n);return(r===a.self()||!i.some(o=>$(o.machine_id)===r))&&E(),r}l(qe,"remoteWatcherMachine");async function Re(e,t,n,a){if(t.publishToken||t.principal.class==="anonymous")return E();const i=await T(e,t);if(i.class==="person")return E();let r;try{r=await I(e,i,a)}catch{return E()}const o=r.owner===null?null:await N(e,r.owner);return o===null||!await ie(e,i,o)||!await Pe(e,i,"link",n)||(await Ce(e,n)).id===i.app.id&&!(await C(e,i,n)&&await C(e,await P(e,n),r))?E():(await V(e,t,n),{actor:i.app,object:r})}l(Re,"linkWatcher");async function Ne(e,t,n){if(t.publishToken)return!0;if(t.principal.class==="anonymous"||!n.type.includes("."))return!1;const a=await T(e,t),i=n.owner===null?null:await N(e,n.owner);return i!==null&&await ie(e,a,i)&&await De(e,a,n)}l(Ne,"ownsWatcher");async function ht(e){const t=O(e),n=q(e.body)?e.body:{};if(typeof n.watcher=="string"&&await Te(t),typeof n.watcher!="string"){const i=await X(e,t,{method:"POST",path:`${z(t)}/watch`,body:e.body});if(i.kind==="unknown")throw de(t,i.unreachable);if(i.kind==="remote"){if(i.status>=400)throw H(i.status,i.body);const r=i.body.patterns;return await ye(e,i.body,i.machine.id,"ask",r),Q(i.body,i.machine)}}const a=await qe(await R(),n.watcher,n.watcher_machine);return await pt(e,a)}l(ht,"watch");async function pt(e,t=null){const n=[],a=e.body===void 0?{}:q(e.body)?e.body:(n.push({field:"body",problem:"must be an object"}),{}),i=wt(a.patterns,n),r=mt(a.config,n);return a.filter!==void 0&&!q(a.filter)&&n.push({field:"filter",problem:"must be an object",received:a.filter}),a.watcher!==void 0&&typeof a.watcher!="string"&&n.push({field:"watcher",problem:"must be a custom-object ref",received:a.watcher}),a.watcher_machine!==void 0&&typeof a.watcher_machine!="string"&&n.push({field:"watcher_machine",problem:"must be a machine id",received:a.watcher_machine}),n.length>0&&G("watch request",n),await v(async o=>{const s=typeof a.watcher=="string";if((e.publishToken||e.principal.class==="anonymous")&&!s)throw new y(404,"not_found","watcher not found");const c=i??[">"],u={patterns:c,...r?{config:r}:{},...a.filter!==void 0?{filter:a.filter}:{}};if(s){const j=a.watcher,k=t===null?null:await yt(o,e,j,t),h=k??(e.publishToken?await re(o,j):await te(o,j));if(h===null)return E();if(k===null&&await Ne(o,e,h)){const W=await oe(o,e,h);await V(o,e,h);const p=await P(o,h),_=await I(o,p,O(e));if(!await C(o,p,_))throw new y(404,"not_found","object not found");return await D(o,h,_,"act",u),await M(o,h,_),await J(o,{event:"watched",object:_,actor:W,attrs:{}},await F(o)),{object:await S(o,_,await g(o,_)),patterns:c}}const{actor:d,object:m}=await Re(o,e,h,O(e));return await D(o,h,m,"act",{...u,linkApp:d}),await M(o,h,m),await J(o,{event:"watched",object:m,actor:d,attrs:{}},await F(o)),{object:await S(o,m,await g(o,m)),patterns:c}}const f=await T(o,e),w=await Z(o,e)??ne(f),b=await I(o,f,O(e));return await D(o,w,b,"ask",u),await M(o,w,b),await J(o,{event:"watched",object:b,actor:w,attrs:{}},await F(o)),{object:await S(o,b,await g(o,b)),patterns:c}})}l(pt,"watchLocal");async function yt(e,t,n,a){return t.publishToken||t.principal.class==="anonymous"?E():await xe(e,n,a)}l(yt,"ensureNodeStubFor");async function Ie(e,t,n,a){const i=l(async()=>(await e.prepare(`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.watch_id = s.watch
3
+ WHERE w.watcher = ? AND w.object = ?`).get(t.id,n.id)).n,"count"),r=await i();await Je(e,t,n,a??void 0);const o=await i();return o===0&&await Ze(e,t,n),{object:await g(e,n),removed:r-o}}l(Ie,"dropWatch");async function bt(e){const t=O(e);if(e.query.get("watcher")&&await Te(t),!e.query.get("watcher")){const a=await X(e,t,{method:"DELETE",path:`${z(t)}/watch`,query:U(e)});if(a.kind==="unknown")throw de(t,a.unreachable);if(a.kind==="remote"){const i=a.status===404?a.body.error?.details:void 0,r=i?.deleted===!0?i.id:void 0;if(a.status>=400&&r===void 0)throw H(a.status,a.body);const o=r??a.body.object?.id,s=await v(async c=>{const u=await ce(c,e),f=o===void 0?null:await N(c,o);return u===null||f===null||!await Y(c,f)?null:await Ie(c,u,f,e.query.get("pattern"))});if(r!==void 0){if(s===null)throw H(a.status,a.body);return{...s,machine:a.machine}}return Q(a.body,a.machine)}}const n=await qe(await R(),e.query.get("watcher")??void 0,e.query.get("watcher_machine")??void 0);return await gt(e,n)}l(bt,"unwatchRoute");async function gt(e,t=null){const n=e.query.get("pattern"),a=e.query.get("watcher");return await v(async i=>{if((e.publishToken||e.principal.class==="anonymous")&&!a)throw new y(404,"not_found","watcher not found");const r=l(async(c,u)=>await Ie(i,c,u,n),"drop");if(a){const c=t===null?null:await(async()=>{const f=await N(i,a);return f!==null&&await et(i,f)!==null?f:null})();if(t!==null&&c===null)return E();const u=c??(e.publishToken?await re(i,a):await te(i,a));return u===null?E():c===null&&await Ne(i,e,u)?(await oe(i,e,u),await V(i,e,u),await r(u,await I(i,await P(i,u),O(e)))):await r(u,(await Re(i,e,u,O(e))).object)}const o=await T(i,e),s=await Z(i,e)??ne(o);return await r(s,await I(i,o,O(e)))})}l(gt,"unwatchLocal");async function jt(e){const t=[],n=x(e.query.get("type"),"type",["acted-on","links-to","watches"],t),a=x(e.query.get("direction"),"direction",["out","in"],t);return t.length>0&&G("edges request",t),await v(async i=>{const r=await T(i,e),o=await I(i,r,O(e)),s=[];if(n!=="watches")for(const c of await Me(i,r,o,{...n?{type:n}:{},direction:a??"both"}))s.push({type:c.type,src:await g(i,c.src),dst:await g(i,c.dst),...c.written_as?{written_as:c.written_as}:{}});if(n===void 0||n==="watches"){const c=[...a!=="in"?await Ke(i,r,o):[],...a!=="out"?await Be(i,r,o):[]];for(const u of c)s.push({type:"watches",src:await g(i,u.watcher),dst:await g(i,u.object)})}return{items:s}})}l(jt,"edges");const A=l(e=>async t=>({status:200,body:await e(t)}),"ok"),Kt=[{method:"POST",pattern:"/v1/objects/search",handler:A(ft)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:A(jt)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:A(ht)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:A(bt)},{method:"GET",pattern:"/v1/objects/:ref",handler:A(ot)},{method:"GET",pattern:"/v1/objects",handler:A(lt)}];export{st as listBudget,Kt as objectRoutes};
@@ -0,0 +1,2 @@
1
+ import type { RouteTable } from '../router.js';
2
+ export declare const relationRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var v=Object.defineProperty;var u=(r,s)=>v(r,"name",{value:s,configurable:!0});import{ApiError as A}from"../../../api/errors.js";import{withCanvasWrite as y}from"../../../core/canvas/db.js";import{deleteFact as T,formatSubject as R,listFacts as S,parseResource as p,parseSubject as b,replaceSet as _,writeFact as $}from"../../../core/permissions/facts.js";import{invalidRequest as g,isRecord as f}from"./validate.js";import{appCaller as m,asApiError as d,requireOwnNamespace as l}from"./schemas.js";function q(r,s,t){return r===void 0?[]:Array.isArray(r)?r.filter((e,o)=>{const n=f(e)&&typeof e.resource=="string"&&typeof e.relation=="string"&&typeof e.subject=="string";return n||t.push({field:`${s}[${o}]`,problem:"must be {resource, relation, subject} strings"}),n}):(t.push({field:s,problem:"must be a list"}),[])}u(q,"facts");async function E(r){const{app:s}=m(r),t=[],e=f(r.body)?r.body:(t.push({field:"body",problem:"must be an object"}),{}),o=q(e.write,"write",t),n=q(e.delete,"delete",t);t.length>0&&g("relations request",t);try{return await y(async i=>{let h=0,j=0;for(const a of o){const c=p(a.resource);await l(i,s,c.type),await $(i,{resourceType:c.type,resourceId:c.id,relation:a.relation,subject:b(a.subject),writtenBy:s})&&h++}for(const a of n){const c=p(a.resource);await l(i,s,c.type),await T(i,{resourceType:c.type,resourceId:c.id,relation:a.relation,subject:b(a.subject)})&&j++}return{written:h,deleted:j}})}catch(i){throw d(i)}}u(E,"change");async function F(r){const{app:s}=m(r),t=[],e=f(r.body)?r.body:(t.push({field:"body",problem:"must be an object"}),{});typeof e.resource!="string"&&t.push({field:"resource",problem:"must be a string"}),typeof e.relation!="string"&&t.push({field:"relation",problem:"must be a string"}),(!Array.isArray(e.subjects)||e.subjects.some(o=>typeof o!="string"))&&t.push({field:"subjects",problem:"must be a list of strings"}),t.length>0&&g("relations replace request",t);try{return await y(async o=>{const n=p(e.resource);return await l(o,s,n.type),await _(o,n.type,n.id,e.relation,e.subjects.map(b),s)})}catch(o){throw d(o)}}u(F,"replace");async function k(r){const{app:s}=m(r),t=r.query.get("resource");if(t===null||t==="")throw new A(400,"invalid_request","`resource` is required");try{return await y(async e=>{const o=p(t);return await l(e,s,o.type),{items:(await S(e,o.type,o.id)).map(i=>({resource:`${o.type}:${o.id}`,relation:i.relation,subject:R({type:i.subject_type,id:i.subject_id,relation:i.subject_relation})}))}})}catch(e){throw d(e)}}u(k,"list");const w=u(r=>async s=>({status:200,body:await r(s)}),"ok"),N=[{method:"POST",pattern:"/v1/relations",handler:w(E)},{method:"PUT",pattern:"/v1/relations",handler:w(F)},{method:"GET",pattern:"/v1/relations",handler:w(k)}];export{N as relationRoutes};
@@ -0,0 +1,12 @@
1
+ import { type CanvasDb } from '../../../core/canvas/db.js';
2
+ import type { RequestContext, RouteTable } from '../router.js';
3
+ /** The calling app and, for the routes that act for one member, the person its call token names. Any other principal is refused. */
4
+ export declare function appCaller(ctx: RequestContext): {
5
+ app: string;
6
+ sub: string | undefined;
7
+ };
8
+ /** A resource type `<namespace>/<name>` must live in a namespace the caller registered. */
9
+ export declare function requireOwnNamespace(db: CanvasDb, app: string, type: string): Promise<void>;
10
+ /** Graph and permission refusals → the wire: a `PermissionError` carries its own status, code and details. */
11
+ export declare function asApiError(error: unknown): unknown;
12
+ export declare const schemaRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var o=Object.defineProperty;var r=(e,a)=>o(e,"name",{value:a,configurable:!0});import{ApiError as i}from"../../../api/errors.js";import{withCanvasWrite as p}from"../../../core/canvas/db.js";import{PermissionError as c}from"../../../core/permissions/errors.js";import{registerSchema as m,schemaOf as u}from"../../../core/permissions/schemas.js";import{invalidRequest as l,isRecord as f}from"./validate.js";function h(e){if(e.principal.class!=="app")throw new i(403,"app_only","only an app server calls this route");return{app:e.principal.app,sub:e.principal.sub}}r(h,"appCaller");async function O(e,a,s){const t=s.split("/")[0],n=s.includes("/")?await u(e,t):null;if(n===null||n.app!==a)throw new i(403,"not_schema_owner",`${s} is not in a namespace ${a} registered`,{type:s})}r(O,"requireOwnNamespace");function d(e){return e instanceof c?new i(e.status,e.code,e.message,e.details):e}r(d,"asApiError");async function b(e){const{app:a}=h(e),s=[],t=f(e.body)?e.body:(s.push({field:"body",problem:"must be an object"}),{});typeof t.namespace!="string"&&s.push({field:"namespace",problem:"must be a string"}),typeof t.source!="string"&&s.push({field:"source",problem:"must be a string"}),s.length>0&&l("schema register request",s);try{return await p(async n=>await m(n,a,t.namespace,t.source))}catch(n){throw d(n)}}r(b,"register");const R=[{method:"POST",pattern:"/v1/schemas",handler:r(async e=>({status:200,body:await b(e)}),"handler")}];export{h as appCaller,d as asApiError,O as requireOwnNamespace,R as schemaRoutes};
@@ -0,0 +1,2 @@
1
+ import type { RouteTable } from '../router.js';
2
+ export declare const shareRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var E=Object.defineProperty;var i=(e,r)=>E(e,"name",{value:r,configurable:!0});import{SHARE_VERBS as l}from"../../../api/dto/permissions.js";import{ApiError as c}from"../../../api/errors.js";import{openDb as v,withCanvasWrite as O}from"../../../core/canvas/db.js";import{joinedOwner as R}from"../../../core/directory/join.js";import{actorOf as g}from"../../../core/graph/documents.js";import{publish as T}from"../../../core/graph/events.js";import{GROUP_TYPE as $,OBJECT_TYPE as b,VERB_RELATION as h}from"../../../core/permissions/builtin.js";import{check as w,userOf as B}from"../../../core/permissions/evaluator.js";import{deleteFact as S,EVERYONE as y,formatSubject as d,listFacts as P,parseSubject as k,writeFact as q}from"../../../core/permissions/facts.js";import{readerFor as A,resolveRef as F}from"../reader.js";import{asApiError as V}from"./schemas.js";import{invalidRequest as Y,isRecord as C}from"./validate.js";const I={edit:["document"],message:["node","profile"],use:["environment"]};function D(e){if(e.startsWith("team:"))return{type:$,id:e,relation:"member"};const r=k(e);if(r.type!=="user"||r.relation!=="")throw new c(400,"invalid_subject","`subject` must be `user:<id>`, `team:<id>` or `user:*`");return r}i(D,"subjectOf");async function G(e,r,n){return r.principal.class==="broker"?`node:${r.principal.node}`:`user:${await B(e,n)}`}i(G,"writtenBy");async function j(e,r,n){const a=await A(e,r),t=await F(e,a,decodeURIComponent(r.params.ref));if("remote"in t||"deleted"in t)throw new c(404,"not_found","object not found");if(!await w(e,a,"share",t.id))throw await w(e,a,"read",t.id)?new c(403,"not_owner",`only the owner of ${t.name}, or the owner's agents, may share it`):new c(404,"not_found","object not found");const o=n===null?void 0:I[n];if(n!==null&&o!==void 0&&!o.includes(t.type))throw new c(400,"verb_not_applicable",`\`${n}\` applies to ${o.join(" and ")} objects; ${t.name} is a ${t.type}`,{verb:n,type:t.type});return{object:t,reader:a}}i(j,"shareable");function L(e,r){const n=[],a=C(e)?e:(n.push({field:"body",problem:"must be an object"}),{}),t=a.verb;return(typeof t!="string"||!l.includes(t))&&n.push({field:"verb",problem:`must be one of ${l.join(", ")}`,received:t}),typeof a.subject!="string"&&n.push({field:"subject",problem:"must be a string"}),n.length>0&&Y(r,n),{verb:t,subject:a.subject}}i(L,"parse");async function _(e,r){const{verb:n,subject:a}=L(r?e.body:Object.fromEntries(e.query),r?"share request":"share revoke request"),t=D(a);if(r&&t.id===y.id&&t.type===y.type&&R()===null)throw new c(400,"not_joined","sharing with everyone needs an install that has joined the directory; run `crtr sys join` first");const o=h[n];try{return await O(async s=>{const{object:u,reader:p}=await j(s,e,n),m={resourceType:b,resourceId:u.id,relation:o,subject:t},f=r?await q(s,{...m,writtenBy:await G(s,e,p)}):await S(s,m);return f&&await T(s,{event:r?"relation.written":"relation.deleted",object:u,actor:g(p),attrs:{resource:u.id,relation:o,subject:d(t)}}),{id:u.id,name:u.name,relation:o,subject:d(t),changed:f}})}catch(s){throw V(s)}}i(_,"change");async function N(e){const r=await v(),{object:n}=await j(r,e,null),a=new Map(Object.entries(h).map(([o,s])=>[s,o])),t=(await P(r,b,n.id)).filter(o=>a.has(o.relation)&&o.written_by!=="package").map(o=>({verb:a.get(o.relation),subject:d({type:o.subject_type,id:o.subject_id,relation:o.subject_relation}),written_by:o.written_by,created_at:o.created_at}));return{id:n.id,name:n.name,items:t}}i(N,"list");const re=[{method:"GET",pattern:"/v1/objects/:ref/shares",handler:i(async e=>({status:200,body:await N(e)}),"handler")},{method:"POST",pattern:"/v1/objects/:ref/shares",handler:i(async e=>({status:200,body:await _(e,!0)}),"handler")},{method:"DELETE",pattern:"/v1/objects/:ref/shares",handler:i(async e=>({status:200,body:await _(e,!1)}),"handler")}];export{re as shareRoutes};
@@ -1 +1 @@
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:"ready",method:"GET",path:"/v1/ready",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",stage:"objects"},{name:"objects.list",method:"GET",path:"/v1/objects",classes:["person","app","broker","cron","forwarded"],resource:"objects",stage:"objects"},{name:"objects.search",method:"POST",path:"/v1/objects/search",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"objects.watch",method:"POST",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron","forwarded"],resource:"objects",stage:"objects"},{name:"objects.unwatch",method:"DELETE",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron","forwarded"],resource:"objects",stage:"objects"},{name:"custom-objects.register",method:"POST",path:"/v1/custom-objects",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"custom-objects.publish",method:"POST",path:"/v1/custom-objects/:ref/events",classes:["anonymous","person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"custom-objects.unregister",method:"DELETE",path:"/v1/custom-objects/:ref",classes:["anonymous","person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"custom-objects.receive",method:"GET",path:"/v1/custom-objects/:ref/deliveries",classes:["anonymous","person","app","broker","cron"],resource:"objects",stream:!0,stage:"objects"},{name:"custom-objects.ack",method:"POST",path:"/v1/custom-objects/:ref/deliveries/ack",classes:["anonymous","person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"objects.edges",method:"GET",path:"/v1/objects/:ref/edges",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.write",method:"POST",path:"/v1/docs",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.edit",method:"PATCH",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.move",method:"POST",path:"/v1/docs/:ref/move",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.delete",method:"DELETE",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.history",method:"GET",path:"/v1/docs/:ref/history",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.lint",method:"POST",path:"/v1/docs/lint",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"plugins.app-token",method:"GET",path:"/v1/plugins/:name/app-token",classes:["person","broker"],resource:"none"},{name:"plugins.call-headers",method:"POST",path:"/v1/plugins/:name/call-headers",classes:["person","broker"],resource:"none"},{name:"documents.browser-access",method:"GET",path:"/v1/documents/browser-access",classes:["person"],resource:"none"},{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.read",method:"POST",path:"/v1/nodes/:id/read",classes:["person"],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.live-roots",method:"GET",path:"/v1/canvas/live-roots",classes:["person"],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:"question.cancel",method:"POST",path:"/v1/questions/:question_id/cancel",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"},{name:"runtime.vendor-account-remove",method:"POST",path:"/v1/runtime/vendor-account-remove",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
+ 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:"ready",method:"GET",path:"/v1/ready",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",stage:"objects"},{name:"objects.list",method:"GET",path:"/v1/objects",classes:["person","app","broker","cron","forwarded"],resource:"objects",stage:"objects"},{name:"objects.search",method:"POST",path:"/v1/objects/search",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"objects.watch",method:"POST",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron","forwarded"],resource:"objects",stage:"objects"},{name:"objects.unwatch",method:"DELETE",path:"/v1/objects/:ref/watch",classes:["anonymous","person","app","broker","cron","forwarded"],resource:"objects",stage:"objects"},{name:"objects.shares",method:"GET",path:"/v1/objects/:ref/shares",classes:["person","broker"],resource:"objects",stage:"objects"},{name:"objects.share",method:"POST",path:"/v1/objects/:ref/shares",classes:["person","broker"],resource:"objects",stage:"objects"},{name:"objects.unshare",method:"DELETE",path:"/v1/objects/:ref/shares",classes:["person","broker"],resource:"objects",stage:"objects"},{name:"custom-objects.register",method:"POST",path:"/v1/custom-objects",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"custom-objects.publish",method:"POST",path:"/v1/custom-objects/:ref/events",classes:["anonymous","person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"custom-objects.unregister",method:"DELETE",path:"/v1/custom-objects/:ref",classes:["anonymous","person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"custom-objects.receive",method:"GET",path:"/v1/custom-objects/:ref/deliveries",classes:["anonymous","person","app","broker","cron"],resource:"objects",stream:!0,stage:"objects"},{name:"custom-objects.ack",method:"POST",path:"/v1/custom-objects/:ref/deliveries/ack",classes:["anonymous","person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"objects.edges",method:"GET",path:"/v1/objects/:ref/edges",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.write",method:"POST",path:"/v1/docs",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.edit",method:"PATCH",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.move",method:"POST",path:"/v1/docs/:ref/move",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.delete",method:"DELETE",path:"/v1/docs/:ref",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"docs.history",method:"GET",path:"/v1/docs/:ref/history",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"schemas.register",method:"POST",path:"/v1/schemas",classes:["app"],resource:"objects",stage:"objects"},{name:"relations.write",method:"POST",path:"/v1/relations",classes:["app"],resource:"objects",stage:"objects"},{name:"relations.replace",method:"PUT",path:"/v1/relations",classes:["app"],resource:"objects",stage:"objects"},{name:"relations.list",method:"GET",path:"/v1/relations",classes:["app"],resource:"objects",stage:"objects"},{name:"check",method:"POST",path:"/v1/check",classes:["app"],resource:"objects",stage:"objects"},{name:"docs.lint",method:"POST",path:"/v1/docs/lint",classes:["person","app","broker","cron"],resource:"objects",stage:"objects"},{name:"plugins.app-token",method:"GET",path:"/v1/plugins/:name/app-token",classes:["person","broker"],resource:"none"},{name:"plugins.call-headers",method:"POST",path:"/v1/plugins/:name/call-headers",classes:["person","broker"],resource:"none"},{name:"documents.browser-access",method:"GET",path:"/v1/documents/browser-access",classes:["person"],resource:"none"},{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.read",method:"POST",path:"/v1/nodes/:id/read",classes:["person"],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.live-roots",method:"GET",path:"/v1/canvas/live-roots",classes:["person"],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:"question.cancel",method:"POST",path:"/v1/questions/:question_id/cancel",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"},{name:"runtime.vendor-account-remove",method:"POST",path:"/v1/runtime/vendor-account-remove",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,6 +1,5 @@
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';
4
3
  import type { AppPrincipal } from './principal.js';
5
4
  import { type Operation } from './operations.js';
6
5
  /** What the caller's bearer token may reach: `null` is the owner (every scope,
@@ -22,6 +21,7 @@ export type RequestPrincipal = {
22
21
  class: 'app';
23
22
  app: string;
24
23
  scopes: readonly string[];
24
+ sub?: string;
25
25
  } | {
26
26
  class: 'broker';
27
27
  app: string;
@@ -47,7 +47,10 @@ export type ForwardedPrincipal = {
47
47
  app: string;
48
48
  node: string | null;
49
49
  node_scopes: string[] | null;
50
- place: RunPlace;
50
+ place: {
51
+ run: string;
52
+ isolated: boolean;
53
+ };
51
54
  };
52
55
  };
53
56
  /** A peer call token with no envelope: the calling machine itself (`peer.*` rows only), never a person or an app. */
@@ -77,10 +80,11 @@ export declare function appOf(principal: RequestPrincipal): string | null;
77
80
  export declare function actsAsPerson(principal: RequestPrincipal): boolean;
78
81
  export declare function resolvedScopes(principal: RequestPrincipal): Promise<readonly string[]>;
79
82
  export declare function runCallerApp(principal: RequestPrincipal | AppPrincipal): string | null;
80
- /** Run confinement (Silas, 2026-09-30): a broker caller reaches a same-app node or
81
- * run only when it is in the caller's run, or neither run is isolated. `target`
82
- * omitted means no particular node (an app-wide question), which passes. */
83
- export declare function brokerMayReach(principal: RequestPrincipal | AppPrincipal, target: string | undefined, grantee: string): Promise<boolean>;
83
+ /** Whether the caller holds `permission` on a node: the evaluator, with the caller's ceiling (own-app run confinement, `objects` and
84
+ * `conversations` scopes, `objects:message`). A person caller passes the schema alone. */
85
+ export declare function mayOnNode(principal: RequestPrincipal | AppPrincipal, permission: 'read' | 'message', nodeId: string): Promise<boolean>;
86
+ /** The ids of the nodes the caller may read, in one query that embeds the evaluator's condition; null when the caller reads every node (the person). */
87
+ export declare function readableNodeIds(principal: RequestPrincipal): Promise<Set<string> | null>;
84
88
  export declare function canReadRun(principal: RequestPrincipal | AppPrincipal, grantee: string, target?: string): Promise<boolean>;
85
89
  export declare function requireRun(principal: RequestPrincipal | AppPrincipal, id: string, acting?: boolean, allowDeleting?: boolean): Promise<import("../../index.js").NodeMeta>;
86
90
  export declare function canReadNode(principal: RequestPrincipal, grantee: string, target?: string): Promise<boolean>;
@@ -1 +1 @@
1
- var j=Object.defineProperty;var u=(e,t)=>j(e,"name",{value:t,configurable:!0});import{toErrorBody as N}from"./map.js";import{emitEvent as U}from"../../core/events/emit.js";import{scopeAllowed as f,ScopeDeniedError as J}from"../../core/scopes.js";import{coveredByAny as p}from"../../shared/env.js";import{ApiError as c}from"../../api/errors.js";import{activeGrant as B,grantFor as S}from"../../core/grants/mirror.js";import{getNode as y}from"../../core/canvas/canvas.js";import{ownedRun as z,RunError as g}from"../../core/runs/operations.js";import{nodeMayReach as H,placeMayReach as R}from"../../core/runs/confinement.js";import{checkCronFire as M}from"../cron/authority.js";import{operationFor as I}from"./operations.js";import{CONTROL_BODY_MAX_BYTES as P}from"../../core/llm/body-limits.js";import{getRequest as F,getRequestByInboxTicket as L}from"../../core/human/requests.js";import{requireVisibleReview as q}from"../../core/review/store.js";import{getComment as O}from"../../core/review/comments.js";async function Y(e,t,o,s,r){const n=e.path,a=r&&typeof r=="object"&&!Array.isArray(r)?r:{};if(n==="/v1/human/requests"||n==="/v1/human/reviews"){const d=n.endsWith("/reviews")?a.origin_node_id:a.requester_node_id,h=n==="/v1/human/requests"&&d==null;if(d!==t.node&&!h)throw new c(403,"other_app_run","a broker may create a human request only for its own node");const i=a.source;if(i&&typeof i=="object"&&"nodeId"in i&&i.nodeId!==t.node)throw new c(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 c(403,"other_app_run","self review requires the calling node");if(n.includes("/comments")&&e.method!=="GET"&&a.actor_node_id!==t.node)throw new c(403,"other_app_run","comment author must be the calling node");if(o.comment_id&&!await O(o.comment_id))throw new c(404,"not_found","comment not found")}u(Y,"authorizeHumanBody");function _(e){return e.class==="broker"||e.class==="cron"}u(_,"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}u(b,"appOf");function $(e){return e.class==="person"||e.class==="forwarded"&&e.actor.kind==="person"}u($,"actsAsPerson");async function A(e){const t=await S(e.actor.app,e.sub);if(!t)throw new c(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);return t}u(A,"forwardedGrant");async 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}=await A(e),s=e.actor.node_scopes;return s===null?o:s.filter(r=>p(o,r))}if(e.class==="app")return e.scopes;if(e.class==="cron"){const o=await 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 c(401,"grant_revoked",o.message):new c(403,"scope_missing",o.message)}const t=e.grant?await B(e.grant):await S(e.app,e.sub);if(t&&t.grantee===e.app&&t.sub===e.sub)return t.resolved;throw new c(401,"grant_revoked","the node grant is not active")}u(v,"resolvedScopes");function k(e){return"class"in e?b(e):e.grantee}u(k,"runCallerApp");async function l(e,t,o){return t===void 0||!("class"in e)?!0:e.class==="cron"?await R({run:e.origin_run??"",isolated:e.isolated},e.app,t,o):e.class==="forwarded"?e.actor.kind!=="app"||await R(e.actor.place,e.actor.app,t,o):e.class!=="broker"?!0:await H(e.node,e.app,t,o)}u(l,"brokerMayReach");async function D(e,t,o){const s=k(e);if(s===t)return await l(e,o,t);if(s===null)return!0;const r="class"in e?null:await B(e.grant),n="class"in e?await v(e):r?.sub===e.sub&&r.grantee===e.grantee?r.resolved:[];return f(n,`crtr:conversations:read:${t}`)&&(!("class"in e)||!_(e)||f(e.scopes,`crtr:conversations:read:${t}`))}u(D,"canReadRun");async function be(e,t,o=!1,s=!1){const r=await y(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(!await D(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 await z(t,r.grantee,s)}u(be,"requireRun");async function C(e,t,o){return $(e)?!0:e.class==="anonymous"||e.class==="machine"?!1:b(e)===t?await l(e,o,t):f(await v(e),`crtr:objects:read:${t}`)&&(!_(e)||f(e.scopes,`crtr:objects:read:${t}`))}u(C,"canReadNode");const V=new Set(["messages.post.58","messages.post.59"]);async function X(e,t,o){if(!e.classes.includes(t.class)&&!(t.class!=="anonymous"&&t.class!=="machine"&&t.class!=="forwarded"&&e.classes.includes("anonymous")))throw new c(403,"permission_error","this operation is not available to the caller");if(t.class==="forwarded"&&t.actor.kind==="app"&&await A(t),t.class==="person"||t.class==="anonymous"||t.class==="machine"||$(t))return;const s=await v(t);if(e.scope&&(!f(s,e.scope)||_(t)&&!f(t.scopes,e.scope)))throw new c(403,"scope_missing",`missing scope ${e.scope}`);if(t.class==="app")return;const r=b(t);t.class==="broker"&&await K(e,t,o,s);const n=o.id;if((e.resource==="node-read"||e.resource==="node-write")&&n!==void 0){const a=await y(n);if(!a)return;if(e.resource==="node-write"&&a.grantee!==r&&!(V.has(e.name)&&f(s,`crtr:objects:message:${a.grantee??"app:terminal"}`)))throw new c(403,"other_app_run","cannot change another app's node");if(e.resource==="node-write"&&!await l(t,n,a.grantee??"app:terminal"))throw new c(404,"not_found","node not found");if(e.resource==="node-read"&&!await C(t,a.grantee??"app:terminal",n))throw new c(404,"not_found","node not found")}}u(X,"authorizeOperation");async function K(e,t,o,s){if(e.resource==="daemon-bash"&&(!f(s,"crtr:files:rw:user:.")||!f(t.scopes,"crtr:files:rw:user:.")))throw new c(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const n=e.path,a=e.method==="GET";if(!a&&(n.endsWith("/respond")||n.endsWith("/submit")||n.endsWith("/dismiss")||n.endsWith("/progress")||n.endsWith("/comment-ranges")||n.includes("/feedback-comments")))throw new c(403,"permission_error","only the person may answer or edit the human inbox");const d=o.request_id?await F(o.request_id):o.ticket_id?await L(o.ticket_id):null,h=o.comment_id?await O(o.comment_id):null,i=o.review_id?await q(o.review_id):h?await q(h.review_id):null,w=d?.requester_node_id??i?.origin_node_id;if(w!=null){const m=await y(w);if(m&&(a?!await C(t,m.grantee??"app:terminal",w):m.grantee!==t.app))throw new c(a?404:403,a?"not_found":"other_app_run","human request belongs to another app");if(m&&!a&&!await l(t,w,m.grantee??"app:terminal"))throw new c(404,"not_found","human request not found")}else if(d||i)throw new c(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 c(403,"other_app_run","the operation requires the calling node")}u(K,"authorizeBrokerOnly");function Q(e,t){if(!f(e,t))throw new J("the bearer token",t)}u(Q,"assertCeiling");function Z(){return new c(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}u(Z,"ownerOnlyError");function ve(e){return e.map(t=>({...t,ownerOnly:!0}))}u(ve,"ownerOnly");class ke{static{u(this,"Router")}routes=[];register(t){const o=I(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:T(t.pattern),handler:t.handler,maxBodyBytes:t.maxBodyBytes??P}),this}registerAll(t){for(const o of t)this.register(o);return this}match(t,o){const s=t.toUpperCase(),r=T(o);for(const n of this.routes){if(n.method!==s)continue;const a=ee(n.segments,r);if(a!==null)return{handler:n.handler,params:a,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"),a=(t.method??"GET").toUpperCase(),d=this.match(a,n.pathname);if(d===null){W(o,404,"not_found",`no route for ${a} ${n.pathname}`);return}if(await X(d.operation,r,d.params),s!==null){if(d.operation.classes.length===1&&d.operation.classes[0]==="person")throw Z();d.operation.scope&&Q(s,d.operation.scope)}let h;try{h=await te(t,d.maxBodyBytes)}catch(m){const x=m instanceof G?"payload_too_large":"invalid_request";W(o,x==="payload_too_large"?413:400,x,m.message);return}r.class==="broker"&&d.operation.resource==="human"&&await Y(d.operation,r,d.params,n.searchParams,h);const i={method:a,path:n.pathname,params:d.params,query:n.searchParams,body:h,ceiling:s,principal:r,...r.class==="anonymous"&&typeof t.headers.authorization=="string"?{publishToken:t.headers.authorization.slice(7)}:{},req:t,res:o},w=await d.handler(i);o.writableEnded||oe(o,w)}catch(n){if(n instanceof Error&&n.code==="person_unresolved"){E(o,503,{error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}});return}const{status:a,body:d}=N(n);a>=500&&U({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??""}}),E(o,a,d)}}}function T(e){return e.split("/").filter(t=>t.length>0)}u(T,"splitPath");function ee(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}u(ee,"matchSegments");class G extends Error{static{u(this,"BodyTooLargeError")}}async function te(e,t){const o=[];let s=0;for await(const n of e){const a=n;if(s+=a.length,s>t)throw new G(`request body exceeds ${t} bytes`);o.push(a)}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")}}u(te,"readJsonBody");function oe(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))}u(oe,"writeResult");function E(e,t,o){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}u(E,"writeJson");function W(e,t,o,s){E(e,t,{error:{code:o,message:s,origin:"runtime"}})}u(W,"writeError");export{ke as Router,$ as actsAsPerson,b as appOf,Q as assertCeiling,l as brokerMayReach,C as canReadNode,D as canReadRun,ve as ownerOnly,Z as ownerOnlyError,be as requireRun,v as resolvedScopes,k as runCallerApp};
1
+ var W=Object.defineProperty;var u=(e,t)=>W(e,"name",{value:t,configurable:!0});import{toErrorBody as G}from"./map.js";import{emitEvent as j}from"../../core/events/emit.js";import{scopeAllowed as w,ScopeDeniedError as H}from"../../core/scopes.js";import{coveredByAny as I}from"../../shared/env.js";import{ApiError as i}from"../../api/errors.js";import{activeGrant as J,grantFor as E}from"../../core/grants/mirror.js";import{getNode as g}from"../../core/canvas/canvas.js";import{ownedRun as L,RunError as _}from"../../core/runs/operations.js";import{openDb as k}from"../../core/canvas/db.js";import{check as z,permits as F}from"../../core/permissions/evaluator.js";import{readerFor as x}from"./reader.js";import{checkCronFire as P}from"../cron/authority.js";import{operationFor as D}from"./operations.js";import{CONTROL_BODY_MAX_BYTES as M}from"../../core/llm/body-limits.js";import{getRequest as Y,getRequestByInboxTicket as V}from"../../core/human/requests.js";import{requireVisibleReview as S}from"../../core/review/store.js";import{getComment as B}from"../../core/review/comments.js";async function X(e,t,o,n,r){const s=e.path,a=r&&typeof r=="object"&&!Array.isArray(r)?r:{};if(s==="/v1/human/requests"||s==="/v1/human/reviews"){const d=s.endsWith("/reviews")?a.origin_node_id:a.requester_node_id,f=s==="/v1/human/requests"&&d==null;if(d!==t.node&&!f)throw new i(403,"other_app_run","a broker may create a human request only for its own node");const c=a.source;if(c&&typeof c=="object"&&"nodeId"in c&&c.nodeId!==t.node)throw new i(403,"other_app_run","request source must name the calling node")}if(s==="/v1/human/reviews/self/comments"&&e.method==="GET"&&n.get("actor_node_id")!==t.node)throw new i(403,"other_app_run","self review requires the calling node");if(s.includes("/comments")&&e.method!=="GET"&&a.actor_node_id!==t.node)throw new i(403,"other_app_run","comment author must be the calling node");if(o.comment_id&&!await B(o.comment_id))throw new i(404,"not_found","comment not found")}u(X,"authorizeHumanBody");function R(e){return e.class==="broker"||e.class==="cron"}u(R,"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}u(b,"appOf");function y(e){return e.class==="person"||e.class==="forwarded"&&e.actor.kind==="person"}u(y,"actsAsPerson");async function q(e){const t=await E(e.actor.app,e.sub);if(!t)throw new i(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);return t}u(q,"forwardedGrant");async function O(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}=await q(e),n=e.actor.node_scopes;return n===null?o:n.filter(r=>I(o,r))}if(e.class==="app")return e.scopes;if(e.class==="cron"){const o=await P({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 i(401,"grant_revoked",o.message):new i(403,"scope_missing",o.message)}const t=e.grant?await J(e.grant):await E(e.app,e.sub);if(t&&t.grantee===e.app&&t.sub===e.sub)return t.resolved;throw new i(401,"grant_revoked","the node grant is not active")}u(O,"resolvedScopes");function A(e){return"class"in e?b(e):e.grantee}u(A,"runCallerApp");function $(e){return"class"in e?e:{class:"app",app:e.grantee,scopes:e.resolved,sub:e.sub}}u($,"asRequestPrincipal");async function l(e,t,o){const n=$(e);if(y(n))return!0;if(n.class==="anonymous"||n.class==="machine")return!1;const r=await k();return await z(r,await x(r,{principal:n}),t,o)}u(l,"mayOnNode");async function xe(e){if(y(e))return null;if(e.class==="anonymous"||e.class==="machine")return new Set;const t=await k(),o=await F(t,await x(t,{principal:e}),"read"),n=await t.prepareUncached(`SELECT o.id FROM objects o WHERE o.type = 'node' AND o.deleted_at IS NULL AND ${o.sql}`).all(...o.params);return new Set(n.map(r=>r.id))}u(xe,"readableNodeIds");async function C(e,t,o){const n=$(e);return y(n)?!0:n.class==="anonymous"||n.class==="machine"?!1:b(n)===t?!0:w(await O(n),o)&&(!R(n)||w(n.scopes,o))}u(C,"mayReadApp");async function Se(e,t,o){return o===void 0?await C(e,t,`crtr:conversations:read:${t}`):await l(e,"read",o)}u(Se,"canReadRun");async function Be(e,t,o=!1,n=!1){const r=await g(t);if(!r||r.parent!==null||r.run_id!==t||!r.grantee||r.deleting_at&&!n)throw new _(404,"not_found","run not found");if(!await l(e,"read",t))throw new _(404,"not_found","run not found");if(o&&A(e)!==null&&A(e)!==r.grantee)throw new _(403,"other_app_run","cannot change another app's run");return await L(t,r.grantee,n)}u(Be,"requireRun");async function K(e,t,o){return o===void 0?await C(e,t,`crtr:objects:read:${t}`):await l(e,"read",o)}u(K,"canReadNode");const Q=new Set(["messages.post.58","messages.post.59"]);async function Z(e,t,o){if(!e.classes.includes(t.class)&&!(t.class!=="anonymous"&&t.class!=="machine"&&t.class!=="forwarded"&&e.classes.includes("anonymous")))throw new i(403,"permission_error","this operation is not available to the caller");if(t.class==="forwarded"&&t.actor.kind==="app"&&await q(t),t.class==="person"||t.class==="anonymous"||t.class==="machine"||y(t))return;const n=await O(t);if(e.scope&&(!w(n,e.scope)||R(t)&&!w(t.scopes,e.scope)))throw new i(403,"scope_missing",`missing scope ${e.scope}`);if(t.class==="app")return;const r=b(t);t.class==="broker"&&await ee(e,t,o,n);const s=o.id;if((e.resource==="node-read"||e.resource==="node-write")&&s!==void 0){const a=await g(s);if(!a)return;if(e.resource==="node-write"){const d=Q.has(e.name);if(a.grantee!==r&&!d)throw new i(403,"other_app_run","cannot change another app's node");if(!await l(t,d&&a.grantee!==r?"message":"read",s))throw a.grantee!==r?new i(403,"other_app_run","cannot change another app's node"):new i(404,"not_found","node not found")}if(e.resource==="node-read"&&!await l(t,"read",s))throw new i(404,"not_found","node not found")}}u(Z,"authorizeOperation");async function ee(e,t,o,n){if(e.resource==="daemon-bash"&&(!w(n,"crtr:files:rw:user:.")||!w(t.scopes,"crtr:files:rw:user:.")))throw new i(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const s=e.path,a=e.method==="GET";if(!a&&(s.endsWith("/respond")||s.endsWith("/submit")||s.endsWith("/dismiss")||s.endsWith("/progress")||s.endsWith("/comment-ranges")||s.includes("/feedback-comments")))throw new i(403,"permission_error","only the person may answer or edit the human inbox");const d=o.request_id?await Y(o.request_id):o.ticket_id?await V(o.ticket_id):null,f=o.comment_id?await B(o.comment_id):null,c=o.review_id?await S(o.review_id):f?await S(f.review_id):null,h=d?.requester_node_id??c?.origin_node_id;if(h!=null){const m=await g(h);if(m&&(a?!await K(t,m.grantee??"app:terminal",h):m.grantee!==t.app))throw new i(a?404:403,a?"not_found":"other_app_run","human request belongs to another app");if(m&&!a&&!await l(t,"read",h))throw new i(404,"not_found","human request not found")}else if(d||c)throw new i(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 i(403,"other_app_run","the operation requires the calling node")}u(ee,"authorizeBrokerOnly");function te(e,t){if(!w(e,t))throw new H("the bearer token",t)}u(te,"assertCeiling");function oe(){return new i(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}u(oe,"ownerOnlyError");function Re(e){return e.map(t=>({...t,ownerOnly:!0}))}u(Re,"ownerOnly");class qe{static{u(this,"Router")}routes=[];register(t){const o=D(t.method,t.pattern);if(!o)throw new Error(`route has no operation row: ${t.method} ${t.pattern}`);if(this.routes.some(n=>n.method===t.method.toUpperCase()&&n.operation.path===t.pattern))throw new Error(`duplicate route: ${t.method} ${t.pattern}`);return this.routes.push({operation:o,method:t.method.toUpperCase(),segments:N(t.pattern),handler:t.handler,maxBodyBytes:t.maxBodyBytes??M}),this}registerAll(t){for(const o of t)this.register(o);return this}match(t,o){const n=t.toUpperCase(),r=N(o);for(const s of this.routes){if(s.method!==n)continue;const a=ne(s.segments,r);if(a!==null)return{handler:s.handler,params:a,operation:s.operation,maxBodyBytes:s.maxBodyBytes}}return null}async handle(t,o,n,r={class:"person"}){try{const s=new URL(t.url??"/","http://127.0.0.1"),a=(t.method??"GET").toUpperCase(),d=this.match(a,s.pathname);if(d===null){U(o,404,"not_found",`no route for ${a} ${s.pathname}`);return}if(await Z(d.operation,r,d.params),n!==null){if(d.operation.classes.length===1&&d.operation.classes[0]==="person")throw oe();d.operation.scope&&te(n,d.operation.scope)}let f;try{f=await re(t,d.maxBodyBytes)}catch(m){const v=m instanceof T?"payload_too_large":"invalid_request";U(o,v==="payload_too_large"?413:400,v,m.message);return}r.class==="broker"&&d.operation.resource==="human"&&await X(d.operation,r,d.params,s.searchParams,f);const c={method:a,path:s.pathname,params:d.params,query:s.searchParams,body:f,ceiling:n,principal:r,...r.class==="anonymous"&&typeof t.headers.authorization=="string"?{publishToken:t.headers.authorization.slice(7)}:{},req:t,res:o},h=await d.handler(c);o.writableEnded||se(o,h)}catch(s){if(s instanceof Error&&s.code==="person_unresolved"){p(o,503,{error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}});return}const{status:a,body:d}=G(s);a>=500&&j({event:"api.request.failed",level:"error",error:s instanceof Error?s:new Error(String(s)),...r.class==="broker"?{node_id:r.node}:{},fields:{method:(t.method??"GET").toUpperCase(),path:t.url??""}}),p(o,a,d)}}}function N(e){return e.split("/").filter(t=>t.length>0)}u(N,"splitPath");function ne(e,t){if(e.length!==t.length)return null;const o={};for(let n=0;n<e.length;n++){const r=e[n],s=t[n];if(r.startsWith(":"))o[r.slice(1)]=decodeURIComponent(s);else if(r!==s)return null}return o}u(ne,"matchSegments");class T extends Error{static{u(this,"BodyTooLargeError")}}async function re(e,t){const o=[];let n=0;for await(const s of e){const a=s;if(n+=a.length,n>t)throw new T(`request body exceeds ${t} bytes`);o.push(a)}if(n===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")}}u(re,"readJsonBody");function se(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))}u(se,"writeResult");function p(e,t,o){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}u(p,"writeJson");function U(e,t,o,n){p(e,t,{error:{code:o,message:n,origin:"runtime"}})}u(U,"writeError");export{qe as Router,y as actsAsPerson,b as appOf,te as assertCeiling,K as canReadNode,Se as canReadRun,l as mayOnNode,Re as ownerOnly,oe as ownerOnlyError,xe as readableNodeIds,Be as requireRun,O as resolvedScopes,A as runCallerApp};