@north-light/crouter 0.3.356 → 0.3.357

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.357",
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.357",
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.357",
4
4
  "description": "Northlight access-token verification and scope rules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.356",
3
+ "version": "0.3.357",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.356",
9
+ "version": "0.3.357",
10
10
  "hasInstallScript": true,
11
11
  "license": "GPL-3.0-only",
12
12
  "workspaces": [
@@ -18,7 +18,7 @@
18
18
  "@earendil-works/pi-ai": "0.87.1",
19
19
  "@earendil-works/pi-coding-agent": "0.87.1",
20
20
  "@earendil-works/pi-tui": "0.87.1",
21
- "@north-light/crouter-identity": "^0.3.356",
21
+ "@north-light/crouter-identity": "^0.3.357",
22
22
  "cron-parser": "^5.6.0",
23
23
  "esbuild": "^0.27.7",
24
24
  "jose": "^6.2.12",
@@ -10885,17 +10885,17 @@
10885
10885
  },
10886
10886
  "packages/crouter-api": {
10887
10887
  "name": "@north-light/crouter-api",
10888
- "version": "0.3.356",
10888
+ "version": "0.3.357",
10889
10889
  "license": "GPL-3.0-only"
10890
10890
  },
10891
10891
  "packages/crouter-env-docker": {
10892
10892
  "name": "@north-light/crouter-env-docker",
10893
- "version": "0.3.356",
10893
+ "version": "0.3.357",
10894
10894
  "license": "GPL-3.0-only"
10895
10895
  },
10896
10896
  "packages/crouter-identity": {
10897
10897
  "name": "@north-light/crouter-identity",
10898
- "version": "0.3.356",
10898
+ "version": "0.3.357",
10899
10899
  "license": "GPL-3.0-only",
10900
10900
  "dependencies": {
10901
10901
  "jose": "^6.2.1"
@@ -10903,19 +10903,19 @@
10903
10903
  },
10904
10904
  "packages/crouter-plugin": {
10905
10905
  "name": "@north-light/crouter-plugin",
10906
- "version": "0.3.356",
10906
+ "version": "0.3.357",
10907
10907
  "license": "GPL-3.0-only",
10908
10908
  "dependencies": {
10909
- "@north-light/crouter-api": "^0.3.356"
10909
+ "@north-light/crouter-api": "^0.3.357"
10910
10910
  }
10911
10911
  },
10912
10912
  "packages/crouter-sdk": {
10913
10913
  "name": "@north-light/crouter-sdk",
10914
- "version": "0.3.356",
10914
+ "version": "0.3.357",
10915
10915
  "license": "GPL-3.0-only",
10916
10916
  "dependencies": {
10917
- "@north-light/crouter-api": "^0.3.356",
10918
- "@north-light/crouter-identity": "^0.3.356",
10917
+ "@north-light/crouter-api": "^0.3.357",
10918
+ "@north-light/crouter-identity": "^0.3.357",
10919
10919
  "jose": "^6.2.1"
10920
10920
  }
10921
10921
  }