@north-light/cli 0.3.568 → 0.3.570
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/attach/viewer.js +151 -151
- package/dist/clients/inbox/tui/render.js +2 -2
- package/dist/core/canvas/export-sqlite.js +2 -2
- package/dist/core/grants/mirror.d.ts +14 -0
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/providers/bundles.d.ts +0 -4
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/scoped-state/materialized-plugins.d.ts +2 -0
- package/dist/core/scoped-state/materialized-plugins.js +1 -1
- package/dist/core/scoped-state/person-rows.js +5 -5
- package/dist/daemon/api/handlers/execution-start.js +2 -2
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
var Ue=Object.defineProperty;var i=(e,r)=>Ue(e,"name",{value:r,configurable:!0});import{createServer as ee}from"node:http";import{createServer as Pe}from"node:https";import{chmodSync as ke,existsSync as $,readFileSync as re,unlinkSync as te}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as ne,RUNTIME_VERSION_HEADER as j,minimumRuntimeRefusal as ze}from"../../api/runtime-version.js";import{CONTRACT_HEADER as M,CONTRACT_LEVEL as oe,REQUIRED_CONTRACT_HEADER as ie,contractRefusal as Ne}from"../../api/contract.js";import{crtrVersion as V}from"../../shared/crtr-version.js";import{apiSocketPath as He}from"../../core/canvas/paths.js";import{resolveNodeToken as Ie}from"../../core/canvas/node-tokens.js";import{isCloudRole as P,runAsPerson as B}from"../../core/canvas/person.js";import{personBearerVerifier as se}from"./auth/person-bearer.js";import{personHasSnapshot as W}from"../../core/scoped-state/person-store.js";import{loadPersonSettings as F}from"../../core/scoped-state/person-rows.js";import{AppPrincipalResolver as Le}from"./principal.js";import{createAppRequestHandler as Be}from"./app-listener.js";import{decodeJwt as De}from"jose";import{handleVendorSignIn as xe,isVendorSignInPath as Je}from"./vendor-signin.js";import{RunError as E}from"../../core/runs/operations.js";import{removeVendorAccount as $e,vendorStatus as je}from"./handlers/vendor-status.js";import{toErrorBody as Me}from"./map.js";import{CONTROL_BODY_MAX_BYTES as Ve}from"../../core/llm/body-limits.js";import{grantFor as We,hasSyncedGrants as Fe}from"../../core/grants/mirror.js";import{readConfig as ae}from"../../core/config.js";import{directoryIssuer as Ge}from"../../core/directory/issuer.js";import{peerUid as Ye}from"../../native/linux.js";import{findScopedApiToken as Ze,getApiToken as Ke,listScopedApiTokens as Xe}from"../../core/secrets.js";import{emitEvent as A}from"../../core/events/emit.js";import{envCrtrdTcp as Qe,envCrtrdToken as qe}from"../../shared/env.js";import{Router as le,actsAsPerson as ce}from"./router.js";import{handleAttachUpgrade as er,refuseUpgrade as y}from"./bridge.js";import{boundDaemonControl as rr}from"../control.js";import{attachRoutes as tr,mayAttachNode as ue}from"./handlers/attach.js";import{peerRoutes as nr}from"../peer/handlers.js";import{bashJobRoutes as or}from"./handlers/bash-jobs.js";import{bashRoutes as ir}from"./handlers/bash.js";import{hookExecRoutes as sr}from"./handlers/hook-exec.js";import{brokerOperationRoutes as de}from"./handlers/broker-ops.js";import{brokerSignalRoutes as ar,brokerSignalStreams as lr}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as pe,nodeFaultRoutes as cr}from"./handlers/broker-recovery.js";import{canvasRoutes as ur}from"./handlers/canvas.js";import{conversationRoutes as dr}from"./handlers/conversations.js";import{chatInventoryRoutes as pr}from"./handlers/chat-inventory.js";import{daemonRoutes as fr}from"./handlers/daemon.js";import{fileRoutes as mr}from"./handlers/files.js";import{focusRoutes as gr}from"./handlers/focus.js";import{analyticsRoutes as hr}from"./handlers/analytics.js";import{memoryReadsRoutes as Rr}from"./handlers/memory-reads.js";import{memoryRoutes as Ar}from"./handlers/memory.js";import{healthRoutes as yr}from"./handlers/health.js";import{humanRequestRoutes as vr}from"./handlers/human-requests.js";import{inboxRoutes as wr}from"./handlers/inbox.js";import{feedbackCommentRoutes as _r}from"./handlers/feedback-comments.js";import{objectRoutes as Sr}from"./handlers/objects.js";import{shareRoutes as Er}from"./handlers/shares.js";import{customObjectRoutes as br}from"./handlers/custom-objects.js";import{docRoutes as Tr}from"./handlers/docs.js";import{deliveryRoutes as fe}from"./handlers/delivery.js";import{deliveryRetryRoutes as Cr}from"./handlers/delivery-retry.js";import{packageDocRoutes as Or}from"./handlers/package-docs.js";import{documentAccessRoutes as Ur}from"./handlers/document-access.js";import{pluginAppRoutes as Pr}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as me,messageRoutes as kr}from"./handlers/messages.js";import{modelAuthRoutes as zr}from"./handlers/modelauth.js";import{llmRoutes as Nr}from"./handlers/llm.js";import{providerRoutes as Hr}from"./handlers/providers.js";import{modelConfigRoutes as Ir}from"./handlers/model-config.js";import{settingsRoutes as Lr}from"./handlers/settings.js";import{nodeRoutes as Br}from"./handlers/nodes.js";import{nodeRecordRoutes as Dr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as xr}from"./handlers/node-outcomes.js";import{nodeEventRoutes as Jr}from"./handlers/node-events.js";import{profileRoutes as $r}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as jr}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as Mr}from"./handlers/reports.js";import{runRoutes as Vr}from"./handlers/run-routes.js";import{reviewCommentRoutes as Wr}from"./handlers/review-comments.js";import{reviewRoutes as Fr}from"./handlers/reviews.js";import{subscriptionRoutes as Gr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as Yr}from"./handlers/structured-requests.js";import{cronRoutes as Zr}from"./handlers/crons.js";import{setCronRequestHandler as ge}from"../cron/run-socket.js";import{worktreeRoutes as Kr}from"./handlers/worktree.js";import{limitsRoutes as Xr}from"./handlers/limits.js";import{chargeRoutes as Qr,spendLimitRoutes as qr}from"./handlers/charges.js";import{executionStartRoutes as et}from"./handlers/execution-start.js";import{gitCredentialRoutes as rt}from"./handlers/git-credential.js";function tt(e){return new le().registerAll(yr(e)).registerAll(fr).registerAll(Er).registerAll(Br).registerAll(Dr).registerAll(xr).registerAll(Cr).registerAll(Jr).registerAll(or).registerAll(ir).registerAll(sr).registerAll(de).registerAll(ar).registerAll(fe).registerAll(pe).registerAll(cr).registerAll(Kr).registerAll(Xr).registerAll(Qr).registerAll(et).registerAll(rt).registerAll(qr).registerAll(me).registerAll(kr).registerAll(Mr).registerAll(Vr).registerAll(Yr).registerAll(tr).registerAll(ur).registerAll(dr).registerAll(hr).registerAll(Rr).registerAll(Ar).registerAll(mr).registerAll(Sr).registerAll(br).registerAll(Tr).registerAll(Or).registerAll(Ur).registerAll(Pr).registerAll(gr).registerAll(Gr).registerAll(Zr).registerAll($r).registerAll(zr).registerAll(Nr).registerAll(Hr).registerAll(Ir).registerAll(Lr).registerAll(Fr).registerAll(Wr).registerAll(wr).registerAll(vr).registerAll(pr).registerAll(jr).registerAll(_r).registerAll(nr)}i(tt,"buildRouter");function nt(e,r){if(e.toUpperCase()!=="GET")return null;const s=r.split("/").filter(f=>f.length>0);if(s.length!==4||s[0]!=="v1"||s[1]!=="nodes"||s[3]!=="attach")return null;const o=s[2];return o===void 0||o===""?null:decodeURIComponent(o)}i(nt,"attachNodeId");function ot(e){const r=e.trim();if(r==="")return null;const s=r.lastIndexOf(":");if(s<0)return null;const o=r.slice(0,s),f=r.slice(s+1),p=Number(f);return!Number.isInteger(p)||p<0||p>65535?null:{host:o===""?"0.0.0.0":o,port:p}}i(ot,"parseTcp");function it(e,r){return`${e.includes(":")?`[${e}]`:e}:${r}`}i(it,"formatTcpAddress");const T={code:"unauthorized",message:"missing or invalid bearer token"},k={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},H={code:"person_bearer_not_supported",message:"this listener accepts a person bearer only on a cloud role with CRTR_DIRECTORY_URL and CRTR_PUBLIC_API_URL set; call with a node, app or public token"},G={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},z=new WeakMap;function I(e){return z.get(e)}i(I,"socketPrincipal");async function he(e,r){const s=process.platform==="linux"?Ye(e.socket):null,o=e.headers.authorization;if(o===void 0)return s===null||r.has(s)?{class:"person"}:"unauthorized";if(typeof o!="string"||!o.startsWith("Bearer "))return"unauthorized";if(o.slice(7).startsWith("crtr_pub_"))return G;if(o.slice(7).startsWith(Y)){const f=ve(o.slice(7));return f!==void 0&&(s===null||r.has(s))?f.principal:"unauthorized"}return Re(o.slice(7),s)}i(he,"resolveSocketPrincipal");async function Re(e,r){const s=await Ie(e);if(!s||r!==null&&r!==s.uid)return"unauthorized";const o=Ge();if(o&&!P()&&!await Fe(o))return"runtime_starting";const f=s.grant??(await We("app:terminal",s.sub))?.id??null;return{class:"broker",...s,grant:f}}i(Re,"brokerPrincipal");function Ae(e){if(e.class!=="anonymous")return e.sub!==void 0&&e.sub!==""?e.sub:void 0}i(Ae,"requestPerson");function ye(e,r){r.class==="broker"&&A({event:"api.request.principal",level:r.app==="app:terminal"?"debug":"info",node_id:r.node,fields:{principal:`${r.app} node:${r.node}`,method:e.method,path:e.url}})}i(ye,"noteBrokerRequest");const Y="crtr_app_";function ve(e){const r=e.startsWith(Y)?Ze(e):void 0;return r===void 0?void 0:{principal:{class:"app",app:r.grantee,scopes:r.scopes},ceiling:r.scopes}}i(ve,"appBearer");function st(e){const r=new Map;for(const s of Xe("user"))r.set(s.token,{principal:{class:"app",app:s.grantee,scopes:s.scopes},ceiling:s.scopes});return e!==void 0&&r.set(e,{principal:{class:"person"},ceiling:null}),r}i(st,"resolveBearers");function at(e){try{return De(e).act!==void 0}catch{return!1}}i(at,"carriesAct");const lt=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/;async function we(e,r){const s=e.headers.authorization;if(s===void 0&&(e.method??"GET").toUpperCase()==="GET"&&(e.url??"").split("?")[0]==="/healthz")return{principal:G,ceiling:null};if(typeof s!="string"||!s.startsWith("Bearer "))return"unauthorized";const o=s.slice(7);if(o.startsWith("crtr_pub_"))return{principal:G,ceiling:null};if(o.startsWith(Y))return ve(o)??"unauthorized";const f=r.get(o);if(f!==void 0)return f;if(lt.test(o)){if(P()&&at(o)){const U=x();if(U===null)return"person_bearer";try{const v=await U.verifyCall(s);return v.chain[0]?.sub.startsWith("app:")?{call:v}:"unauthorized"}catch(v){return v instanceof E&&v.status===503?"runtime_starting":"unauthorized"}}const R=P()?se():null;if(R===null)return"person_bearer";const m=await R.verify(o);return m===null?"unauthorized":{principal:{class:"person",sub:m},ceiling:null}}const p=await Re(o,null);return typeof p=="string"?p:{principal:p,ceiling:null}}i(we,"authorizeTcp");let D;function x(){if(D!==void 0)return D;const e=process.env.CRTR_DIRECTORY_URL||void 0,r=process.env.CRTR_PUBLIC_API_URL||void 0;return D=e===void 0||r===void 0?null:new Le(e,r,async()=>{}),D}i(x,"cloudCallResolver");let _e;function ct(){const e=x();if(e===null)throw new E(503,"runtime_starting","app calls are not configured on this listener");return _e??=Be(e,async()=>!0,async()=>{}),_e}i(ct,"cloudAppCalls");async function ut(e,r){C(r),O(r);const s=x();try{if(s===null)throw new E(503,"runtime_starting","vendor sign-in is not configured on this listener");await xe(e,r,new URL(e.url??"/","http://runtime.local"),s)}catch(o){if(!(o instanceof E))throw o;if(r.headersSent){r.destroy();return}r.writeHead(o.status,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),r.end(JSON.stringify({error:{code:o.code,message:o.message,...o.param?{param:o.param}:{},origin:"runtime"}}))}}i(ut,"serveVendorSignIn");function dt(){const e=process.env.CRTRD_TLS_CERT||void 0,r=process.env.CRTRD_TLS_KEY||void 0;if(e===void 0&&r===void 0)return null;if(e===void 0||r===void 0)throw new Error("CRTRD_TLS_CERT and CRTRD_TLS_KEY must be set together");return{cert:re(e),key:re(r)}}i(dt,"tcpTls");function C(e){e.setHeader(j,V()),e.setHeader(M,oe)}i(C,"advertiseRuntime");function O(e){e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Expose-Headers",`${j}, ${M}`)}i(O,"exposeRuntimeHeaders");function pt(e,r){return(e.method??"GET").toUpperCase()!=="OPTIONS"?!1:(C(r),r.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${j}, ${M}`,"Access-Control-Allow-Headers":`authorization, content-type, ${ne.toLowerCase()}, ${ie.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),r.end(),!0)}i(pt,"answerPreflight");function J(e,r=!1){C(e),r&&O(e),e.writeHead(401,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{...T,origin:"runtime"}}))}i(J,"writeUnauthorized");function ft(e){C(e),O(e),e.writeHead(401,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{...H,origin:"runtime"}}))}i(ft,"writePersonBearerRefused");const mt={"/v1/runtime/vendor-status":{method:"GET",purpose:"vendor_status"},"/v1/runtime/vendor-account-remove":{method:"POST",purpose:"vendor_account_remove"}};async function gt(e,r){if(!P())return!1;const s=new URL(e.url??"/","http://runtime.local").pathname,o=mt[s];if(o===void 0||e.method!==o.method)return!1;const f=i((p,R)=>{C(r),O(r),r.writeHead(p,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify(R))},"answer");try{const p=se();if(p===null)throw new E(401,H.code,H.message);const R=e.headers.authorization,m=R?.startsWith("Bearer ")?await p.verifyPurpose(R.slice(7),o.purpose):null;if(m===null)throw new E(401,"unauthorized","invalid directory token");const U=o.purpose==="vendor_status"?void 0:await ht(e);f(200,await B(m,async()=>o.purpose==="vendor_status"?je():await $e(U)))}catch(p){const{status:R,body:m}=Me(p);f(R,m)}return!0}i(gt,"serveCloudVendorRoute");async function ht(e){const r=[];let s=0;for await(const o of e){if(s+=o.length,s>Ve)throw new E(400,"invalid_request","request body too large");r.push(o)}if(s!==0)try{return JSON.parse(Buffer.concat(r).toString("utf8"))}catch{throw new E(400,"invalid_request","invalid JSON body")}}i(ht,"readVendorBody");function Se(e){C(e),e.writeHead(503,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}))}i(Se,"writeRuntimeStarting");function Rt(e,r){e.writeHead(503,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{code:"startup_blocked",message:r,origin:"runtime"}}))}i(Rt,"writeStartupBlocked");function Ee(e,r,s){return new Promise(o=>{if(s===void 0){try{e.closeAllConnections()}catch{}e.close(()=>o());return}const f=[];e.close(()=>{for(const m of f)clearTimeout(m);o()});for(const m of r)m.destroy();const p=setInterval(()=>e.closeIdleConnections(),250),R=setTimeout(()=>e.closeAllConnections(),s);f.push(p,R),e.closeIdleConnections()})}i(Ee,"closeServer");function qn(e={}){let r=null;const s=tt(()=>r),o=new le().registerAll(de).registerAll(fe).registerAll(pe).registerAll(me),f=i((t,n)=>{const c=rr()?.startupBlock()??null;return c===null||t==="GET"&&(n==="/healthz"||n==="/v1/status"||n==="/v1/ready")||t==="POST"&&(n==="/v1/daemon/migrate"||n==="/v1/daemon/admit")||c.phase==="recovering"&&o.match(t,n)!==null?null:c},"startupBlockFor"),p=e.socketPath??He(),R=new Set([process.getuid?.()??0,...ae("user").runtime?.person_uids??[]]),m=i((t,n,c)=>{C(n);const u=i(a=>Array.isArray(a)?a[0]:a,"first"),b=u(t.headers[ne.toLowerCase()]),g=ze(b,V())??Ne(u(t.headers[ie.toLowerCase()]),oe,{legacyMinimum:b,runtimeVersion:V()});if(g!==null){n.writeHead(g.status,{"content-type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:g.code,message:g.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in g?{param:g.param}:{details:g.details}}}));return}const w=i(a=>{const l=I(t);A({event:"api.request.failed",level:"error",...l?.class==="broker"?{node_id:l.node}:{},error:a instanceof Error?a:new Error(String(a))});try{n.headersSent||n.writeHead(500,{"content-type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:"internal",message:"internal error",origin:"runtime"}}))}catch{}},"internalFailure");let S;try{S=new URL(t.url??"/","http://127.0.0.1")}catch{try{n.writeHead(400,{"content-type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid",origin:"runtime"}}))}catch{}return}try{const a=f((t.method??"GET").toUpperCase(),S.pathname);if(a!==null){Rt(n,a.message);return}const l=I(t)??{class:"person"},d=Ae(l),h=i(()=>s.handle(t,n,c,l),"handled");(d===void 0?h():B(d,i(async()=>{W()||await F(d),await h()},"handledAsPerson"))).catch(w)}catch(a){w(a)}},"onRequest"),U=i(async(t,n,c)=>{const u=I(t);return u===void 0||ce(u)||await ue(u,"either",c)?!0:(y(n,404,"Not Found","node_not_found",`no node ${c}`),!1)},"authorizeAttachUpgrade"),v=new Set,Z=i((t,n,c)=>{v.add(n),n.once("close",()=>v.delete(n)),n.on("error",()=>{});try{const u=new URL(t.url??"/","http://127.0.0.1"),b=f((t.method??"GET").toUpperCase(),u.pathname);if(b!==null){y(n,503,"Service Unavailable","startup_blocked",b.message);return}const g=nt(t.method??"GET",u.pathname);if(g===null){n.destroy();return}const w=(()=>{const a=I(t);return a===void 0?void 0:Ae(a)})(),S=i(()=>U(t,n,g).then(a=>a?er(t,n,c,g,async l=>{const d=I(t);return d===void 0||ce(d)||await ue(d,l,g)}):void 0),"attach");(w===void 0?S():B(w,async()=>{W()||await F(w),await S()})).catch(()=>{try{n.destroy()}catch{}})}catch{try{n.destroy()}catch{}}},"onUpgrade"),be=i(t=>{t.on("error",n=>{A({event:"api.server.failed",level:"error",error:n})})},"bindErrorHandler"),Te=i(async(t,n)=>{try{const c=await he(t,R);if(c==="unauthorized"){A({event:"api.principal.denied",level:"warn",fields:{method:t.method}}),J(n);return}if(c==="runtime_starting"){Se(n);return}z.set(t,c),ye(t,c),m(t,n,c.class==="app"?c.scopes:null)}catch(c){A({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),J(n)}},"onSocketRequest"),N=ee((t,n)=>{Te(t,n).catch(c=>A({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}))}),Ce=i(async(t,n,c)=>{try{const u=await he(t,R);if(u==="unauthorized"||u==="runtime_starting"){u==="unauthorized"&&A({event:"api.principal.denied",level:"warn",fields:{method:t.method}}),y(n,u==="unauthorized"?401:503,"Unauthorized",u,"socket principal unavailable");return}if(u.class!=="person"&&u.class!=="broker"){y(n,403,"Forbidden",k.code,k.message);return}z.set(t,u),Z(t,n,c)}catch(u){A({event:"api.principal.failed",level:"error",error:u instanceof Error?u:new Error(String(u))}),y(n,401,"Unauthorized",T.code,T.message)}},"onSocketUpgrade");N.on("upgrade",(t,n,c)=>{Ce(t,n,c).catch(u=>A({event:"api.principal.failed",level:"error",error:u instanceof Error?u:new Error(String(u))}))}),ge((t,n,c)=>{z.set(t,c),m(t,n,null)});let K=!1,X,Q;const Oe=new Promise((t,n)=>{X=t,Q=n});N.once("listening",()=>{K=!0,X()}),N.on("error",t=>{A({event:"api.server.failed",level:"error",error:t}),K||Q(t)});try{$(p)&&te(p)}catch{}N.listen(p,()=>{try{ke(p,process.platform==="linux"&&$("/run/crtr/launcher.sock")?438:384)}catch(t){A({event:"api.socket.chmod_failed",level:"error",error:t instanceof Error?t:new Error(String(t))})}});let _;const L=e.tcp??Qe()??ae("user").api.tcp;if(L!==void 0&&L!==""){const t=ot(L);if(t===null)A({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${L}`)});else{P()&&x();const n=e.token??qe()??Ke("user"),c=st(n),u=i(async(a,l)=>{if(pt(a,l))return;if(P()&&Je(new URL(a.url??"/","http://runtime.local").pathname)){await ut(a,l);return}if(await gt(a,l))return;const d=await we(a,c);if(d==="runtime_starting"){O(l),Se(l);return}if(d==="person_bearer"){ft(l);return}if(d==="unauthorized"){A({event:"api.principal.denied",level:"warn",fields:{method:a.method,listener:"tcp"}}),J(l,!0);return}if("call"in d){O(l);const h=d.call.sub;await B(h,async()=>{W()||await F(h),await ct()(a,l,d.call)});return}z.set(a,d.principal),ye(a,d.principal),O(l),m(a,l,d.ceiling)},"tcpOnRequest"),b=i(async(a,l,d)=>{const h=await we(a,c);if(h==="runtime_starting"){y(l,503,"Service Unavailable","runtime_starting","grant sync is not ready");return}if(h==="person_bearer"){y(l,401,"Unauthorized",H.code,H.message);return}if(h==="unauthorized"){y(l,401,"Unauthorized",T.code,T.message);return}if("call"in h){y(l,403,"Forbidden",k.code,k.message);return}if(h.ceiling!==null||h.principal.class==="anonymous"){y(l,403,"Forbidden",k.code,k.message);return}z.set(a,h.principal),Z(a,l,d)},"tcpOnUpgrade"),g=i(a=>{A({event:"api.principal.failed",level:"error",error:a instanceof Error?a:new Error(String(a))})},"failed"),w=i((a,l)=>{u(a,l).catch(d=>{g(d),l.headersSent?l.destroy():J(l,!0)})},"listener"),S=dt();_=S===null?ee(w):Pe(S,w),_.on("upgrade",(a,l,d)=>{l.on("error",()=>{}),b(a,l,d).catch(h=>{g(h),y(l,401,"Unauthorized",T.code,T.message)})}),be(_),_.once("listening",()=>{const a=_?.address();if(a!==null&&typeof a=="object"){const{address:l,port:d}=a;r=it(l,d)}}),_.listen(t.port,t.host)}}let q=!1;return{ready:Oe,tcpAddress:i(()=>r,"tcpAddress"),close:i(async(t={})=>{if(!q){q=!0,ge(null),lr.close(),await Promise.all([Ee(N,v,t.graceMs),_!==void 0?Ee(_,v,t.graceMs):Promise.resolve()]);try{$(p)&&te(p)}catch{}}},"close")}}i(qn,"createApiServer");export{tt as buildRouter,Ee as closeServer,qn as createApiServer,I as socketPrincipal};
|
|
1
|
+
var Pe=Object.defineProperty;var o=(e,r)=>Pe(e,"name",{value:r,configurable:!0});import{createServer as te}from"node:http";import{createServer as Ne}from"node:https";import{chmodSync as ze,existsSync as V,readFileSync as ne,unlinkSync as oe}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as ie,RUNTIME_VERSION_HEADER as W,minimumRuntimeRefusal as He}from"../../api/runtime-version.js";import{CONTRACT_HEADER as F,CONTRACT_LEVEL as se,REQUIRED_CONTRACT_HEADER as ae,contractRefusal as Ie}from"../../api/contract.js";import{crtrVersion as G}from"../../shared/crtr-version.js";import{apiSocketPath as Le}from"../../core/canvas/paths.js";import{resolveNodeToken as Be}from"../../core/canvas/node-tokens.js";import{isCloudRole as P,runAsPerson as x}from"../../core/canvas/person.js";import{personBearerVerifier as le}from"./auth/person-bearer.js";import{personHasSnapshot as Y}from"../../core/scoped-state/person-store.js";import{loadPersonSettings as Z}from"../../core/scoped-state/person-rows.js";import{AppPrincipalResolver as De}from"./principal.js";import{createAppRequestHandler as xe}from"./app-listener.js";import{decodeJwt as $e}from"jose";import{handleVendorSignIn as Je,isVendorSignInPath as je}from"./vendor-signin.js";import{RunError as _}from"../../core/runs/operations.js";import{removeVendorAccount as Me,vendorStatus as Ve}from"./handlers/vendor-status.js";import{toErrorBody as We}from"./map.js";import{CONTROL_BODY_MAX_BYTES as Fe}from"../../core/llm/body-limits.js";import{grantFor as Ge,hasSyncedGrants as Ye}from"../../core/grants/mirror.js";import{readConfig as ce}from"../../core/config.js";import{directoryIssuer as Ze}from"../../core/directory/issuer.js";import{peerUid as Ke}from"../../native/linux.js";import{findScopedApiToken as Xe,getApiToken as Qe,listScopedApiTokens as qe}from"../../core/secrets.js";import{emitEvent as A}from"../../core/events/emit.js";import{envCrtrdTcp as er,envCrtrdToken as rr}from"../../shared/env.js";import{Router as ue,actsAsPerson as de}from"./router.js";import{handleAttachUpgrade as tr,refuseUpgrade as y}from"./bridge.js";import{boundDaemonControl as nr}from"../control.js";import{attachRoutes as or,mayAttachNode as pe}from"./handlers/attach.js";import{peerRoutes as ir}from"../peer/handlers.js";import{bashJobRoutes as sr}from"./handlers/bash-jobs.js";import{bashRoutes as ar}from"./handlers/bash.js";import{hookExecRoutes as lr}from"./handlers/hook-exec.js";import{brokerOperationRoutes as fe}from"./handlers/broker-ops.js";import{brokerSignalRoutes as cr,brokerSignalStreams as ur}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as me,nodeFaultRoutes as dr}from"./handlers/broker-recovery.js";import{canvasRoutes as pr}from"./handlers/canvas.js";import{conversationRoutes as fr}from"./handlers/conversations.js";import{chatInventoryRoutes as mr}from"./handlers/chat-inventory.js";import{daemonRoutes as gr}from"./handlers/daemon.js";import{fileRoutes as hr}from"./handlers/files.js";import{focusRoutes as Rr}from"./handlers/focus.js";import{analyticsRoutes as Ar}from"./handlers/analytics.js";import{memoryReadsRoutes as yr}from"./handlers/memory-reads.js";import{memoryRoutes as vr}from"./handlers/memory.js";import{healthRoutes as wr}from"./handlers/health.js";import{humanRequestRoutes as _r}from"./handlers/human-requests.js";import{inboxRoutes as Sr}from"./handlers/inbox.js";import{feedbackCommentRoutes as Er}from"./handlers/feedback-comments.js";import{objectRoutes as br}from"./handlers/objects.js";import{shareRoutes as Tr}from"./handlers/shares.js";import{customObjectRoutes as Cr}from"./handlers/custom-objects.js";import{docRoutes as kr}from"./handlers/docs.js";import{deliveryRoutes as ge}from"./handlers/delivery.js";import{deliveryRetryRoutes as Ur}from"./handlers/delivery-retry.js";import{packageDocRoutes as Or}from"./handlers/package-docs.js";import{documentAccessRoutes as Pr}from"./handlers/document-access.js";import{pluginAppRoutes as Nr}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as he,messageRoutes as zr}from"./handlers/messages.js";import{modelAuthRoutes as Hr}from"./handlers/modelauth.js";import{llmRoutes as Ir}from"./handlers/llm.js";import{providerRoutes as Lr}from"./handlers/providers.js";import{modelConfigRoutes as Br}from"./handlers/model-config.js";import{settingsRoutes as Dr}from"./handlers/settings.js";import{nodeRoutes as xr}from"./handlers/nodes.js";import{nodeRecordRoutes as $r}from"./handlers/node-records.js";import{nodeOutcomeRoutes as Jr}from"./handlers/node-outcomes.js";import{nodeEventRoutes as jr}from"./handlers/node-events.js";import{profileRoutes as Mr}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as Vr}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as Wr}from"./handlers/reports.js";import{runRoutes as Fr}from"./handlers/run-routes.js";import{reviewCommentRoutes as Gr}from"./handlers/review-comments.js";import{reviewRoutes as Yr}from"./handlers/reviews.js";import{subscriptionRoutes as Zr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as Kr}from"./handlers/structured-requests.js";import{cronRoutes as Xr}from"./handlers/crons.js";import{setCronRequestHandler as Re}from"../cron/run-socket.js";import{worktreeRoutes as Qr}from"./handlers/worktree.js";import{limitsRoutes as qr}from"./handlers/limits.js";import{chargeRoutes as et,spendLimitRoutes as rt}from"./handlers/charges.js";import{executionStartRoutes as tt}from"./handlers/execution-start.js";import{gitCredentialRoutes as nt}from"./handlers/git-credential.js";function ot(e){return new ue().registerAll(wr(e)).registerAll(gr).registerAll(Tr).registerAll(xr).registerAll($r).registerAll(Jr).registerAll(Ur).registerAll(jr).registerAll(sr).registerAll(ar).registerAll(lr).registerAll(fe).registerAll(cr).registerAll(ge).registerAll(me).registerAll(dr).registerAll(Qr).registerAll(qr).registerAll(et).registerAll(tt).registerAll(nt).registerAll(rt).registerAll(he).registerAll(zr).registerAll(Wr).registerAll(Fr).registerAll(Kr).registerAll(or).registerAll(pr).registerAll(fr).registerAll(Ar).registerAll(yr).registerAll(vr).registerAll(hr).registerAll(br).registerAll(Cr).registerAll(kr).registerAll(Or).registerAll(Pr).registerAll(Nr).registerAll(Rr).registerAll(Zr).registerAll(Xr).registerAll(Mr).registerAll(Hr).registerAll(Ir).registerAll(Lr).registerAll(Br).registerAll(Dr).registerAll(Yr).registerAll(Gr).registerAll(Sr).registerAll(_r).registerAll(mr).registerAll(Vr).registerAll(Er).registerAll(ir)}o(ot,"buildRouter");function it(e,r){if(e.toUpperCase()!=="GET")return null;const i=r.split("/").filter(d=>d.length>0);if(i.length!==4||i[0]!=="v1"||i[1]!=="nodes"||i[3]!=="attach")return null;const s=i[2];return s===void 0||s===""?null:decodeURIComponent(s)}o(it,"attachNodeId");function st(e){const r=e.trim();if(r==="")return null;const i=r.lastIndexOf(":");if(i<0)return null;const s=r.slice(0,i),d=r.slice(i+1),p=Number(d);return!Number.isInteger(p)||p<0||p>65535?null:{host:s===""?"0.0.0.0":s,port:p}}o(st,"parseTcp");function at(e,r){return`${e.includes(":")?`[${e}]`:e}:${r}`}o(at,"formatTcpAddress");const C={code:"unauthorized",message:"missing or invalid bearer token"},N={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},L={code:"person_bearer_not_supported",message:"this listener accepts a person bearer only on a cloud role with CRTR_DIRECTORY_URL and CRTR_PUBLIC_API_URL set; call with a node, app or public token"},K={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},z=new WeakMap;function B(e){return z.get(e)}o(B,"socketPrincipal");async function Ae(e,r){const i=process.platform==="linux"?Ke(e.socket):null,s=e.headers.authorization;if(s===void 0)return i===null||r.has(i)?{class:"person"}:"unauthorized";if(typeof s!="string"||!s.startsWith("Bearer "))return"unauthorized";if(s.slice(7).startsWith("crtr_pub_"))return K;if(s.slice(7).startsWith(X)){const d=_e(s.slice(7));return d!==void 0&&(i===null||r.has(i))?d.principal:"unauthorized"}return ye(s.slice(7),i)}o(Ae,"resolveSocketPrincipal");async function ye(e,r){const i=await Be(e);if(!i||r!==null&&r!==i.uid)return"unauthorized";const s=Ze();if(s&&!P()&&!await Ye(s))return"runtime_starting";const d=i.grant??(await Ge("app:terminal",i.sub))?.id??null;return{class:"broker",...i,grant:d}}o(ye,"brokerPrincipal");function ve(e){if(e.class!=="anonymous")return e.sub!==void 0&&e.sub!==""?e.sub:void 0}o(ve,"requestPerson");function we(e,r){r.class==="broker"&&A({event:"api.request.principal",level:r.app==="app:terminal"?"debug":"info",node_id:r.node,fields:{principal:`${r.app} node:${r.node}`,method:e.method,path:e.url}})}o(we,"noteBrokerRequest");const X="crtr_app_";function _e(e){const r=e.startsWith(X)?Xe(e):void 0;return r===void 0?void 0:{principal:{class:"app",app:r.grantee,scopes:r.scopes},ceiling:r.scopes}}o(_e,"appBearer");function lt(e){const r=new Map;for(const i of qe("user"))r.set(i.token,{principal:{class:"app",app:i.grantee,scopes:i.scopes},ceiling:i.scopes});return e!==void 0&&r.set(e,{principal:{class:"person"},ceiling:null}),r}o(lt,"resolveBearers");function ct(e){try{return $e(e).act!==void 0}catch{return!1}}o(ct,"carriesAct");const ut=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/;function H(e,r){return e!==void 0&&(e.reason=r),"unauthorized"}o(H,"deny");async function Se(e,r,i){const s=e.headers.authorization;if(s===void 0&&(e.method??"GET").toUpperCase()==="GET"&&(e.url??"").split("?")[0]==="/healthz")return{principal:K,ceiling:null};if(typeof s!="string"||!s.startsWith("Bearer "))return H(i,s===void 0?"no_authorization_header":"not_a_bearer");const d=s.slice(7);if(d.startsWith("crtr_pub_"))return{principal:K,ceiling:null};if(d.startsWith(X))return _e(d)??H(i,"app_token_unknown");const p=r.get(d);if(p!==void 0)return p;if(ut.test(d)){if(P()&&ct(d)){const b=J();if(b===null)return"person_bearer";try{const v=await b.verifyCall(s);return v.chain[0]?.sub.startsWith("app:")?{call:v}:H(i,"call_token_presenter_not_an_app")}catch(v){return v instanceof _&&v.status===503?"runtime_starting":H(i,`call_token_${v instanceof _?v.code:"invalid"}`)}}const h=P()?le():null;if(h===null)return"person_bearer";const O=await h.verify(d);return O===null?H(i,"person_bearer_not_verified"):{principal:{class:"person",sub:O},ceiling:null}}const g=await ye(d,null);return g==="unauthorized"?H(i,"node_token_unknown"):typeof g=="string"?g:{principal:g,ceiling:null}}o(Se,"authorizeTcp");let $;function J(){if($!==void 0)return $;const e=process.env.CRTR_DIRECTORY_URL||void 0,r=process.env.CRTR_PUBLIC_API_URL||void 0;return $=e===void 0||r===void 0?null:new De(e,r,async()=>{}),$}o(J,"cloudCallResolver");let Ee;function dt(){const e=J();if(e===null)throw new _(503,"runtime_starting","app calls are not configured on this listener");return Ee??=xe(e,async()=>!0,async()=>{}),Ee}o(dt,"cloudAppCalls");async function pt(e,r){k(r),U(r);const i=J();try{if(i===null)throw new _(503,"runtime_starting","vendor sign-in is not configured on this listener");await Je(e,r,new URL(e.url??"/","http://runtime.local"),i)}catch(s){if(!(s instanceof _))throw s;if(r.headersSent){r.destroy();return}r.writeHead(s.status,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),r.end(JSON.stringify({error:{code:s.code,message:s.message,...s.param?{param:s.param}:{},origin:"runtime"}}))}}o(pt,"serveVendorSignIn");function ft(){const e=process.env.CRTRD_TLS_CERT||void 0,r=process.env.CRTRD_TLS_KEY||void 0;if(e===void 0&&r===void 0)return null;if(e===void 0||r===void 0)throw new Error("CRTRD_TLS_CERT and CRTRD_TLS_KEY must be set together");return{cert:ne(e),key:ne(r)}}o(ft,"tcpTls");function k(e){e.setHeader(W,G()),e.setHeader(F,se)}o(k,"advertiseRuntime");function U(e){e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Expose-Headers",`${W}, ${F}`)}o(U,"exposeRuntimeHeaders");function mt(e,r){return(e.method??"GET").toUpperCase()!=="OPTIONS"?!1:(k(r),r.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${W}, ${F}`,"Access-Control-Allow-Headers":`authorization, content-type, ${ie.toLowerCase()}, ${ae.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),r.end(),!0)}o(mt,"answerPreflight");function j(e,r=!1){k(e),r&&U(e),e.writeHead(401,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{...C,origin:"runtime"}}))}o(j,"writeUnauthorized");function gt(e){k(e),U(e),e.writeHead(401,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{...L,origin:"runtime"}}))}o(gt,"writePersonBearerRefused");const ht={"/v1/runtime/vendor-status":{method:"GET",purpose:"vendor_status"},"/v1/runtime/vendor-account-remove":{method:"POST",purpose:"vendor_account_remove"}};async function Rt(e,r){if(!P())return!1;const i=new URL(e.url??"/","http://runtime.local").pathname,s=ht[i];if(s===void 0||e.method!==s.method)return!1;const d=o((p,g)=>{k(r),U(r),r.writeHead(p,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify(g))},"answer");try{const p=le();if(p===null)throw new _(401,L.code,L.message);const g=e.headers.authorization,h=g?.startsWith("Bearer ")?await p.verifyPurpose(g.slice(7),s.purpose):null;if(h===null)throw new _(401,"unauthorized","invalid directory token");const O=s.purpose==="vendor_status"?void 0:await At(e);d(200,await x(h,async()=>s.purpose==="vendor_status"?Ve():await Me(O)))}catch(p){const{status:g,body:h}=We(p);d(g,h)}return!0}o(Rt,"serveCloudVendorRoute");async function At(e){const r=[];let i=0;for await(const s of e){if(i+=s.length,i>Fe)throw new _(400,"invalid_request","request body too large");r.push(s)}if(i!==0)try{return JSON.parse(Buffer.concat(r).toString("utf8"))}catch{throw new _(400,"invalid_request","invalid JSON body")}}o(At,"readVendorBody");function be(e){k(e),e.writeHead(503,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}))}o(be,"writeRuntimeStarting");function yt(e,r){e.writeHead(503,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{code:"startup_blocked",message:r,origin:"runtime"}}))}o(yt,"writeStartupBlocked");function Te(e,r,i){return new Promise(s=>{if(i===void 0){try{e.closeAllConnections()}catch{}e.close(()=>s());return}const d=[];e.close(()=>{for(const h of d)clearTimeout(h);s()});for(const h of r)h.destroy();const p=setInterval(()=>e.closeIdleConnections(),250),g=setTimeout(()=>e.closeAllConnections(),i);d.push(p,g),e.closeIdleConnections()})}o(Te,"closeServer");function eo(e={}){let r=null;const i=ot(()=>r),s=new ue().registerAll(fe).registerAll(ge).registerAll(me).registerAll(he),d=o((t,n)=>{const c=nr()?.startupBlock()??null;return c===null||t==="GET"&&(n==="/healthz"||n==="/v1/status"||n==="/v1/ready")||t==="POST"&&(n==="/v1/daemon/migrate"||n==="/v1/daemon/admit")||c.phase==="recovering"&&s.match(t,n)!==null?null:c},"startupBlockFor"),p=e.socketPath??Le(),g=new Set([process.getuid?.()??0,...ce("user").runtime?.person_uids??[]]),h=o((t,n,c)=>{k(n);const u=o(a=>Array.isArray(a)?a[0]:a,"first"),T=u(t.headers[ie.toLowerCase()]),R=He(T,G())??Ie(u(t.headers[ae.toLowerCase()]),se,{legacyMinimum:T,runtimeVersion:G()});if(R!==null){n.writeHead(R.status,{"content-type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:R.code,message:R.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in R?{param:R.param}:{details:R.details}}}));return}const w=o(a=>{const l=B(t);A({event:"api.request.failed",level:"error",...l?.class==="broker"?{node_id:l.node}:{},error:a instanceof Error?a:new Error(String(a))});try{n.headersSent||n.writeHead(500,{"content-type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:"internal",message:"internal error",origin:"runtime"}}))}catch{}},"internalFailure");let E;try{E=new URL(t.url??"/","http://127.0.0.1")}catch{try{n.writeHead(400,{"content-type":"application/json; charset=utf-8"}),n.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid",origin:"runtime"}}))}catch{}return}try{const a=d((t.method??"GET").toUpperCase(),E.pathname);if(a!==null){yt(n,a.message);return}const l=B(t)??{class:"person"},m=ve(l),f=o(()=>i.handle(t,n,c,l),"handled");(m===void 0?f():x(m,o(async()=>{Y()||await Z(m),await f()},"handledAsPerson"))).catch(w)}catch(a){w(a)}},"onRequest"),O=o(async(t,n,c)=>{const u=B(t);return u===void 0||de(u)||await pe(u,"either",c)?!0:(y(n,404,"Not Found","node_not_found",`no node ${c}`),!1)},"authorizeAttachUpgrade"),b=new Set,v=o((t,n,c)=>{b.add(n),n.once("close",()=>b.delete(n)),n.on("error",()=>{});try{const u=new URL(t.url??"/","http://127.0.0.1"),T=d((t.method??"GET").toUpperCase(),u.pathname);if(T!==null){y(n,503,"Service Unavailable","startup_blocked",T.message);return}const R=it(t.method??"GET",u.pathname);if(R===null){n.destroy();return}const w=(()=>{const a=B(t);return a===void 0?void 0:ve(a)})(),E=o(()=>O(t,n,R).then(a=>a?tr(t,n,c,R,async l=>{const m=B(t);return m===void 0||de(m)||await pe(m,l,R)}):void 0),"attach");(w===void 0?E():x(w,async()=>{Y()||await Z(w),await E()})).catch(()=>{try{n.destroy()}catch{}})}catch{try{n.destroy()}catch{}}},"onUpgrade"),Ce=o(t=>{t.on("error",n=>{A({event:"api.server.failed",level:"error",error:n})})},"bindErrorHandler"),ke=o(async(t,n)=>{try{const c=await Ae(t,g);if(c==="unauthorized"){A({event:"api.principal.denied",level:"warn",fields:{method:t.method}}),j(n);return}if(c==="runtime_starting"){be(n);return}z.set(t,c),we(t,c),h(t,n,c.class==="app"?c.scopes:null)}catch(c){A({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),j(n)}},"onSocketRequest"),I=te((t,n)=>{ke(t,n).catch(c=>A({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}))}),Ue=o(async(t,n,c)=>{try{const u=await Ae(t,g);if(u==="unauthorized"||u==="runtime_starting"){u==="unauthorized"&&A({event:"api.principal.denied",level:"warn",fields:{method:t.method}}),y(n,u==="unauthorized"?401:503,"Unauthorized",u,"socket principal unavailable");return}if(u.class!=="person"&&u.class!=="broker"){y(n,403,"Forbidden",N.code,N.message);return}z.set(t,u),v(t,n,c)}catch(u){A({event:"api.principal.failed",level:"error",error:u instanceof Error?u:new Error(String(u))}),y(n,401,"Unauthorized",C.code,C.message)}},"onSocketUpgrade");I.on("upgrade",(t,n,c)=>{Ue(t,n,c).catch(u=>A({event:"api.principal.failed",level:"error",error:u instanceof Error?u:new Error(String(u))}))}),Re((t,n,c)=>{z.set(t,c),h(t,n,null)});let Q=!1,q,ee;const Oe=new Promise((t,n)=>{q=t,ee=n});I.once("listening",()=>{Q=!0,q()}),I.on("error",t=>{A({event:"api.server.failed",level:"error",error:t}),Q||ee(t)});try{V(p)&&oe(p)}catch{}I.listen(p,()=>{try{ze(p,process.platform==="linux"&&V("/run/crtr/launcher.sock")?438:384)}catch(t){A({event:"api.socket.chmod_failed",level:"error",error:t instanceof Error?t:new Error(String(t))})}});let S;const D=e.tcp??er()??ce("user").api.tcp;if(D!==void 0&&D!==""){const t=st(D);if(t===null)A({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${D}`)});else{P()&&J();const n=e.token??rr()??Qe("user"),c=lt(n),u=o(async(a,l)=>{if(mt(a,l))return;if(P()&&je(new URL(a.url??"/","http://runtime.local").pathname)){await pt(a,l);return}if(await Rt(a,l))return;const m={},f=await Se(a,c,m);if(f==="runtime_starting"){U(l),be(l);return}if(f==="person_bearer"){gt(l);return}if(f==="unauthorized"){A({event:"api.principal.denied",level:"warn",fields:{method:a.method,listener:"tcp",path:new URL(a.url??"/","http://runtime.local").pathname,reason:m.reason??"unknown"}}),j(l,!0);return}if("call"in f){U(l);const M=f.call.sub;await x(M,async()=>{Y()||await Z(M),await dt()(a,l,f.call)});return}z.set(a,f.principal),we(a,f.principal),U(l),h(a,l,f.ceiling)},"tcpOnRequest"),T=o(async(a,l,m)=>{const f=await Se(a,c);if(f==="runtime_starting"){y(l,503,"Service Unavailable","runtime_starting","grant sync is not ready");return}if(f==="person_bearer"){y(l,401,"Unauthorized",L.code,L.message);return}if(f==="unauthorized"){y(l,401,"Unauthorized",C.code,C.message);return}if("call"in f){y(l,403,"Forbidden",N.code,N.message);return}if(f.ceiling!==null||f.principal.class==="anonymous"){y(l,403,"Forbidden",N.code,N.message);return}z.set(a,f.principal),v(a,l,m)},"tcpOnUpgrade"),R=o(a=>{A({event:"api.principal.failed",level:"error",error:a instanceof Error?a:new Error(String(a))})},"failed"),w=o((a,l)=>{u(a,l).catch(m=>{R(m),l.headersSent?l.destroy():j(l,!0)})},"listener"),E=ft();S=E===null?te(w):Ne(E,w),S.on("upgrade",(a,l,m)=>{l.on("error",()=>{}),T(a,l,m).catch(f=>{R(f),y(l,401,"Unauthorized",C.code,C.message)})}),Ce(S),S.once("listening",()=>{const a=S?.address();if(a!==null&&typeof a=="object"){const{address:l,port:m}=a;r=at(l,m)}}),S.listen(t.port,t.host)}}let re=!1;return{ready:Oe,tcpAddress:o(()=>r,"tcpAddress"),close:o(async(t={})=>{if(!re){re=!0,Re(null),ur.close(),await Promise.all([Te(I,b,t.graceMs),S!==void 0?Te(S,b,t.graceMs):Promise.resolve()]);try{V(p)&&oe(p)}catch{}}},"close")}}o(eo,"createApiServer");export{ot as buildRouter,Te as closeServer,eo as createApiServer,B as socketPrincipal};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.570",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
},
|
|
145
145
|
"license": "UNLICENSED",
|
|
146
146
|
"dependencies": {
|
|
147
|
-
"@north-light/identity": "0.3.
|
|
147
|
+
"@north-light/identity": "0.3.570",
|
|
148
148
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
149
149
|
"@earendil-works/pi-ai": "1.1.0",
|
|
150
150
|
"@earendil-works/pi-coding-agent": "1.1.0",
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.570",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/cli",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.570",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"workspaces": [
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@milkdown/preset-gfm": "^7.22.3",
|
|
25
25
|
"@milkdown/prose": "^7.22.3",
|
|
26
26
|
"@milkdown/utils": "^7.22.3",
|
|
27
|
-
"@north-light/identity": "0.3.
|
|
27
|
+
"@north-light/identity": "0.3.570",
|
|
28
28
|
"cron-parser": "^5.6.0",
|
|
29
29
|
"esbuild": "^0.27.7",
|
|
30
30
|
"jose": "^6.2.12",
|
|
@@ -12455,17 +12455,17 @@
|
|
|
12455
12455
|
},
|
|
12456
12456
|
"packages/crouter-api": {
|
|
12457
12457
|
"name": "@north-light/api",
|
|
12458
|
-
"version": "0.3.
|
|
12458
|
+
"version": "0.3.570",
|
|
12459
12459
|
"license": "UNLICENSED"
|
|
12460
12460
|
},
|
|
12461
12461
|
"packages/crouter-env-docker": {
|
|
12462
12462
|
"name": "@north-light/env-docker",
|
|
12463
|
-
"version": "0.3.
|
|
12463
|
+
"version": "0.3.570",
|
|
12464
12464
|
"license": "UNLICENSED"
|
|
12465
12465
|
},
|
|
12466
12466
|
"packages/crouter-identity": {
|
|
12467
12467
|
"name": "@north-light/identity",
|
|
12468
|
-
"version": "0.3.
|
|
12468
|
+
"version": "0.3.570",
|
|
12469
12469
|
"license": "UNLICENSED",
|
|
12470
12470
|
"dependencies": {
|
|
12471
12471
|
"jose": "^6.2.1"
|
|
@@ -12473,21 +12473,21 @@
|
|
|
12473
12473
|
},
|
|
12474
12474
|
"packages/crouter-plugin": {
|
|
12475
12475
|
"name": "@north-light/plugin",
|
|
12476
|
-
"version": "0.3.
|
|
12476
|
+
"version": "0.3.570",
|
|
12477
12477
|
"license": "UNLICENSED",
|
|
12478
12478
|
"dependencies": {
|
|
12479
|
-
"@north-light/api": "0.3.
|
|
12480
|
-
"@north-light/identity": "0.3.
|
|
12479
|
+
"@north-light/api": "0.3.570",
|
|
12480
|
+
"@north-light/identity": "0.3.570"
|
|
12481
12481
|
}
|
|
12482
12482
|
},
|
|
12483
12483
|
"packages/crouter-sdk": {
|
|
12484
12484
|
"name": "@north-light/sdk",
|
|
12485
|
-
"version": "0.3.
|
|
12485
|
+
"version": "0.3.570",
|
|
12486
12486
|
"license": "UNLICENSED",
|
|
12487
12487
|
"dependencies": {
|
|
12488
|
-
"@north-light/api": "0.3.
|
|
12489
|
-
"@north-light/identity": "0.3.
|
|
12490
|
-
"@north-light/plugin": "0.3.
|
|
12488
|
+
"@north-light/api": "0.3.570",
|
|
12489
|
+
"@north-light/identity": "0.3.570",
|
|
12490
|
+
"@north-light/plugin": "0.3.570",
|
|
12491
12491
|
"jose": "^6.2.1"
|
|
12492
12492
|
},
|
|
12493
12493
|
"bin": {
|