@north-light/crouter 0.3.356 → 0.3.358

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.
@@ -0,0 +1,97 @@
1
+ import { RunError } from '../runs/operations.js';
2
+ export type ErrorType = 'invalid_request_error' | 'authentication_error' | 'permission_error' | 'rate_limit_error' | 'server_error';
3
+ export type ErrorOrigin = 'directory' | 'router' | 'runtime' | 'provider';
4
+ export interface CodeRow {
5
+ type: ErrorType;
6
+ status: number;
7
+ retryable: boolean;
8
+ user_action?: string;
9
+ }
10
+ /** The provider rows of the daemon-operations code table. `provider_error`'s
11
+ * status is the provider's own 4xx; 400 is its default (a provider `scope_missing`). */
12
+ export declare const PROVIDER_CODES: {
13
+ readonly provider_error: {
14
+ readonly type: "invalid_request_error";
15
+ readonly status: 400;
16
+ readonly retryable: false;
17
+ };
18
+ readonly provider_rate_limited: {
19
+ readonly type: "rate_limit_error";
20
+ readonly status: 429;
21
+ readonly retryable: true;
22
+ };
23
+ readonly provider_unavailable: {
24
+ readonly type: "server_error";
25
+ readonly status: 503;
26
+ readonly retryable: true;
27
+ };
28
+ readonly provider_refused: {
29
+ readonly type: "permission_error";
30
+ readonly status: 403;
31
+ readonly retryable: false;
32
+ };
33
+ readonly provider_not_connected: {
34
+ readonly type: "permission_error";
35
+ readonly status: 403;
36
+ readonly retryable: false;
37
+ };
38
+ readonly provider_version_retired: {
39
+ readonly type: "permission_error";
40
+ readonly status: 403;
41
+ readonly retryable: false;
42
+ };
43
+ readonly storage_unavailable: {
44
+ readonly type: "server_error";
45
+ readonly status: 503;
46
+ readonly retryable: true;
47
+ };
48
+ readonly approval_pending: {
49
+ readonly type: "permission_error";
50
+ readonly status: 403;
51
+ readonly retryable: false;
52
+ readonly user_action: "answer_question";
53
+ };
54
+ readonly user_denied: {
55
+ readonly type: "permission_error";
56
+ readonly status: 403;
57
+ readonly retryable: false;
58
+ };
59
+ };
60
+ export type ProviderCode = keyof typeof PROVIDER_CODES;
61
+ /** The non-provider codes a provider call also returns (the rest of the table
62
+ * rows it reaches). Anything absent falls back by status. */
63
+ declare const OTHER_CODES: Record<string, CodeRow>;
64
+ export declare function codeRow(code: string, status: number): CodeRow;
65
+ export interface ProviderErrorOptions {
66
+ /** Overrides the table status (`provider_error` carries the provider's 4xx). */
67
+ status?: number;
68
+ param?: string;
69
+ details?: unknown;
70
+ scope?: string;
71
+ origin?: ErrorOrigin;
72
+ retry_after_s?: number;
73
+ question_id?: string;
74
+ run_id?: string;
75
+ }
76
+ export declare class ProviderError extends RunError {
77
+ readonly origin: ErrorOrigin;
78
+ readonly type: ErrorType;
79
+ readonly retry_after_s?: number;
80
+ readonly question_id?: string;
81
+ readonly user_action?: string;
82
+ readonly run_id?: string;
83
+ constructor(code: ProviderCode | keyof typeof OTHER_CODES, message: string, options?: ProviderErrorOptions);
84
+ }
85
+ /** `scope_missing` naming the `<provider>:<group>` string. */
86
+ export declare function scopeMissing(scope: string): ProviderError;
87
+ /** The contract-2 error envelope for any value a provider operation throws.
88
+ * A value that is not a `RunError` is a 500 `server_error` (its cause is logged by the caller).
89
+ * `directoryCaller`: the caller holds a directory token (app listener). */
90
+ export declare function providerErrorBody(thrown: unknown, requestId: string, directoryCaller: boolean, runId?: string): {
91
+ status: number;
92
+ body: {
93
+ error: Record<string, unknown>;
94
+ };
95
+ headers: Record<string, string>;
96
+ };
97
+ export {};
@@ -0,0 +1 @@
1
+ var c=Object.defineProperty;var a=(e,t)=>c(e,"name",{value:t,configurable:!0});import{RunError as o}from"../runs/operations.js";const m={provider_error:{type:"invalid_request_error",status:400,retryable:!1},provider_rate_limited:{type:"rate_limit_error",status:429,retryable:!0},provider_unavailable:{type:"server_error",status:503,retryable:!0},provider_refused:{type:"permission_error",status:403,retryable:!1},provider_not_connected:{type:"permission_error",status:403,retryable:!1},provider_version_retired:{type:"permission_error",status:403,retryable:!1},storage_unavailable:{type:"server_error",status:503,retryable:!0},approval_pending:{type:"permission_error",status:403,retryable:!1,user_action:"answer_question"},user_denied:{type:"permission_error",status:403,retryable:!1}},v={unauthorized:{type:"authentication_error",status:401,retryable:!1},grant_revoked:{type:"authentication_error",status:401,retryable:!1},scope_missing:{type:"permission_error",status:403,retryable:!1},permission_error:{type:"permission_error",status:403,retryable:!1},invalid_request:{type:"invalid_request_error",status:400,retryable:!1},not_found:{type:"invalid_request_error",status:404,retryable:!1},not_implemented:{type:"server_error",status:501,retryable:!1},runtime_starting:{type:"server_error",status:503,retryable:!0},server_error:{type:"server_error",status:500,retryable:!0}};function u(e,t){return m[e]??v[e]??{type:t===401?"authentication_error":t===403?"permission_error":t===429?"rate_limit_error":t>=500?"server_error":"invalid_request_error",status:t,retryable:t>=500}}a(u,"codeRow");class _ extends o{static{a(this,"ProviderError")}origin;type;retry_after_s;question_id;user_action;run_id;constructor(t,n,s={}){const r=u(t,s.status??500);super(s.status??r.status,t,n,s.param,s.details,s.scope,r.retryable),this.type=r.type,this.origin=s.origin??"runtime",s.retry_after_s!==void 0&&(this.retry_after_s=s.retry_after_s),s.question_id!==void 0&&(this.question_id=s.question_id),s.run_id!==void 0&&(this.run_id=s.run_id),r.user_action!==void 0&&(this.user_action=r.user_action)}}function E(e){return new _("scope_missing",`missing scope ${e}`,{scope:e})}a(E,"scopeMissing");function b(e){if(!(e instanceof Error))return null;const{status:t,code:n,details:s}=e;return typeof t!="number"||typeof n!="string"||t<400||t>599?null:new o(t,n,e.message,void 0,s,void 0,u(n,t).retryable)}a(b,"shaped");function g(e){if(e.code==="unauthorized"||e.code==="grant_revoked")return"reconnect";if(e.code==="scope_missing"&&e.scope)return`grant_scope:${e.scope}`}a(g,"directoryAction");function R(e,t,n,s){const r=e instanceof o?e:b(e)??new _("server_error","provider request failed"),i=r instanceof _?r:null,p=u(r.code,r.status),d=i?.run_id??s,l=i?.user_action??(n?g(r):void 0),f={code:r.code,message:r.message,...r.details===void 0?{}:{details:r.details},type:i?.type??p.type,...r.param?{param:r.param}:{},origin:i?.origin??"runtime",retryable:r.retryable,...i?.retry_after_s===void 0?{}:{retry_after_s:i.retry_after_s},request_id:t,...d?{run_id:d}:{},...i?.question_id?{question_id:i.question_id}:{},...l?{user_action:l}:{},...r.scope?{scope:r.scope}:{}},y={"Request-Id":t};return i?.retry_after_s!==void 0&&(y["Retry-After"]=String(i.retry_after_s)),{status:r.status,body:{error:f},headers:y}}a(R,"providerErrorBody");export{m as PROVIDER_CODES,_ as ProviderError,u as codeRow,R as providerErrorBody,E as scopeMissing};
@@ -1,21 +1,21 @@
1
- var k=Object.defineProperty;var i=(e,r)=>k(e,"name",{value:r,configurable:!0});import{randomUUID as C}from"node:crypto";import{createServer as x}from"node:http";import{Router as H}from"./router.js";import{OPERATIONS as I}from"./operations.js";import{AppPrincipalResolver as J}from"./principal.js";import{handleRunOperation as $,integer as z}from"./handlers/runs.js";import{parseLlmRequest as D,runLlm as U}from"../../core/llm/run.js";import{RunError as u}from"../../core/runs/operations.js";import{requireRun as T}from"./router.js";import{readRunEvents as A,registerGrantStream as X,subscribeRunEvents as j}from"../../core/runs/events.js";import{activeGrant as B}from"../../core/grants/mirror.js";import{emitEvent as G}from"../../core/events/emit.js";import{handleVendorSignIn as L,isVendorSignInPath as F}from"./vendor-signin.js";import{listAppProfiles as M}from"./handlers/app-profiles.js";import{handleTransferDownload as Q,handleTransferOperation as V,TRANSFER_OPERATIONS as W}from"./handlers/transfer.js";import{handleQuestionOperation as Y,QUESTION_OPERATIONS as K}from"./handlers/questions.js";import{vendorStatus as Z}from"./handlers/vendor-status.js";const ee={other_app_run:"permission_error",unauthorized:"authentication_error",grant_revoked:"authentication_error",scope_missing:"permission_error",owner_only:"permission_error",invalid_request:"invalid_request_error",not_found:"invalid_request_error",model_unavailable:"invalid_request_error",substitution_refused:"invalid_request_error",payer_not_app:"invalid_request_error",all_routes_exhausted:"rate_limit_error",idempotency_conflict:"invalid_request_error",run_settled:"invalid_request_error",stream_gap:"invalid_request_error",stream_dropped:"server_error",runtime_starting:"server_error",storage_unavailable:"server_error",server_error:"server_error"};function R(e,r,a){return{error:{code:e.code,message:e.message,...e.details===void 0?{}:{details:e.details},type:ee[e.code]??"api_error",...e.param?{param:e.param}:{},origin:"runtime",retryable:e.retryable||e.code==="stream_dropped",request_id:r,...a?{run_id:a}:{},...e.scope?{scope:e.scope}:{},...e.code==="unauthorized"?{user_action:"reconnect"}:{},...e.code==="all_routes_exhausted"?{retry_after_s:e.details.retry_after_s}:{}}}}i(R,"envelope");function te(e,r,a,s){const d=r instanceof u?r:new u(500,"server_error","runtime request failed");if(r instanceof u||console.error("[app-listener]",r),e.headersSent&&!String(e.getHeader("Content-Type")??"").startsWith("text/event-stream")){e.destroy();return}if(e.headersSent){e.end(`event: error
2
- data: ${JSON.stringify(R(d,a,s))}
1
+ var C=Object.defineProperty;var s=(e,r)=>C(e,"name",{value:r,configurable:!0});import{randomUUID as k}from"node:crypto";import{createServer as I}from"node:http";import{Router as x}from"./router.js";import{OPERATIONS as H}from"./operations.js";import{AppPrincipalResolver as J}from"./principal.js";import{handleRunOperation as $,integer as D}from"./handlers/runs.js";import{parseLlmRequest as X,runLlm as j}from"../../core/llm/run.js";import{RunError as u}from"../../core/runs/operations.js";import{requireRun as A}from"./router.js";import{readRunEvents as P,registerGrantStream as z,subscribeRunEvents as U}from"../../core/runs/events.js";import{activeGrant as B}from"../../core/grants/mirror.js";import{emitEvent as F}from"../../core/events/emit.js";import{handleVendorSignIn as G,isVendorSignInPath as L}from"./vendor-signin.js";import{listAppProfiles as V}from"./handlers/app-profiles.js";import{handleTransferDownload as M,handleTransferOperation as Q,TRANSFER_OPERATIONS as W}from"./handlers/transfer.js";import{handleQuestionOperation as Y,QUESTION_OPERATIONS as K}from"./handlers/questions.js";import{vendorStatus as Z}from"./handlers/vendor-status.js";import{abortOnClose as ee,callerFromApp as te,handleProviderOperation as re,PROVIDER_OPERATIONS as ne,providerFailure as ae}from"./handlers/providers.js";const oe={other_app_run:"permission_error",unauthorized:"authentication_error",grant_revoked:"authentication_error",scope_missing:"permission_error",owner_only:"permission_error",invalid_request:"invalid_request_error",not_found:"invalid_request_error",model_unavailable:"invalid_request_error",substitution_refused:"invalid_request_error",payer_not_app:"invalid_request_error",all_routes_exhausted:"rate_limit_error",idempotency_conflict:"invalid_request_error",run_settled:"invalid_request_error",stream_gap:"invalid_request_error",stream_dropped:"server_error",runtime_starting:"server_error",storage_unavailable:"server_error",server_error:"server_error"};function N(e,r,a){return{error:{code:e.code,message:e.message,...e.details===void 0?{}:{details:e.details},type:oe[e.code]??"api_error",...e.param?{param:e.param}:{},origin:"runtime",retryable:e.retryable||e.code==="stream_dropped",request_id:r,...a?{run_id:a}:{},...e.scope?{scope:e.scope}:{},...e.code==="unauthorized"?{user_action:"reconnect"}:{},...e.code==="all_routes_exhausted"?{retry_after_s:e.details.retry_after_s}:{}}}}s(N,"envelope");function ie(e,r,a,i){const l=r instanceof u?r:new u(500,"server_error","runtime request failed");if(r instanceof u||console.error("[app-listener]",r),e.headersSent&&!String(e.getHeader("Content-Type")??"").startsWith("text/event-stream")){e.destroy();return}if(e.headersSent){e.end(`event: error
2
+ data: ${JSON.stringify(N(l,a,i))}
3
3
 
4
- `);return}e.writeHead(d.status,{"Content-Type":"application/json; charset=utf-8","Request-Id":a,"X-Content-Type-Options":"nosniff",...d.code==="all_routes_exhausted"?{"Retry-After":String(d.details.retry_after_s)}:{}}),e.end(JSON.stringify(R(d,a,s)))}i(te,"fail");function y(e,r,a){e.writeHead(r,{"Content-Type":"application/json; charset=utf-8"}),e.end(JSON.stringify(a))}i(y,"json");async function N(e){const r=[];let a=0;for await(const s of e){if(a+=s.length,a>4*1024*1024)throw new u(400,"invalid_request","request body too large");r.push(s)}if(a)try{return JSON.parse(Buffer.concat(r).toString("utf8"))}catch{throw new u(400,"invalid_request","invalid JSON body")}}i(N,"bodyOf");function re(e,r){const a=e.headers["last-event-id"]??r.get("after");if(Array.isArray(a))throw new u(400,"invalid_request","invalid cursor","after");return z(a??null,"after",0,Number.MAX_SAFE_INTEGER,0)}i(re,"cursor");function ne(e){return`id: ${e.sequence_number}
4
+ `);return}e.writeHead(l.status,{"Content-Type":"application/json; charset=utf-8","Request-Id":a,"X-Content-Type-Options":"nosniff",...l.code==="all_routes_exhausted"?{"Retry-After":String(l.details.retry_after_s)}:{}}),e.end(JSON.stringify(N(l,a,i)))}s(ie,"fail");function g(e,r,a){e.writeHead(r,{"Content-Type":"application/json; charset=utf-8"}),e.end(JSON.stringify(a))}s(g,"json");async function T(e){const r=[];let a=0;for await(const i of e){if(a+=i.length,a>4*1024*1024)throw new u(400,"invalid_request","request body too large");r.push(i)}if(a)try{return JSON.parse(Buffer.concat(r).toString("utf8"))}catch{throw new u(400,"invalid_request","invalid JSON body")}}s(T,"bodyOf");function se(e,r){const a=e.headers["last-event-id"]??r.get("after");if(Array.isArray(a))throw new u(400,"invalid_request","invalid cursor","after");return D(a??null,"after",0,Number.MAX_SAFE_INTEGER,0)}s(se,"cursor");function ue(e){return`id: ${e.sequence_number}
5
5
  event: ${e.type}
6
6
  data: ${JSON.stringify(e)}
7
7
 
8
- `}i(ne,"frame");function ae(e,r,a,s,d,b,m){T(s,a);let p=A(a,d);if(d>p.latest_sequence)throw new u(400,"invalid_request","cursor is beyond the run","after");if(d<p.latest_sequence&&(p.earliest_sequence===null||d<p.earliest_sequence-1))throw new u(409,"stream_gap","events have expired",void 0,{earliest_sequence:p.earliest_sequence,latest_sequence:p.latest_sequence});if(r.destroyed||e.destroyed)return r.destroy(),Promise.resolve();r.writeHead(200,{"Content-Type":m==="sse"?"text/event-stream":"application/x-ndjson","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),m==="sse"?r.write(`: connected
8
+ `}s(ue,"frame");function de(e,r,a,i,l,R,m){A(i,a);let p=P(a,l);if(l>p.latest_sequence)throw new u(400,"invalid_request","cursor is beyond the run","after");if(l<p.latest_sequence&&(p.earliest_sequence===null||l<p.earliest_sequence-1))throw new u(409,"stream_gap","events have expired",void 0,{earliest_sequence:p.earliest_sequence,latest_sequence:p.latest_sequence});if(r.destroyed||e.destroyed)return r.destroy(),Promise.resolve();r.writeHead(200,{"Content-Type":m==="sse"?"text/event-stream":"application/x-ndjson","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),m==="sse"?r.write(`: connected
9
9
 
10
- `):r.flushHeaders();let n=d,t=!1,f=!1,_=!1,l;const v=new Promise(h=>{l=h}),o=i(()=>{t||(t=!0,clearInterval(P),q(),E(),r.off("close",o),r.off("drain",w),r.end(),l())},"end"),w=i(()=>{_=!1,c()},"onDrain"),g=i(h=>{t||r.write(m==="sse"?`event: error
11
- data: ${JSON.stringify(R(h,b,a))}
10
+ `):r.flushHeaders();let n=l,t=!1,c=!1,_=!1,f;const v=new Promise(w=>{f=w}),o=s(()=>{t||(t=!0,clearInterval(q),S(),E(),r.off("close",o),r.off("drain",h),r.end(),f())},"end"),h=s(()=>{_=!1,d()},"onDrain"),O=s(w=>{t||r.write(m==="sse"?`event: error
11
+ data: ${JSON.stringify(N(w,R,a))}
12
12
 
13
- `:`${JSON.stringify({type:"error",...R(h,b,a)})}
14
- `),o()},"error"),c=i(()=>{if(!(t||f)){f=!0;try{if(!O()){S();return}if(T(s,a),p=A(a,n),p.backlog_count>1e3||p.backlog_bytes>32*1024*1024){g(new u(503,"stream_dropped","stream reader fell behind",void 0,{last_sequence:n}));return}for(const h of p.events){if(_)break;_=!r.write(m==="sse"?ne(h):`${JSON.stringify(h)}
15
- `),n=h.sequence_number}}catch(h){g(h instanceof u?h:new u(500,"server_error","stream failed"))}finally{f=!1}}},"flush"),S=i(()=>g(new u(401,"grant_revoked","grant is not active")),"revoked"),O=i(()=>"class"in s||B(s.grant)!==null,"grantActive"),q=j(a,c),E="class"in s?()=>{}:X(s.grant,S),P=setInterval(()=>{!t&&!_&&m==="sse"&&r.write(`: keepalive
13
+ `:`${JSON.stringify({type:"error",...N(w,R,a)})}
14
+ `),o()},"error"),d=s(()=>{if(!(t||c)){c=!0;try{if(!y()){b();return}if(A(i,a),p=P(a,n),p.backlog_count>1e3||p.backlog_bytes>32*1024*1024){O(new u(503,"stream_dropped","stream reader fell behind",void 0,{last_sequence:n}));return}for(const w of p.events){if(_)break;_=!r.write(m==="sse"?ue(w):`${JSON.stringify(w)}
15
+ `),n=w.sequence_number}}catch(w){O(w instanceof u?w:new u(500,"server_error","stream failed"))}finally{c=!1}}},"flush"),b=s(()=>O(new u(401,"grant_revoked","grant is not active")),"revoked"),y=s(()=>"class"in i||B(i.grant)!==null,"grantActive"),S=U(a,d),E="class"in i?()=>{}:z(i.grant,b),q=setInterval(()=>{!t&&!_&&m==="sse"&&r.write(`: keepalive
16
16
 
17
- `)},15e3);return r.on("drain",w),r.on("close",o),c(),v}i(ae,"streamRunEvents");function Oe(e,r,a){if(!e.issuer||!e.audience||!e.listener?.address||!Number.isInteger(e.listener.port)||e.listener.port<1||e.listener.port>65535)throw new Error("runtime issuer, audience and listener address/port are required");if(["0.0.0.0","::","[::]"].includes(e.listener.address))throw new Error("runtime listener must bind a specific address");const s=new J(e.issuer,e.audience,a,e.jwksUrl),d=new H,b=new Map;for(const n of I.filter(t=>t.stage!==void 0)){const t=i(()=>({status:500}),"handler");d.register({method:n.method,pattern:n.path,handler:t}),b.set(t,n)}const m=x((n,t)=>{(async()=>{const f=C();t.setHeader("Request-Id",f);let _;try{const l=new URL(n.url??"/","http://runtime.local");if(F(l.pathname)){await L(n,t,l,s);return}if((n.method!=="GET"||l.pathname!=="/v1/health")&&(!s.isReady()||!r()))throw new u(503,"runtime_starting","runtime_starting");const v=d.match(n.method??"GET",l.pathname);if(!v)throw new u(404,"not_found","unknown operation");const o=b.get(v.handler);if(!o)throw new u(404,"not_found","unknown operation");if(_=v.params.run_id,o.name==="health"){y(t,200,{status:"ok",api_version:"2026-09-23"});return}if(o.name==="runtime.sync-notice"){if(!await s.verifySyncNotice(n.headers.authorization)){t.writeHead(204),t.end();return}G({level:"info",event:"daemon.grants.sync_notice",fields:{request_id:f}});try{await a({fresh:!0})}catch{throw new u(503,"server_error","grant sync failed")}t.writeHead(204),t.end();return}if(o.name==="runtime.vendor-status"){await s.verifyDirectoryRead(n.headers.authorization,"vendor_status"),y(t,200,Z());return}const w=await s.resolve(n.headers.authorization,o.scope);if(t.setHeader("Request-Id",f),_&&T(w,_,["run.message","run.interrupt","run.cancel","run.rename","run.delete"].includes(o.name),o.name==="run.delete"),o.stream==="bytes"){await Q(n,t,w,l.searchParams);return}if(o.stream){ae(n,t,_,w,re(n,l.searchParams),f,"sse");return}if(o.name==="llm"){const c=D(await N(n)),S=new AbortController,O=i(()=>S.abort(),"abort");t.on("close",O);try{const q=await U(c,S.signal,c.stream?E=>{t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.write(`data: ${JSON.stringify(E)}
17
+ `)},15e3);return r.on("drain",h),r.on("close",o),d(),v}s(de,"streamRunEvents");function Pe(e,r,a){if(!e.issuer||!e.audience||!e.listener?.address||!Number.isInteger(e.listener.port)||e.listener.port<1||e.listener.port>65535)throw new Error("runtime issuer, audience and listener address/port are required");if(["0.0.0.0","::","[::]"].includes(e.listener.address))throw new Error("runtime listener must bind a specific address");const i=new J(e.issuer,e.audience,a,e.jwksUrl),l=new x,R=new Map;for(const n of H.filter(t=>t.stage!==void 0)){const t=s(()=>({status:500}),"handler");l.register({method:n.method,pattern:n.path,handler:t}),R.set(t,n)}const m=I((n,t)=>{(async()=>{const c=k();t.setHeader("Request-Id",c);let _;try{const f=new URL(n.url??"/","http://runtime.local");if(L(f.pathname)){await G(n,t,f,i);return}if((n.method!=="GET"||f.pathname!=="/v1/health")&&(!i.isReady()||!r()))throw new u(503,"runtime_starting","runtime_starting");const v=l.match(n.method??"GET",f.pathname);if(!v)throw new u(404,"not_found","unknown operation");const o=R.get(v.handler);if(!o)throw new u(404,"not_found","unknown operation");if(_=v.params.run_id,o.name==="health"){g(t,200,{status:"ok",api_version:"2026-09-23"});return}if(o.name==="runtime.sync-notice"){if(!await i.verifySyncNotice(n.headers.authorization)){t.writeHead(204),t.end();return}F({level:"info",event:"daemon.grants.sync_notice",fields:{request_id:c}});try{await a({fresh:!0})}catch{throw new u(503,"server_error","grant sync failed")}t.writeHead(204),t.end();return}if(o.name==="runtime.vendor-status"){await i.verifyDirectoryRead(n.headers.authorization,"vendor_status"),g(t,200,Z());return}const h=await i.resolve(n.headers.authorization,o.scope);if(t.setHeader("Request-Id",c),_&&A(h,_,["run.message","run.interrupt","run.cancel","run.rename","run.delete"].includes(o.name),o.name==="run.delete"),o.stream==="bytes"){await M(n,t,h,f.searchParams);return}if(o.stream){de(n,t,_,h,se(n,f.searchParams),c,"sse");return}if(o.name==="llm"){const d=X(await T(n)),b=new AbortController,y=s(()=>b.abort(),"abort");t.on("close",y);try{const S=await j(d,b.signal,d.stream?E=>{t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.write(`data: ${JSON.stringify(E)}
18
18
 
19
- `)}:void 0);c.stream?(t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.end(`data: [DONE]
19
+ `)}:void 0);d.stream?(t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.end(`data: [DONE]
20
20
 
21
- `)):y(t,200,q.completion)}finally{t.off("close",O)}return}if(o.name==="profile.list"){y(t,200,M(w));return}if(K.has(o.name)){const c=await Y(o.name,w,v.params.question_id,o.method==="POST"?await N(n):void 0);y(t,c.status,c.body);return}if(W.has(o.name)){const c=await V(o,w,v.params,l.searchParams,await N(n));y(t,c.status,c.body);return}const g=await $(o,w,_,l.searchParams,await N(n),n.headers["idempotency-key"]);y(t,g.status,g.body)}catch(l){te(t,l,f,_)}})()});return{ready:new Promise((n,t)=>{m.once("error",t),m.listen(e.listener.port,e.listener.address,()=>{m.off("error",t),n()})}),close:i(async()=>{s.close(),m.closeAllConnections(),await new Promise((n,t)=>m.close(f=>f?t(f):n()))},"close")}}i(Oe,"createAppListener");export{Oe as createAppListener,re as cursor,ae as streamRunEvents};
21
+ `)):g(t,200,S.completion)}finally{t.off("close",y)}return}if(o.name==="profile.list"){g(t,200,V(h));return}if(K.has(o.name)){const d=await Y(o.name,h,v.params.question_id,o.method==="POST"?await T(n):void 0);g(t,d.status,d.body);return}if(ne.has(o.name)){const{signal:d,release:b}=ee(t);try{const y=await re(o.name,te(h),{params:v.params,body:o.method==="POST"?await T(n):void 0},{requestId:c,signal:d});g(t,y.status,y.body)}catch(y){const S=ae(y,c,!0);t.writeHead(S.status,{"Content-Type":"application/json; charset=utf-8","X-Content-Type-Options":"nosniff",...S.headers}),t.end(JSON.stringify(S.body))}finally{b()}return}if(W.has(o.name)){const d=await Q(o,h,v.params,f.searchParams,await T(n));g(t,d.status,d.body);return}const O=await $(o,h,_,f.searchParams,await T(n),n.headers["idempotency-key"]);g(t,O.status,O.body)}catch(f){ie(t,f,c,_)}})()});return{ready:new Promise((n,t)=>{m.once("error",t),m.listen(e.listener.port,e.listener.address,()=>{m.off("error",t),n()})}),close:s(async()=>{i.close(),m.closeAllConnections(),await new Promise((n,t)=>m.close(c=>c?t(c):n()))},"close")}}s(Pe,"createAppListener");export{Pe as createAppListener,se as cursor,de as streamRunEvents};
@@ -0,0 +1,69 @@
1
+ import type { ServerResponse } from 'node:http';
2
+ import { type RequestPrincipal, type RouteTable } from '../router.js';
3
+ import type { AppPrincipal } from '../principal.js';
4
+ export declare const PROVIDER_OPERATIONS: Set<string>;
5
+ /** Who is calling, normalized across listeners. `resolved` is the caller's
6
+ * resolved scope set read at call time (the grant mirror, so a grant sync
7
+ * changes the answer for a running broker, D3-TOK-21); `null` = the person,
8
+ * who holds every group (contract 1 OWN-4). `nodeScopes` is a broker node's
9
+ * own narrowing list (`null` = none). */
10
+ export interface ProviderCaller {
11
+ class: 'person' | 'app' | 'broker';
12
+ /** The user on whose behalf; `null` for a person on the socket (R2 resolves it). */
13
+ sub: string | null;
14
+ grantee: string | null;
15
+ client_id: string | null;
16
+ resolved: readonly string[] | null;
17
+ nodeScopes: readonly string[] | null;
18
+ run_id: string | null;
19
+ node_id: string | null;
20
+ }
21
+ export declare function callerFromRequest(principal: RequestPrincipal): ProviderCaller;
22
+ export declare function callerFromApp(principal: AppPrincipal): ProviderCaller;
23
+ /** Does the caller hold `<provider>:<group>`? Both the resolved set and a
24
+ * broker's node list must cover it. */
25
+ export declare function callerAllows(caller: ProviderCaller, scope: string): boolean;
26
+ /** Throws `scope_missing` naming `<provider>:<group>` unless the caller holds it (D2-PRV-10). */
27
+ export declare function requireGroup(caller: ProviderCaller, provider: string, group: string): void;
28
+ /** v0 = no directory configured: both rows answer `not_found` (D3-V0-1). */
29
+ export declare function providerOperationsEnabled(): boolean;
30
+ export interface ProviderCallInput {
31
+ provider: string;
32
+ tool: string;
33
+ arguments: Record<string, unknown>;
34
+ version?: number;
35
+ /** Outside a run, the answered approval question the repeat names (R5). */
36
+ approval?: string;
37
+ }
38
+ export declare function parseProvider(value: unknown): string;
39
+ export declare function parseCallInput(body: unknown): ProviderCallInput;
40
+ /** Per-request context the call path needs: the audit `request_id` (also the
41
+ * `Crtr-Request-Id` a provider receives) and the signal that aborts the call
42
+ * when the caller's socket closes (R9). */
43
+ export interface ProviderRequest {
44
+ requestId: string;
45
+ signal: AbortSignal;
46
+ }
47
+ export interface ProviderInput {
48
+ params: Record<string, string>;
49
+ body: unknown;
50
+ }
51
+ /** Dispatch one provider operation. Throws `ProviderError`/`RunError`; the listener renders it with `providerErrorBody`. */
52
+ export declare function handleProviderOperation(name: string, caller: ProviderCaller, input: ProviderInput, request: ProviderRequest): Promise<{
53
+ status: number;
54
+ body: unknown;
55
+ }>;
56
+ /** An `AbortController` tied to the response: closing the caller's socket aborts the call. */
57
+ export declare function abortOnClose(res: ServerResponse): {
58
+ signal: AbortSignal;
59
+ release: () => void;
60
+ };
61
+ /** Render a thrown value as the contract-2 envelope; a non-`RunError` is logged as a 500.
62
+ * `directoryCaller`: true on the app listener (a directory-token caller), false on the socket. */
63
+ export declare function providerFailure(error: unknown, requestId: string, directoryCaller: boolean, runId?: string | null): {
64
+ status: number;
65
+ body: unknown;
66
+ headers: Record<string, string>;
67
+ };
68
+ /** Socket routes (person, broker). The router has already checked the caller class. */
69
+ export declare const providerRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var m=Object.defineProperty;var o=(e,r)=>m(e,"name",{value:r,configurable:!0});import{randomUUID as _}from"node:crypto";import{readConfig as w}from"../../../core/config.js";import{getNode as b}from"../../../core/canvas/canvas.js";import{scopeAllowed as c}from"../../../core/scopes.js";import{ProviderError as d,providerErrorBody as g,scopeMissing as y}from"../../../core/providers/errors.js";import{emitEvent as h}from"../../../core/events/emit.js";import{resolvedScopes as f}from"../router.js";const G=new Set(["provider.tools","provider.call"]);function S(e){return e.class==="person"?{class:"person",sub:null,grantee:null,client_id:null,resolved:null,nodeScopes:null,run_id:null,node_id:null}:e.class==="app"?{class:"app",sub:null,grantee:e.app,client_id:null,resolved:f(e),nodeScopes:null,run_id:null,node_id:null}:{class:"broker",sub:e.sub,grantee:e.app,client_id:e.client_id,resolved:f(e),nodeScopes:e.scopes,run_id:e.run??b(e.node)?.run_id??null,node_id:e.node}}o(S,"callerFromRequest");function U(e){return{class:"app",sub:e.sub,grantee:e.grantee,client_id:e.client_id,resolved:e.resolved,nodeScopes:null,run_id:null,node_id:null}}o(U,"callerFromApp");function A(e,r){return e.class==="person"?!0:c(e.resolved??[],r)&&c(e.nodeScopes,r)}o(A,"callerAllows");function V(e,r,t){const n=`${r}:${t}`;if(!A(e,n))throw y(n)}o(V,"requireGroup");function E(){return!!w("user").runtime?.issuer}o(E,"providerOperationsEnabled");const q=/^[A-Za-z0-9_-]{1,64}$/;function u(e,r){return new d("invalid_request",e,{param:r})}o(u,"invalid");function v(e){if(typeof e!="string"||!q.test(e)||e==="crtr")throw u("provider must be a provider id","provider");return e}o(v,"parseProvider");function x(e){if(!e||typeof e!="object"||Array.isArray(e))throw new d("invalid_request","a JSON object is required");const r=e,t=v(r.provider),n=r.tool;if(typeof n!="string"||!n.trim())throw u("tool must be a non-empty string","tool");const s=r.arguments??{};if(!s||typeof s!="object"||Array.isArray(s))throw u("arguments must be an object","arguments");const i=r.version;if(i!==void 0&&(typeof i!="number"||!Number.isInteger(i)||i<1))throw u("version must be an integer >= 1","version");const l=r.approval;if(l!==void 0&&(typeof l!="string"||!l))throw u("approval must be a question id","approval");return{provider:t,tool:n.trim(),arguments:s,...i===void 0?{}:{version:i},...l===void 0?{}:{approval:l}}}o(x,"parseCallInput");async function O(e,r,t){throw new d("not_implemented",`provider.tools is not implemented yet (provider ${r})`)}o(O,"providerTools");async function I(e,r,t){throw new d("not_implemented",`provider.call is not implemented yet (provider ${r.provider})`)}o(I,"providerCall");async function R(e,r,t,n){if(!E())throw new d("not_found","provider operations need a directory-connected runtime");if(e==="provider.tools")return O(r,v(t.params.provider),n);if(e==="provider.call")return I(r,x(t.body),n);throw new d("not_found","unknown operation")}o(R,"handleProviderOperation");function P(e){const r=new AbortController,t=o(()=>{e.writableFinished||r.abort()},"abort");return e.on("close",t),{signal:r.signal,release:o(()=>e.off("close",t),"release")}}o(P,"abortOnClose");function C(e,r,t,n){const s=g(e,r,t,n??void 0);return s.status>=500&&!(e instanceof d)&&h({event:"api.provider.failed",level:"error",error:e instanceof Error?e:new Error(String(e)),fields:{request_id:r}}),s}o(C,"providerFailure");const z=[{method:"GET",pattern:"/v1/providers/:provider/tools",name:"provider.tools"},{method:"POST",pattern:"/v1/provider/call",name:"provider.call"}].map(({method:e,pattern:r,name:t})=>({method:e,pattern:r,handler:o(async n=>{const s=_(),{signal:i,release:l}=P(n.res);let a=null;try{return a=S(n.principal),{...await R(t,a,{params:n.params,body:n.body},{requestId:s,signal:i}),headers:{"Request-Id":s}}}catch(p){return C(p,s,!1,a?.run_id)}finally{l()}},"handler")}));export{G as PROVIDER_OPERATIONS,P as abortOnClose,A as callerAllows,U as callerFromApp,S as callerFromRequest,R as handleProviderOperation,x as parseCallInput,v as parseProvider,C as providerFailure,E as providerOperationsEnabled,z as providerRoutes,V as requireGroup};
@@ -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:"chat-inventory.get.1",method:"GET",path:"/v1/nodes/:id/chat-inventory",classes:["person","broker"],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-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"],resource:"objects"},{name:"objects.list",method:"GET",path:"/v1/objects",classes:["person","app","broker"],resource:"objects"},{name:"objects.search",method:"POST",path:"/v1/objects/search",classes:["person","app","broker"],resource:"objects"},{name:"objects.watch",method:"POST",path:"/v1/objects/:ref/watch",classes:["person","app","broker"],resource:"objects"},{name:"objects.unwatch",method:"DELETE",path:"/v1/objects/:ref/watch",classes:["person","app","broker"],resource:"objects"},{name:"objects.edges",method:"GET",path:"/v1/objects/:ref/edges",classes:["person","app","broker"],resource:"objects"},{name:"docs.write",method:"POST",path:"/v1/docs",classes:["person","app","broker"],resource:"objects"},{name:"docs.edit",method:"PATCH",path:"/v1/docs/:ref",classes:["person","app","broker"],resource:"objects"},{name:"docs.move",method:"POST",path:"/v1/docs/:ref/move",classes:["person","app","broker"],resource:"objects"},{name:"docs.delete",method:"DELETE",path:"/v1/docs/:ref",classes:["person","app","broker"],resource:"objects"},{name:"docs.history",method:"GET",path:"/v1/docs/:ref/history",classes:["person","app","broker"],resource:"objects"},{name:"docs.lint",method:"POST",path:"/v1/docs/lint",classes:["person","app","broker"],resource:"objects"},{name:"documents.reconcile-packages",method:"POST",path:"/v1/documents/reconcile-packages",classes:["person","broker"],resource:"none"},{name:"nodes.delivery",method:"POST",path:"/v1/nodes/:id/delivery",classes:["person","broker"],resource:"node-own"},{name:"delivery.dry-run",method:"POST",path:"/v1/delivery/dry-run",classes:["person","broker"],resource:"none"},{name:"bash-jobs.background",method:"POST",path:"/v1/nodes/:id/jobs/:jobId/background",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"health.get.33",method:"GET",path:"/healthz",classes:["anonymous"],resource:"none"},{name:"health.get.34",method:"GET",path:"/v1/status",classes:["person","broker"],resource:"none"},{name:"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"],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"],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:"none"},{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"],resource:"node-write"},{name:"messages.post.59",method:"POST",path:"/v1/nodes/:id/interrupt",classes:["person","broker"],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"],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"],resource:"cron",scope:"crtr:schedule"},{name:"crons.get.74",method:"GET",path:"/v1/crons",classes:["person","app","broker"],resource:"cron"},{name:"crons.get.75",method:"GET",path:"/v1/crons/:cronId",classes:["person","app","broker"],resource:"cron"},{name:"crons.post.76",method:"POST",path:"/v1/crons/:cronId/pause",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.77",method:"POST",path:"/v1/crons/:cronId/resume",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.78",method:"POST",path:"/v1/crons/poke",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.79",method:"POST",path:"/v1/crons/:cronId/run",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.delete.80",method:"DELETE",path:"/v1/crons/:cronId",classes:["person","app","broker"],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",wait:!0},{name:"nodes.post.85",method:"POST",path:"/v1/nodes",classes:["person","broker"],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"],resource:"node-read"},{name:"nodes.get.89",method:"GET",path:"/v1/nodes/:id/snapshot",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.90",method:"GET",path:"/v1/nodes/:id/subject",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.91",method:"GET",path:"/v1/nodes/:id/messages",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.92",method:"GET",path:"/v1/nodes/:id/session",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.93",method:"GET",path:"/v1/nodes/:id/transcript",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.94",method:"GET",path:"/v1/nodes/:id/context",classes:["person","broker"],resource:"node-read"},{name:"nodes.post.96",method:"POST",path:"/v1/nodes/:id/fork",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.97",method:"POST",path:"/v1/nodes/:id/revive",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.98",method:"POST",path:"/v1/nodes/:id/relaunch-root",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.99",method:"POST",path:"/v1/nodes/:id/close",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.100",method:"POST",path:"/v1/nodes/:id/recycle",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.101",method:"POST",path:"/v1/nodes/:id/demote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.102",method:"POST",path:"/v1/nodes/:id/promote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.103",method:"POST",path:"/v1/nodes/:id/yield",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.104",method:"POST",path:"/v1/nodes/:id/wait",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.patch.105",method:"PATCH",path:"/v1/nodes/:id/config",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"broker-recovery.post.106",method:"POST",path:"/v1/broker/:id/turn",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.107",method:"POST",path:"/v1/broker/:id/provider-retry",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.108",method:"POST",path:"/v1/broker/:id/fault",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.get.109",method:"GET",path:"/v1/broker/:id/recovery",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.110",method:"POST",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"broker-recovery.delete.111",method:"DELETE",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"profiles.put.112",method:"PUT",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profiles.post.113",method:"POST",path:"/v1/profiles/:name/pause",classes:["person","broker"],resource:"profile"},{name:"profiles.post.114",method:"POST",path:"/v1/profiles/:name/resume",classes:["person","broker"],resource:"profile"},{name:"profiles.patch.115",method:"PATCH",path:"/v1/profiles/:name/metadata",classes:["person","app","broker"],resource:"profile"},{name:"profile.create",method:"POST",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile"},{name:"profile.update",method:"PATCH",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"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"],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"],resource:"node-read"},{name:"node-outcomes.delete.122",method:"DELETE",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"canvas.get.123",method:"GET",path:"/v1/canvas/attention",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.124",method:"POST",path:"/v1/canvas/attention/counts",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.125",method:"POST",path:"/v1/canvas/history/search",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.126",method:"POST",path:"/v1/canvas/history/grep",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.127",method:"GET",path:"/v1/canvas/history/read",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.128",method:"POST",path:"/v1/canvas/history/stats",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.129",method:"GET",path:"/v1/canvas/snapshot",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.130",method:"GET",path:"/v1/canvas/roster",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.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:"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:"llm",method:"POST",path:"/v1/llm",classes:["app","person","broker"],scope:"crtr:llm",resource:"none",stage:"v1"},{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"],resource:"run",stage:"v0.5"},{name:"run.get",method:"GET",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5",wait:!0},{name:"run.message",method:"POST",path:"/v1/runs/:run_id/messages",classes:["app","person","broker"],scope:"crtr:act",resource:"run",stage:"v0.5"},{name:"run.events",method:"GET",path:"/v1/runs/:run_id/events",classes:["app","person","broker"],resource:"run",stage:"v0.5",stream:!0},{name:"run.interrupt",method:"POST",path:"/v1/runs/:run_id/interrupt",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.cancel",method:"POST",path:"/v1/runs/:run_id/cancel",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.delete",method:"DELETE",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.rename",method:"POST",path:"/v1/runs/:run_id/rename",classes:["app"],resource:"run",stage:"chat"},{name:"question.get",method:"GET",path:"/v1/questions/:question_id",classes:["app"],resource:"none",stage:"chat"},{name:"question.answer",method:"POST",path:"/v1/questions/:question_id/answer",classes:["app"],resource:"none",stage:"chat"},{name:"trace.get",method:"GET",path:"/v1/runs/:run_id/trace",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"upload.create",method:"POST",path:"/v1/uploads",classes:["app"],scope:"crtr:act",resource:"none",stage:"file-transfer"},{name:"attachment.link",method:"GET",path:"/v1/attachments/link",classes:["app"],resource:"none",stage:"file-transfer"},{name:"file.download",method:"GET",path:"/v1/files/download",classes:["app"],resource:"none",stage:"file-transfer",stream:"bytes"},{name:"share.create",method:"POST",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.list",method:"GET",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.delete",method:"DELETE",path:"/v1/shares/:share_id",classes:["app"],resource:"none",stage:"file-transfer"},{name:"runtime.sync-notice",method:"POST",path:"/v1/runtime/sync-notice",classes:["directory"],resource:"none",stage:"v1"},{name:"runtime.vendor-status",method:"GET",path:"/v1/runtime/vendor-status",classes:["directory"],resource:"none",stage:"v1"}];function c(e,s){return n.find(o=>o.method===e.toUpperCase()&&o.path===s)}r(c,"operationFor");export{n as OPERATIONS,c as operationFor};
1
+ var a=Object.defineProperty;var r=(e,s)=>a(e,"name",{value:s,configurable:!0});const n=[{name:"health",method:"GET",path:"/v1/health",classes:["anonymous"],resource:"none",stage:"v0.5"},{name:"chat-inventory.get.1",method:"GET",path:"/v1/nodes/:id/chat-inventory",classes:["person","broker"],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-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"],resource:"objects"},{name:"objects.list",method:"GET",path:"/v1/objects",classes:["person","app","broker"],resource:"objects"},{name:"objects.search",method:"POST",path:"/v1/objects/search",classes:["person","app","broker"],resource:"objects"},{name:"objects.watch",method:"POST",path:"/v1/objects/:ref/watch",classes:["person","app","broker"],resource:"objects"},{name:"objects.unwatch",method:"DELETE",path:"/v1/objects/:ref/watch",classes:["person","app","broker"],resource:"objects"},{name:"objects.edges",method:"GET",path:"/v1/objects/:ref/edges",classes:["person","app","broker"],resource:"objects"},{name:"docs.write",method:"POST",path:"/v1/docs",classes:["person","app","broker"],resource:"objects"},{name:"docs.edit",method:"PATCH",path:"/v1/docs/:ref",classes:["person","app","broker"],resource:"objects"},{name:"docs.move",method:"POST",path:"/v1/docs/:ref/move",classes:["person","app","broker"],resource:"objects"},{name:"docs.delete",method:"DELETE",path:"/v1/docs/:ref",classes:["person","app","broker"],resource:"objects"},{name:"docs.history",method:"GET",path:"/v1/docs/:ref/history",classes:["person","app","broker"],resource:"objects"},{name:"docs.lint",method:"POST",path:"/v1/docs/lint",classes:["person","app","broker"],resource:"objects"},{name:"documents.reconcile-packages",method:"POST",path:"/v1/documents/reconcile-packages",classes:["person","broker"],resource:"none"},{name:"nodes.delivery",method:"POST",path:"/v1/nodes/:id/delivery",classes:["person","broker"],resource:"node-own"},{name:"delivery.dry-run",method:"POST",path:"/v1/delivery/dry-run",classes:["person","broker"],resource:"none"},{name:"bash-jobs.background",method:"POST",path:"/v1/nodes/:id/jobs/:jobId/background",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"health.get.33",method:"GET",path:"/healthz",classes:["anonymous"],resource:"none"},{name:"health.get.34",method:"GET",path:"/v1/status",classes:["person","broker"],resource:"none"},{name:"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"],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"],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:"none"},{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"],resource:"node-write"},{name:"messages.post.59",method:"POST",path:"/v1/nodes/:id/interrupt",classes:["person","broker"],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"],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"],resource:"cron",scope:"crtr:schedule"},{name:"crons.get.74",method:"GET",path:"/v1/crons",classes:["person","app","broker"],resource:"cron"},{name:"crons.get.75",method:"GET",path:"/v1/crons/:cronId",classes:["person","app","broker"],resource:"cron"},{name:"crons.post.76",method:"POST",path:"/v1/crons/:cronId/pause",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.77",method:"POST",path:"/v1/crons/:cronId/resume",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.78",method:"POST",path:"/v1/crons/poke",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.79",method:"POST",path:"/v1/crons/:cronId/run",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.delete.80",method:"DELETE",path:"/v1/crons/:cronId",classes:["person","app","broker"],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",wait:!0},{name:"nodes.post.85",method:"POST",path:"/v1/nodes",classes:["person","broker"],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"],resource:"node-read"},{name:"nodes.get.89",method:"GET",path:"/v1/nodes/:id/snapshot",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.90",method:"GET",path:"/v1/nodes/:id/subject",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.91",method:"GET",path:"/v1/nodes/:id/messages",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.92",method:"GET",path:"/v1/nodes/:id/session",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.93",method:"GET",path:"/v1/nodes/:id/transcript",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.94",method:"GET",path:"/v1/nodes/:id/context",classes:["person","broker"],resource:"node-read"},{name:"nodes.post.96",method:"POST",path:"/v1/nodes/:id/fork",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.97",method:"POST",path:"/v1/nodes/:id/revive",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.98",method:"POST",path:"/v1/nodes/:id/relaunch-root",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.99",method:"POST",path:"/v1/nodes/:id/close",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.100",method:"POST",path:"/v1/nodes/:id/recycle",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.101",method:"POST",path:"/v1/nodes/:id/demote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.102",method:"POST",path:"/v1/nodes/:id/promote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.103",method:"POST",path:"/v1/nodes/:id/yield",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.104",method:"POST",path:"/v1/nodes/:id/wait",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.patch.105",method:"PATCH",path:"/v1/nodes/:id/config",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"broker-recovery.post.106",method:"POST",path:"/v1/broker/:id/turn",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.107",method:"POST",path:"/v1/broker/:id/provider-retry",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.108",method:"POST",path:"/v1/broker/:id/fault",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.get.109",method:"GET",path:"/v1/broker/:id/recovery",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.110",method:"POST",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"broker-recovery.delete.111",method:"DELETE",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"profiles.put.112",method:"PUT",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profiles.post.113",method:"POST",path:"/v1/profiles/:name/pause",classes:["person","broker"],resource:"profile"},{name:"profiles.post.114",method:"POST",path:"/v1/profiles/:name/resume",classes:["person","broker"],resource:"profile"},{name:"profiles.patch.115",method:"PATCH",path:"/v1/profiles/:name/metadata",classes:["person","app","broker"],resource:"profile"},{name:"profile.create",method:"POST",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile"},{name:"profile.update",method:"PATCH",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"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"],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"],resource:"node-read"},{name:"node-outcomes.delete.122",method:"DELETE",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"canvas.get.123",method:"GET",path:"/v1/canvas/attention",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.124",method:"POST",path:"/v1/canvas/attention/counts",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.125",method:"POST",path:"/v1/canvas/history/search",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.126",method:"POST",path:"/v1/canvas/history/grep",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.127",method:"GET",path:"/v1/canvas/history/read",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.128",method:"POST",path:"/v1/canvas/history/stats",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.129",method:"GET",path:"/v1/canvas/snapshot",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.130",method:"GET",path:"/v1/canvas/roster",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.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:"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:"llm",method:"POST",path:"/v1/llm",classes:["app","person","broker"],scope:"crtr:llm",resource:"none",stage:"v1"},{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"],resource:"run",stage:"v0.5"},{name:"run.get",method:"GET",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5",wait:!0},{name:"run.message",method:"POST",path:"/v1/runs/:run_id/messages",classes:["app","person","broker"],scope:"crtr:act",resource:"run",stage:"v0.5"},{name:"run.events",method:"GET",path:"/v1/runs/:run_id/events",classes:["app","person","broker"],resource:"run",stage:"v0.5",stream:!0},{name:"run.interrupt",method:"POST",path:"/v1/runs/:run_id/interrupt",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.cancel",method:"POST",path:"/v1/runs/:run_id/cancel",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.delete",method:"DELETE",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.rename",method:"POST",path:"/v1/runs/:run_id/rename",classes:["app"],resource:"run",stage:"chat"},{name:"question.get",method:"GET",path:"/v1/questions/:question_id",classes:["app"],resource:"none",stage:"chat"},{name:"question.answer",method:"POST",path:"/v1/questions/:question_id/answer",classes:["app"],resource:"none",stage:"chat"},{name:"trace.get",method:"GET",path:"/v1/runs/:run_id/trace",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"upload.create",method:"POST",path:"/v1/uploads",classes:["app"],scope:"crtr:act",resource:"none",stage:"file-transfer"},{name:"attachment.link",method:"GET",path:"/v1/attachments/link",classes:["app"],resource:"none",stage:"file-transfer"},{name:"file.download",method:"GET",path:"/v1/files/download",classes:["app"],resource:"none",stage:"file-transfer",stream:"bytes"},{name:"share.create",method:"POST",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.list",method:"GET",path:"/v1/shares",classes:["app"],resource:"none",stage:"file-transfer"},{name:"share.delete",method:"DELETE",path:"/v1/shares/:share_id",classes:["app"],resource:"none",stage:"file-transfer"},{name:"provider.tools",method:"GET",path:"/v1/providers/:provider/tools",classes:["person","app","broker"],resource:"none",stage:"v1"},{name:"provider.call",method:"POST",path:"/v1/provider/call",classes:["person","app","broker"],resource:"none",stage:"v1"},{name:"runtime.sync-notice",method:"POST",path:"/v1/runtime/sync-notice",classes:["directory"],resource:"none",stage:"v1"},{name:"runtime.vendor-status",method:"GET",path:"/v1/runtime/vendor-status",classes:["directory"],resource:"none",stage:"v1"}];function c(e,s){return n.find(o=>o.method===e.toUpperCase()&&o.path===s)}r(c,"operationFor");export{n as OPERATIONS,c as operationFor};
@@ -1 +1 @@
1
- var Y=Object.defineProperty;var a=(t,o)=>Y(t,"name",{value:o,configurable:!0});import{createServer as H}from"node:http";import{chmodSync as Z,existsSync as C,unlinkSync as x}from"node:fs";import{apiSocketPath as K}from"../../core/canvas/paths.js";import{resolveNodeToken as I}from"../../core/canvas/node-tokens.js";import{grantFor as Q,hasSyncedGrants as V}from"../../core/grants/mirror.js";import{readConfig as U}from"../../core/config.js";import{peerUid as X}from"../../native/linux.js";import{getApiToken as q,listScopedApiTokens as ee}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as re,envCrtrdToken as te}from"../../shared/env.js";import{Router as B}from"./router.js";import{handleAttachUpgrade as oe,refuseUpgrade as A}from"./bridge.js";import{boundDaemonControl as ne}from"../control.js";import{attachRoutes as ie}from"./handlers/attach.js";import{bashJobRoutes as se}from"./handlers/bash-jobs.js";import{bashRoutes as le}from"./handlers/bash.js";import{hookExecRoutes as ae}from"./handlers/hook-exec.js";import{brokerOperationRoutes as j}from"./handlers/broker-ops.js";import{brokerRecoveryRoutes as G,nodeFaultRoutes as ce}from"./handlers/broker-recovery.js";import{canvasRoutes as ue}from"./handlers/canvas.js";import{chatInventoryRoutes as pe}from"./handlers/chat-inventory.js";import{daemonRoutes as de}from"./handlers/daemon.js";import{fileRoutes as me}from"./handlers/files.js";import{focusRoutes as fe}from"./handlers/focus.js";import{analyticsRoutes as ge}from"./handlers/analytics.js";import{memoryReadsRoutes as he}from"./handlers/memory-reads.js";import{healthRoutes as Ae}from"./handlers/health.js";import{humanRequestRoutes as Re}from"./handlers/human-requests.js";import{inboxRoutes as ve}from"./handlers/inbox.js";import{feedbackCommentRoutes as ye}from"./handlers/feedback-comments.js";import{objectRoutes as be}from"./handlers/objects.js";import{docRoutes as we}from"./handlers/docs.js";import{deliveryRoutes as $}from"./handlers/delivery.js";import{packageDocRoutes as ke}from"./handlers/package-docs.js";import{brokerMailRoutes as F,messageRoutes as Se}from"./handlers/messages.js";import{modelAuthRoutes as Te}from"./handlers/modelauth.js";import{llmRoutes as Ee}from"./handlers/llm.js";import{modelConfigRoutes as Ce}from"./handlers/model-config.js";import{nodeRoutes as Ue}from"./handlers/nodes.js";import{nodeRecordRoutes as Oe}from"./handlers/node-records.js";import{nodeOutcomeRoutes as ze}from"./handlers/node-outcomes.js";import{nodeEventRoutes as Pe}from"./handlers/node-events.js";import{profileRoutes as _e}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as Ne}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as He}from"./handlers/reports.js";import{runRoutes as xe}from"./handlers/run-routes.js";import{reviewCommentRoutes as Ie}from"./handlers/review-comments.js";import{reviewRoutes as Be}from"./handlers/reviews.js";import{subscriptionRoutes as je}from"./handlers/subscriptions.js";import{cronRoutes as Ge}from"./handlers/crons.js";import{worktreeRoutes as $e}from"./handlers/worktree.js";function Fe(t){return new B().registerAll(Ae(t)).registerAll(de).registerAll(Ue).registerAll(Oe).registerAll(ze).registerAll(Pe).registerAll(se).registerAll(le).registerAll(ae).registerAll(j).registerAll($).registerAll(G).registerAll(ce).registerAll($e).registerAll(F).registerAll(Se).registerAll(He).registerAll(xe).registerAll(ie).registerAll(ue).registerAll(ge).registerAll(he).registerAll(me).registerAll(be).registerAll(we).registerAll(ke).registerAll(fe).registerAll(je).registerAll(Ge).registerAll(_e).registerAll(Te).registerAll(Ee).registerAll(Ce).registerAll(Be).registerAll(Ie).registerAll(ve).registerAll(Re).registerAll(pe).registerAll(Ne).registerAll(ye)}a(Fe,"buildRouter");function Je(t,o){if(t.toUpperCase()!=="GET")return null;const s=o.split("/").filter(d=>d.length>0);if(s.length!==4||s[0]!=="v1"||s[1]!=="nodes"||s[3]!=="attach")return null;const p=s[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(Je,"attachNodeId");function Le(t){const o=t.trim();if(o==="")return null;const s=o.lastIndexOf(":");if(s<0)return null;const p=o.slice(0,s),d=o.slice(s+1),c=Number(d);return!Number.isInteger(c)||c<0||c>65535?null:{host:p===""?"0.0.0.0":p,port:c}}a(Le,"parseTcp");function De(t,o){return`${t.includes(":")?`[${t}]`:t}:${o}`}a(De,"formatTcpAddress");const v={code:"unauthorized",message:"missing or invalid bearer token"},w={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},k=new WeakMap;function Me(t){return k.get(t)}a(Me,"socketPrincipal");function J(t,o){const s=process.platform==="linux"?X(t.socket):null,p=t.headers.authorization;if(p===void 0)return s===null||o.has(s)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";const d=I(p.slice(7));if(!d||s!==null&&s!==d.uid)return"unauthorized";const c=U("user").runtime?.issuer;if(c&&!V(c.replace(/\/$/,"")))return"runtime_starting";const y=d.grant??Q("app:terminal",d.sub)?.id??null;return{class:"broker",...d,grant:y}}a(J,"resolveSocketPrincipal");function We(t){const o=new Map;for(const s of ee("user"))o.set(s.token,{principal:{class:"app",app:s.grantee,scopes:s.scopes},ceiling:s.scopes});return o.set(t,{principal:{class:"person"},ceiling:null}),o}a(We,"resolveBearers");function L(t,o){const s=t.headers.authorization;if(!(typeof s!="string"||!s.startsWith("Bearer ")))return o.get(s.slice(7))}a(L,"authorize");function S(t){t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:v}))}a(S,"writeUnauthorized");function Ye(t,o){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:o}}))}a(Ye,"writeStartupBlocked");function D(t){return new Promise(o=>{try{t.closeAllConnections()}catch{}t.close(()=>o())})}a(D,"closeServer");function Yr(t={}){let o=null;const s=Fe(()=>o),p=new B().registerAll(j).registerAll($).registerAll(G).registerAll(F),d=a((e,r)=>{const n=ne()?.startupBlock()??null;return n===null||e==="GET"&&(r==="/healthz"||r==="/v1/status")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||n.phase==="recovering"&&p.match(e,r)!==null?null:n},"startupBlockFor"),c=K(),y=new Set([process.getuid?.()??0,...U("user").runtime?.person_uids??[]]),T=a((e,r,n)=>{const l=a(i=>{g({event:"api.request.failed",level:"error",error:i instanceof Error?i:new Error(String(i))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error"}}))}catch{}},"internalFailure");let h;try{h=new URL(e.url??"/","http://127.0.0.1")}catch{try{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid"}}))}catch{}return}try{const i=d((e.method??"GET").toUpperCase(),h.pathname);if(i!==null){Ye(r,i.message);return}s.handle(e,r,n,Me(e)??{class:"person"}).catch(l)}catch(i){l(i)}},"onRequest"),E=a((e,r,n)=>{r.on("error",()=>{});try{const l=new URL(e.url??"/","http://127.0.0.1"),h=d((e.method??"GET").toUpperCase(),l.pathname);if(h!==null){A(r,503,"Service Unavailable","startup_blocked",h.message);return}const i=Je(e.method??"GET",l.pathname);if(i===null){r.destroy();return}oe(e,r,n,i).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),M=a(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),R=H((e,r)=>{try{const n=J(e,y);if(n==="unauthorized"){S(r);return}if(n==="runtime_starting"){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}k.set(e,n),n.class==="broker"&&g({event:"api.request.principal",level:"info",node_id:n.node,fields:{principal:`${n.app} node:${n.node}`,method:e.method,path:e.url}}),T(e,r,null)}catch(n){g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}),S(r)}});R.on("upgrade",(e,r,n)=>{try{const l=J(e,y);if(l==="unauthorized"||l==="runtime_starting"){A(r,l==="unauthorized"?401:503,"Unauthorized",l,"socket principal unavailable");return}if(l.class!=="person"&&l.class!=="broker"){A(r,403,"Forbidden",w.code,w.message);return}k.set(e,l),E(e,r,n)}catch(l){g({event:"api.principal.failed",level:"error",error:l instanceof Error?l:new Error(String(l))}),A(r,401,"Unauthorized",v.code,v.message)}});let O=!1,z,P;const W=new Promise((e,r)=>{z=e,P=r});R.once("listening",()=>{O=!0,z()}),R.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),O||P(e)});try{C(c)&&x(c)}catch{}R.listen(c,()=>{try{Z(c,process.platform==="linux"&&C("/run/crtr/launcher.sock")?438:384)}catch(e){g({event:"api.socket.chmod_failed",level:"error",error:e instanceof Error?e:new Error(String(e))})}});let f;const b=t.tcp??re()??U("user").api.tcp;if(b!==void 0&&b!==""){const e=Le(b);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${b}`)});else{const r=t.token??te()??q("user"),n=r===void 0?void 0:We(r),l=n===void 0?(i,u)=>{const m=i.headers.authorization;if(typeof m=="string"&&m.startsWith("Bearer ")&&I(m.slice(7))){S(u);return}T(i,u,null)}:(i,u)=>{if((i.method??"GET").toUpperCase()==="OPTIONS"){u.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"authorization, content-type","Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),u.end();return}const m=L(i,n);if(m===void 0){S(u);return}k.set(i,m.principal),u.setHeader("Access-Control-Allow-Origin","*"),T(i,u,m.ceiling)},h=n===void 0?E:(i,u,m)=>{const N=L(i,n);if(N===void 0){A(u,401,"Unauthorized",v.code,v.message);return}if(N.ceiling!==null){A(u,403,"Forbidden",w.code,w.message);return}E(i,u,m)};f=H(l),f.on("upgrade",h),M(f),f.once("listening",()=>{const i=f?.address();if(i!==null&&typeof i=="object"){const{address:u,port:m}=i;o=De(u,m)}}),f.listen(e.port,e.host)}}let _=!1;return{ready:W,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!_){_=!0,await Promise.all([D(R),f!==void 0?D(f):Promise.resolve()]);try{C(c)&&x(c)}catch{}}},"close")}}a(Yr,"createApiServer");export{Yr as createApiServer,Me as socketPrincipal};
1
+ var Y=Object.defineProperty;var a=(t,o)=>Y(t,"name",{value:o,configurable:!0});import{createServer as H}from"node:http";import{chmodSync as Z,existsSync as C,unlinkSync as x}from"node:fs";import{apiSocketPath as K}from"../../core/canvas/paths.js";import{resolveNodeToken as I}from"../../core/canvas/node-tokens.js";import{grantFor as Q,hasSyncedGrants as V}from"../../core/grants/mirror.js";import{readConfig as U}from"../../core/config.js";import{peerUid as X}from"../../native/linux.js";import{getApiToken as q,listScopedApiTokens as ee}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as re,envCrtrdToken as te}from"../../shared/env.js";import{Router as B}from"./router.js";import{handleAttachUpgrade as oe,refuseUpgrade as A}from"./bridge.js";import{boundDaemonControl as ne}from"../control.js";import{attachRoutes as ie}from"./handlers/attach.js";import{bashJobRoutes as se}from"./handlers/bash-jobs.js";import{bashRoutes as le}from"./handlers/bash.js";import{hookExecRoutes as ae}from"./handlers/hook-exec.js";import{brokerOperationRoutes as j}from"./handlers/broker-ops.js";import{brokerRecoveryRoutes as G,nodeFaultRoutes as ce}from"./handlers/broker-recovery.js";import{canvasRoutes as ue}from"./handlers/canvas.js";import{chatInventoryRoutes as pe}from"./handlers/chat-inventory.js";import{daemonRoutes as de}from"./handlers/daemon.js";import{fileRoutes as me}from"./handlers/files.js";import{focusRoutes as fe}from"./handlers/focus.js";import{analyticsRoutes as ge}from"./handlers/analytics.js";import{memoryReadsRoutes as he}from"./handlers/memory-reads.js";import{healthRoutes as Ae}from"./handlers/health.js";import{humanRequestRoutes as Re}from"./handlers/human-requests.js";import{inboxRoutes as ve}from"./handlers/inbox.js";import{feedbackCommentRoutes as ye}from"./handlers/feedback-comments.js";import{objectRoutes as be}from"./handlers/objects.js";import{docRoutes as we}from"./handlers/docs.js";import{deliveryRoutes as $}from"./handlers/delivery.js";import{packageDocRoutes as ke}from"./handlers/package-docs.js";import{brokerMailRoutes as F,messageRoutes as Se}from"./handlers/messages.js";import{modelAuthRoutes as Te}from"./handlers/modelauth.js";import{llmRoutes as Ee}from"./handlers/llm.js";import{providerRoutes as Ce}from"./handlers/providers.js";import{modelConfigRoutes as Ue}from"./handlers/model-config.js";import{nodeRoutes as Oe}from"./handlers/nodes.js";import{nodeRecordRoutes as ze}from"./handlers/node-records.js";import{nodeOutcomeRoutes as Pe}from"./handlers/node-outcomes.js";import{nodeEventRoutes as _e}from"./handlers/node-events.js";import{profileRoutes as Ne}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as He}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as xe}from"./handlers/reports.js";import{runRoutes as Ie}from"./handlers/run-routes.js";import{reviewCommentRoutes as Be}from"./handlers/review-comments.js";import{reviewRoutes as je}from"./handlers/reviews.js";import{subscriptionRoutes as Ge}from"./handlers/subscriptions.js";import{cronRoutes as $e}from"./handlers/crons.js";import{worktreeRoutes as Fe}from"./handlers/worktree.js";function Je(t){return new B().registerAll(Ae(t)).registerAll(de).registerAll(Oe).registerAll(ze).registerAll(Pe).registerAll(_e).registerAll(se).registerAll(le).registerAll(ae).registerAll(j).registerAll($).registerAll(G).registerAll(ce).registerAll(Fe).registerAll(F).registerAll(Se).registerAll(xe).registerAll(Ie).registerAll(ie).registerAll(ue).registerAll(ge).registerAll(he).registerAll(me).registerAll(be).registerAll(we).registerAll(ke).registerAll(fe).registerAll(Ge).registerAll($e).registerAll(Ne).registerAll(Te).registerAll(Ee).registerAll(Ce).registerAll(Ue).registerAll(je).registerAll(Be).registerAll(ve).registerAll(Re).registerAll(pe).registerAll(He).registerAll(ye)}a(Je,"buildRouter");function Le(t,o){if(t.toUpperCase()!=="GET")return null;const s=o.split("/").filter(d=>d.length>0);if(s.length!==4||s[0]!=="v1"||s[1]!=="nodes"||s[3]!=="attach")return null;const p=s[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(Le,"attachNodeId");function De(t){const o=t.trim();if(o==="")return null;const s=o.lastIndexOf(":");if(s<0)return null;const p=o.slice(0,s),d=o.slice(s+1),c=Number(d);return!Number.isInteger(c)||c<0||c>65535?null:{host:p===""?"0.0.0.0":p,port:c}}a(De,"parseTcp");function Me(t,o){return`${t.includes(":")?`[${t}]`:t}:${o}`}a(Me,"formatTcpAddress");const v={code:"unauthorized",message:"missing or invalid bearer token"},w={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},k=new WeakMap;function We(t){return k.get(t)}a(We,"socketPrincipal");function J(t,o){const s=process.platform==="linux"?X(t.socket):null,p=t.headers.authorization;if(p===void 0)return s===null||o.has(s)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";const d=I(p.slice(7));if(!d||s!==null&&s!==d.uid)return"unauthorized";const c=U("user").runtime?.issuer;if(c&&!V(c.replace(/\/$/,"")))return"runtime_starting";const y=d.grant??Q("app:terminal",d.sub)?.id??null;return{class:"broker",...d,grant:y}}a(J,"resolveSocketPrincipal");function Ye(t){const o=new Map;for(const s of ee("user"))o.set(s.token,{principal:{class:"app",app:s.grantee,scopes:s.scopes},ceiling:s.scopes});return o.set(t,{principal:{class:"person"},ceiling:null}),o}a(Ye,"resolveBearers");function L(t,o){const s=t.headers.authorization;if(!(typeof s!="string"||!s.startsWith("Bearer ")))return o.get(s.slice(7))}a(L,"authorize");function S(t){t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:v}))}a(S,"writeUnauthorized");function Ze(t,o){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:o}}))}a(Ze,"writeStartupBlocked");function D(t){return new Promise(o=>{try{t.closeAllConnections()}catch{}t.close(()=>o())})}a(D,"closeServer");function Kr(t={}){let o=null;const s=Je(()=>o),p=new B().registerAll(j).registerAll($).registerAll(G).registerAll(F),d=a((e,r)=>{const n=ne()?.startupBlock()??null;return n===null||e==="GET"&&(r==="/healthz"||r==="/v1/status")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||n.phase==="recovering"&&p.match(e,r)!==null?null:n},"startupBlockFor"),c=K(),y=new Set([process.getuid?.()??0,...U("user").runtime?.person_uids??[]]),T=a((e,r,n)=>{const l=a(i=>{g({event:"api.request.failed",level:"error",error:i instanceof Error?i:new Error(String(i))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error"}}))}catch{}},"internalFailure");let h;try{h=new URL(e.url??"/","http://127.0.0.1")}catch{try{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid"}}))}catch{}return}try{const i=d((e.method??"GET").toUpperCase(),h.pathname);if(i!==null){Ze(r,i.message);return}s.handle(e,r,n,We(e)??{class:"person"}).catch(l)}catch(i){l(i)}},"onRequest"),E=a((e,r,n)=>{r.on("error",()=>{});try{const l=new URL(e.url??"/","http://127.0.0.1"),h=d((e.method??"GET").toUpperCase(),l.pathname);if(h!==null){A(r,503,"Service Unavailable","startup_blocked",h.message);return}const i=Le(e.method??"GET",l.pathname);if(i===null){r.destroy();return}oe(e,r,n,i).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),M=a(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),R=H((e,r)=>{try{const n=J(e,y);if(n==="unauthorized"){S(r);return}if(n==="runtime_starting"){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}k.set(e,n),n.class==="broker"&&g({event:"api.request.principal",level:"info",node_id:n.node,fields:{principal:`${n.app} node:${n.node}`,method:e.method,path:e.url}}),T(e,r,null)}catch(n){g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}),S(r)}});R.on("upgrade",(e,r,n)=>{try{const l=J(e,y);if(l==="unauthorized"||l==="runtime_starting"){A(r,l==="unauthorized"?401:503,"Unauthorized",l,"socket principal unavailable");return}if(l.class!=="person"&&l.class!=="broker"){A(r,403,"Forbidden",w.code,w.message);return}k.set(e,l),E(e,r,n)}catch(l){g({event:"api.principal.failed",level:"error",error:l instanceof Error?l:new Error(String(l))}),A(r,401,"Unauthorized",v.code,v.message)}});let O=!1,z,P;const W=new Promise((e,r)=>{z=e,P=r});R.once("listening",()=>{O=!0,z()}),R.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),O||P(e)});try{C(c)&&x(c)}catch{}R.listen(c,()=>{try{Z(c,process.platform==="linux"&&C("/run/crtr/launcher.sock")?438:384)}catch(e){g({event:"api.socket.chmod_failed",level:"error",error:e instanceof Error?e:new Error(String(e))})}});let f;const b=t.tcp??re()??U("user").api.tcp;if(b!==void 0&&b!==""){const e=De(b);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${b}`)});else{const r=t.token??te()??q("user"),n=r===void 0?void 0:Ye(r),l=n===void 0?(i,u)=>{const m=i.headers.authorization;if(typeof m=="string"&&m.startsWith("Bearer ")&&I(m.slice(7))){S(u);return}T(i,u,null)}:(i,u)=>{if((i.method??"GET").toUpperCase()==="OPTIONS"){u.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"authorization, content-type","Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),u.end();return}const m=L(i,n);if(m===void 0){S(u);return}k.set(i,m.principal),u.setHeader("Access-Control-Allow-Origin","*"),T(i,u,m.ceiling)},h=n===void 0?E:(i,u,m)=>{const N=L(i,n);if(N===void 0){A(u,401,"Unauthorized",v.code,v.message);return}if(N.ceiling!==null){A(u,403,"Forbidden",w.code,w.message);return}E(i,u,m)};f=H(l),f.on("upgrade",h),M(f),f.once("listening",()=>{const i=f?.address();if(i!==null&&typeof i=="object"){const{address:u,port:m}=i;o=Me(u,m)}}),f.listen(e.port,e.host)}}let _=!1;return{ready:W,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!_){_=!0,await Promise.all([D(R),f!==void 0?D(f):Promise.resolve()]);try{C(c)&&x(c)}catch{}}},"close")}}a(Kr,"createApiServer");export{Kr as createApiServer,We as socketPrincipal};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.356",
3
+ "version": "0.3.358",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -131,7 +131,7 @@
131
131
  "@earendil-works/pi-ai": "0.87.1",
132
132
  "@earendil-works/pi-coding-agent": "0.87.1",
133
133
  "@earendil-works/pi-tui": "0.87.1",
134
- "@north-light/crouter-identity": "^0.3.356",
134
+ "@north-light/crouter-identity": "^0.3.358",
135
135
  "cron-parser": "^5.6.0",
136
136
  "esbuild": "^0.27.7",
137
137
  "jose": "^6.2.12",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter-identity",
3
- "version": "0.3.356",
3
+ "version": "0.3.358",
4
4
  "description": "Northlight access-token verification and scope rules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",