@north-light/cli 0.3.549 → 0.3.551
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/custom-objects.d.ts +1 -1
- package/dist/api/dto/docs.d.ts +12 -0
- package/dist/api/dto/objects.d.ts +17 -1
- package/dist/api/dto/objects.js +1 -1
- package/dist/api/dto/permissions.d.ts +76 -0
- package/dist/api/dto/permissions.js +1 -0
- package/dist/api/index.d.ts +3 -2
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +4 -0
- package/dist/api/routes.js +1 -1
- package/dist/builtin-memory/crouter-concepts/documents.md +1 -1
- package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +2 -2
- package/dist/builtin-memory/crouter-sdk/release-notes.md +11 -0
- package/dist/builtin-memory/internal/INDEX.md +2 -1
- package/dist/builtin-memory/internal/agent-shaping.md +1 -1
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-memory/northlight-apps/guides/files-and-documents.md +3 -3
- package/dist/builtin-memory/northlight-apps/guides/many-users.md +1 -1
- package/dist/builtin-memory/northlight-apps/guides/test-your-app.md +1 -1
- package/dist/clients/attach/viewer.js +9 -9
- package/dist/commands/canvas/list.js +2 -2
- package/dist/commands/canvas/share.d.ts +2 -0
- package/dist/commands/canvas/share.js +2 -0
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/doc/edit.js +1 -1
- package/dist/commands/doc/shared.js +1 -1
- package/dist/commands/doc/write.js +1 -1
- package/dist/commands/sys/sync-skills.js +2 -2
- package/dist/core/canvas/canvas.js +20 -20
- package/dist/core/canvas/db.js +4 -4
- package/dist/core/canvas/export-sqlite.js +2 -2
- package/dist/core/canvas/import-sqlite.js +5 -5
- package/dist/core/canvas/outcome-actions.js +3 -3
- package/dist/core/canvas/person.js +11 -9
- package/dist/core/canvas/schema-pg.sql +49 -5
- package/dist/core/environments.js +1 -1
- package/dist/core/feed/feed.js +1 -1
- package/dist/core/grants/mirror.d.ts +9 -1
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/graph/access.d.ts +8 -49
- package/dist/core/graph/access.js +4 -7
- package/dist/core/graph/custom.d.ts +5 -2
- package/dist/core/graph/custom.js +9 -9
- package/dist/core/graph/deletion.js +5 -4
- package/dist/core/graph/documents.d.ts +12 -3
- package/dist/core/graph/documents.js +13 -7
- package/dist/core/graph/edges.js +3 -3
- package/dist/core/graph/events.js +12 -8
- package/dist/core/graph/kinds/document.js +4 -4
- package/dist/core/graph/kinds/kind.js +1 -1
- package/dist/core/graph/kinds/node.js +5 -5
- package/dist/core/graph/names.d.ts +16 -1
- package/dist/core/graph/names.js +11 -3
- package/dist/core/graph/objects.d.ts +19 -2
- package/dist/core/graph/objects.js +16 -10
- package/dist/core/graph/package-docs.js +5 -5
- package/dist/core/graph/package-files.js +2 -2
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/rules.d.ts +7 -5
- package/dist/core/graph/rules.js +3 -3
- package/dist/core/graph/types.d.ts +12 -1
- package/dist/core/graph/types.js +1 -1
- package/dist/core/graph/watches.d.ts +1 -1
- package/dist/core/graph/watches.js +9 -8
- package/dist/core/peer/envelope.d.ts +1 -1
- package/dist/core/peer/envelope.js +1 -1
- package/dist/core/peer/stubs.d.ts +1 -1
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/permissions/boot.d.ts +17 -0
- package/dist/core/permissions/boot.js +18 -0
- package/dist/core/permissions/builtin.d.ts +8 -0
- package/dist/core/permissions/builtin.js +20 -0
- package/dist/core/permissions/ceiling.d.ts +57 -0
- package/dist/core/permissions/ceiling.js +22 -0
- package/dist/core/permissions/compile.d.ts +14 -0
- package/dist/core/permissions/compile.js +1 -0
- package/dist/core/permissions/errors.d.ts +7 -0
- package/dist/core/permissions/errors.js +1 -0
- package/dist/core/permissions/evaluator.d.ts +28 -0
- package/dist/core/permissions/evaluator.js +6 -0
- package/dist/core/permissions/facts.d.ts +56 -0
- package/dist/core/permissions/facts.js +2 -0
- package/dist/core/permissions/schema-parser.d.ts +29 -0
- package/dist/core/permissions/schema-parser.js +2 -0
- package/dist/core/permissions/schemas.d.ts +21 -0
- package/dist/core/permissions/schemas.js +2 -0
- package/dist/core/permissions/sql.d.ts +16 -0
- package/dist/core/permissions/sql.js +1 -0
- package/dist/core/runtime/broker/frame-client.d.ts +1 -1
- package/dist/core/runtime/broker/frame-client.js +1 -1
- package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
- package/dist/core/runtime/broker/frame-dispatch.js +1 -1
- package/dist/core/runtime/broker/frame-read.d.ts +4 -3
- package/dist/core/runtime/broker/frame-read.js +1 -1
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/substrate/delivery/corpus.d.ts +2 -2
- package/dist/core/substrate/delivery/corpus.js +3 -3
- package/dist/core/substrate/delivery/deliver.js +2 -2
- package/dist/core/substrate/delivery/render-event.js +6 -6
- package/dist/core/substrate/subject-fields.d.ts +2 -0
- package/dist/core/substrate/subject.js +1 -1
- package/dist/daemon/api/app-listener.js +12 -12
- package/dist/daemon/api/bridge.d.ts +1 -1
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/handlers/attach.d.ts +4 -1
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +5 -5
- package/dist/daemon/api/handlers/check.d.ts +2 -0
- package/dist/daemon/api/handlers/check.js +1 -0
- package/dist/daemon/api/handlers/custom-objects.js +2 -2
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/memory.js +7 -6
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/relations.d.ts +2 -0
- package/dist/daemon/api/handlers/relations.js +1 -0
- package/dist/daemon/api/handlers/schemas.d.ts +12 -0
- package/dist/daemon/api/handlers/schemas.js +1 -0
- package/dist/daemon/api/handlers/shares.d.ts +2 -0
- package/dist/daemon/api/handlers/shares.js +1 -0
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/router.d.ts +10 -6
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/crtrd.js +12 -12
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/doc-editor/editor.css +1 -1
- package/dist/doc-editor/editor.js +16 -16
- package/dist/migrations/004-canvas-documents/fields.d.ts +1 -1
- package/dist/migrations/004-canvas-documents/fields.js +2 -2
- package/docs/apps/guides/files-and-documents.md +3 -3
- package/docs/apps/guides/many-users.md +1 -1
- package/docs/apps/guides/test-your-app.md +1 -1
- package/docs/cli/documents-and-preferences.md +1 -1
- package/docs/concepts/documents.md +1 -1
- package/docs/concepts/scopes-and-trust.md +2 -2
- package/docs/sdk/release-notes.md +11 -0
- package/package.json +2 -2
- package/packages/crouter-identity/dist/index.js +14 -1
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/dist/core/graph/spaces/app.d.ts +0 -3
- package/dist/core/graph/spaces/app.js +0 -1
- package/dist/core/graph/spaces/index.d.ts +0 -18
- package/dist/core/graph/spaces/index.js +0 -1
- package/dist/core/graph/spaces/own-memory.d.ts +0 -18
- package/dist/core/graph/spaces/own-memory.js +0 -1
- package/dist/core/graph/spaces/person.d.ts +0 -5
- package/dist/core/graph/spaces/person.js +0 -3
- package/dist/core/graph/spaces/repo.d.ts +0 -14
- package/dist/core/graph/spaces/repo.js +0 -1
- package/dist/core/runs/confinement.d.ts +0 -25
- package/dist/core/runs/confinement.js +0 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
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"),
|
|
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 @@
|
|
|
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 @@
|
|
|
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:
|
|
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
|
-
/**
|
|
81
|
-
*
|
|
82
|
-
|
|
83
|
-
|
|
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};
|