@north-light/cli 0.3.506 → 0.3.508
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 +130 -130
- package/dist/clients/dashboard/app.js +2 -2
- package/dist/commands/surface-dashboard.js +2 -2
- package/dist/core/graph/names.d.ts +7 -0
- package/dist/core/graph/names.js +3 -3
- package/dist/daemon/api/bridge.js +3 -3
- package/dist/daemon/api/handlers/canvas.js +6 -6
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/peer/ingress.js +1 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
var le=Object.defineProperty;var a=(r,o)=>le(r,"name",{value:o,configurable:!0});import{createServer as D}from"node:http";import{chmodSync as ae,existsSync as N,unlinkSync as F}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as G,RUNTIME_VERSION_HEADER as z,minimumRuntimeRefusal as ue}from"../../api/runtime-version.js";import{CONTRACT_HEADER as P,CONTRACT_LEVEL as J,REQUIRED_CONTRACT_HEADER as V,contractRefusal as ce}from"../../api/contract.js";import{crtrVersion as I}from"../../shared/crtr-version.js";import{apiSocketPath as pe}from"../../core/canvas/paths.js";import{resolveNodeToken as de}from"../../core/canvas/node-tokens.js";import{grantFor as me,hasSyncedGrants as fe}from"../../core/grants/mirror.js";import{readConfig as x}from"../../core/config.js";import{peerUid as ge}from"../../native/linux.js";import{findScopedApiToken as he,getApiToken as Ae,listScopedApiTokens as Re}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as ye,envCrtrdToken as ve}from"../../shared/env.js";import{Router as K}from"./router.js";import{handleAttachUpgrade as be,refuseUpgrade as h}from"./bridge.js";import{boundDaemonControl as Ee}from"../control.js";import{attachRoutes as we}from"./handlers/attach.js";import{peerRoutes as Te}from"../peer/handlers.js";import{bashJobRoutes as _e}from"./handlers/bash-jobs.js";import{bashRoutes as Se}from"./handlers/bash.js";import{hookExecRoutes as Ce}from"./handlers/hook-exec.js";import{brokerOperationRoutes as Q}from"./handlers/broker-ops.js";import{brokerSignalRoutes as ke,brokerSignalStreams as Oe}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as X,nodeFaultRoutes as Ue}from"./handlers/broker-recovery.js";import{canvasRoutes as He}from"./handlers/canvas.js";import{chatInventoryRoutes as Ne}from"./handlers/chat-inventory.js";import{daemonRoutes as ze}from"./handlers/daemon.js";import{fileRoutes as Pe}from"./handlers/files.js";import{focusRoutes as Ie}from"./handlers/focus.js";import{analyticsRoutes as xe}from"./handlers/analytics.js";import{memoryReadsRoutes as Be}from"./handlers/memory-reads.js";import{memoryRoutes as We}from"./handlers/memory.js";import{healthRoutes as $e}from"./handlers/health.js";import{humanRequestRoutes as Le}from"./handlers/human-requests.js";import{inboxRoutes as Me}from"./handlers/inbox.js";import{feedbackCommentRoutes as je}from"./handlers/feedback-comments.js";import{objectRoutes as De}from"./handlers/objects.js";import{customObjectRoutes as Fe}from"./handlers/custom-objects.js";import{docRoutes as Ge}from"./handlers/docs.js";import{deliveryRoutes as Y}from"./handlers/delivery.js";import{deliveryRetryRoutes as Je}from"./handlers/delivery-retry.js";import{packageDocRoutes as Ve}from"./handlers/package-docs.js";import{pluginAppRoutes as Ke}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as Z,messageRoutes as Qe}from"./handlers/messages.js";import{modelAuthRoutes as Xe}from"./handlers/modelauth.js";import{llmRoutes as Ye}from"./handlers/llm.js";import{providerRoutes as Ze}from"./handlers/providers.js";import{modelConfigRoutes as qe}from"./handlers/model-config.js";import{nodeRoutes as er}from"./handlers/nodes.js";import{nodeRecordRoutes as rr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as tr}from"./handlers/node-outcomes.js";import{nodeEventRoutes as or}from"./handlers/node-events.js";import{profileRoutes as nr}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as ir}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as sr}from"./handlers/reports.js";import{runRoutes as lr}from"./handlers/run-routes.js";import{reviewCommentRoutes as ar}from"./handlers/review-comments.js";import{reviewRoutes as ur}from"./handlers/reviews.js";import{subscriptionRoutes as cr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as pr}from"./handlers/structured-requests.js";import{cronRoutes as dr}from"./handlers/crons.js";import{setCronRequestHandler as q}from"../cron/run-socket.js";import{worktreeRoutes as mr}from"./handlers/worktree.js";import{limitsRoutes as fr}from"./handlers/limits.js";function gr(r){return new K().registerAll($e(r)).registerAll(ze).registerAll(er).registerAll(rr).registerAll(tr).registerAll(Je).registerAll(or).registerAll(_e).registerAll(Se).registerAll(Ce).registerAll(Q).registerAll(ke).registerAll(Y).registerAll(X).registerAll(Ue).registerAll(mr).registerAll(fr).registerAll(Z).registerAll(Qe).registerAll(sr).registerAll(lr).registerAll(pr).registerAll(we).registerAll(He).registerAll(xe).registerAll(Be).registerAll(We).registerAll(Pe).registerAll(De).registerAll(Fe).registerAll(Ge).registerAll(Ve).registerAll(Ke).registerAll(Ie).registerAll(cr).registerAll(dr).registerAll(nr).registerAll(Xe).registerAll(Ye).registerAll(Ze).registerAll(qe).registerAll(ur).registerAll(ar).registerAll(Me).registerAll(Le).registerAll(Ne).registerAll(ir).registerAll(je).registerAll(Te)}a(gr,"buildRouter");function hr(r,o){if(r.toUpperCase()!=="GET")return null;const l=o.split("/").filter(f=>f.length>0);if(l.length!==4||l[0]!=="v1"||l[1]!=="nodes"||l[3]!=="attach")return null;const p=l[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(hr,"attachNodeId");function Ar(r){const o=r.trim();if(o==="")return null;const l=o.lastIndexOf(":");if(l<0)return null;const p=o.slice(0,l),f=o.slice(l+1),m=Number(f);return!Number.isInteger(m)||m<0||m>65535?null:{host:p===""?"0.0.0.0":p,port:m}}a(Ar,"parseTcp");function Rr(r,o){return`${r.includes(":")?`[${r}]`:r}:${o}`}a(Rr,"formatTcpAddress");const R={code:"unauthorized",message:"missing or invalid bearer token"},v={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},B={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},b=new WeakMap;function ee(r){return b.get(r)}a(ee,"socketPrincipal");function re(r,o){const l=process.platform==="linux"?ge(r.socket):null,p=r.headers.authorization;if(p===void 0)return l===null||o.has(l)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";if(p.slice(7).startsWith("crtr_pub_"))return B;if(p.slice(7).startsWith(W)){const A=O(p.slice(7));return A!==void 0&&(l===null||o.has(l))?A.principal:"unauthorized"}const f=de(p.slice(7));if(!f||l!==null&&l!==f.uid)return"unauthorized";const m=x("user").runtime?.issuer;if(m&&!fe(m.replace(/\/$/,"")))return"runtime_starting";const C=f.grant??me("app:terminal",f.sub)?.id??null;return{class:"broker",...f,grant:C}}a(re,"resolveSocketPrincipal");const W="crtr_app_";function O(r){const o=r.startsWith(W)?he(r):void 0;return o===void 0?void 0:{principal:{class:"app",app:o.grantee,scopes:o.scopes},ceiling:o.scopes}}a(O,"appBearer");function yr(r){const o=new Map;for(const l of Re("user"))o.set(l.token,{principal:{class:"app",app:l.grantee,scopes:l.scopes},ceiling:l.scopes});return o.set(r,{principal:{class:"person"},ceiling:null}),o}a(yr,"resolveBearers");function te(r,o){const l=r.headers.authorization;if(typeof l!="string"||!l.startsWith("Bearer "))return;const p=l.slice(7);return p.startsWith(W)?O(p):o.get(p)}a(te,"authorize");function U(r){r.setHeader(z,I()),r.setHeader(P,J)}a(U,"advertiseRuntime");function _(r){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Expose-Headers",`${z}, ${P}`)}a(_,"exposeRuntimeHeaders");function oe(r,o){return(r.method??"GET").toUpperCase()!=="OPTIONS"?!1:(U(o),o.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${z}, ${P}`,"Access-Control-Allow-Headers":`authorization, content-type, ${G.toLowerCase()}, ${V.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),o.end(),!0)}a(oe,"answerPreflight");function S(r,o=!1){U(r),o&&_(r),r.writeHead(401,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:R}))}a(S,"writeUnauthorized");function vr(r,o){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"startup_blocked",message:o}}))}a(vr,"writeStartupBlocked");function ne(r){return new Promise(o=>{try{r.closeAllConnections()}catch{}r.close(()=>o())})}a(ne,"closeServer");function zt(r={}){let o=null;const l=gr(()=>o),p=new K().registerAll(Q).registerAll(Y).registerAll(X).registerAll(Z),f=a((e,t)=>{const i=Ee()?.startupBlock()??null;return i===null||e==="GET"&&(t==="/healthz"||t==="/v1/status")||e==="POST"&&(t==="/v1/daemon/migrate"||t==="/v1/daemon/admit")||i.phase==="recovering"&&p.match(e,t)!==null?null:i},"startupBlockFor"),m=pe(),C=new Set([process.getuid?.()??0,...x("user").runtime?.person_uids??[]]),A=a((e,t,i)=>{U(t);const c=a(u=>Array.isArray(u)?u[0]:u,"first"),E=c(e.headers[G.toLowerCase()]),n=ue(E,I())??ce(c(e.headers[V.toLowerCase()]),J,{legacyMinimum:E,runtimeVersion:I()});if(n!==null){t.writeHead(n.status,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:n.code,message:n.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in n?{param:n.param}:{details:n.details}}}));return}const s=a(u=>{const w=ee(e);g({event:"api.request.failed",level:"error",...w?.class==="broker"?{node_id:w.node}:{},error:u instanceof Error?u:new Error(String(u))});try{t.headersSent||t.writeHead(500,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"internal",message:"internal error"}}))}catch{}},"internalFailure");let d;try{d=new URL(e.url??"/","http://127.0.0.1")}catch{try{t.writeHead(400,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid"}}))}catch{}return}try{const u=f((e.method??"GET").toUpperCase(),d.pathname);if(u!==null){vr(t,u.message);return}l.handle(e,t,i,ee(e)??{class:"person"}).catch(s)}catch(u){s(u)}},"onRequest"),H=a((e,t,i)=>{t.on("error",()=>{});try{const c=new URL(e.url??"/","http://127.0.0.1"),E=f((e.method??"GET").toUpperCase(),c.pathname);if(E!==null){h(t,503,"Service Unavailable","startup_blocked",E.message);return}const n=hr(e.method??"GET",c.pathname);if(n===null){t.destroy();return}be(e,t,i,n).catch(()=>{try{t.destroy()}catch{}})}catch{try{t.destroy()}catch{}}},"onUpgrade"),ie=a(e=>{e.on("error",t=>{g({event:"api.server.failed",level:"error",error:t})})},"bindErrorHandler"),T=D((e,t)=>{try{const i=re(e,C);if(i==="unauthorized"){g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),S(t);return}if(i==="runtime_starting"){U(t),t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}b.set(e,i),i.class==="broker"&&g({event:"api.request.principal",level:i.app==="app:terminal"?"debug":"info",node_id:i.node,fields:{principal:`${i.app} node:${i.node}`,method:e.method,path:e.url}}),A(e,t,i.class==="app"?i.scopes:null)}catch(i){g({event:"api.principal.failed",level:"error",error:i instanceof Error?i:new Error(String(i))}),S(t)}});T.on("upgrade",(e,t,i)=>{try{const c=re(e,C);if(c==="unauthorized"||c==="runtime_starting"){c==="unauthorized"&&g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),h(t,c==="unauthorized"?401:503,"Unauthorized",c,"socket principal unavailable");return}if(c.class!=="person"&&c.class!=="broker"){h(t,403,"Forbidden",v.code,v.message);return}b.set(e,c),H(e,t,i)}catch(c){g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),h(t,401,"Unauthorized",R.code,R.message)}}),q((e,t,i)=>{b.set(e,i),A(e,t,null)});let $=!1,L,M;const se=new Promise((e,t)=>{L=e,M=t});T.once("listening",()=>{$=!0,L()}),T.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),$||M(e)});try{N(m)&&F(m)}catch{}T.listen(m,()=>{try{ae(m,process.platform==="linux"&&N("/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 y;const k=r.tcp??ye()??x("user").api.tcp;if(k!==void 0&&k!==""){const e=Ar(k);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${k}`)});else{const t=r.token??ve()??Ae("user"),i=t===void 0?void 0:yr(t),c=i===void 0?(n,s)=>{if(oe(n,s))return;const d=n.headers.authorization;if(typeof d=="string"&&d.startsWith("Bearer crtr_pub_"))b.set(n,B),_(s);else if(n.headers.origin!==void 0){S(s,!0);return}else if(d!==void 0){const w=typeof d=="string"&&d.startsWith("Bearer ")?O(d.slice(7)):void 0;if(w===void 0){S(s,!0);return}b.set(n,w.principal),_(s),A(n,s,w.ceiling);return}A(n,s,null)}:(n,s)=>{if(oe(n,s))return;const d=te(n,i);if(d===void 0&&n.headers.authorization?.startsWith("Bearer crtr_pub_")){b.set(n,B),_(s),A(n,s,null);return}if(d===void 0){S(s,!0);return}b.set(n,d.principal),_(s),A(n,s,d.ceiling)},E=i===void 0?(n,s,d)=>{if(n.headers.origin!==void 0){h(s,401,"Unauthorized",R.code,R.message);return}const u=n.headers.authorization;if(u!==void 0){if(typeof u=="string"&&u.startsWith("Bearer crtr_pub_")){h(s,403,"Forbidden",v.code,v.message);return}(typeof u=="string"&&u.startsWith("Bearer ")?O(u.slice(7)):void 0)===void 0?h(s,401,"Unauthorized",R.code,R.message):h(s,403,"Forbidden",v.code,v.message);return}H(n,s,d)}:(n,s,d)=>{const u=te(n,i);if(u===void 0){h(s,401,"Unauthorized",R.code,R.message);return}if(u.ceiling!==null){h(s,403,"Forbidden",v.code,v.message);return}H(n,s,d)};y=D(c),y.on("upgrade",E),ie(y),y.once("listening",()=>{const n=y?.address();if(n!==null&&typeof n=="object"){const{address:s,port:d}=n;o=Rr(s,d)}}),y.listen(e.port,e.host)}}let j=!1;return{ready:se,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!j){j=!0,q(null),Oe.close(),await Promise.all([ne(T),y!==void 0?ne(y):Promise.resolve()]);try{N(m)&&F(m)}catch{}}},"close")}}a(zt,"createApiServer");export{gr as buildRouter,zt as createApiServer,ee as socketPrincipal};
|
|
1
|
+
var le=Object.defineProperty;var a=(r,o)=>le(r,"name",{value:o,configurable:!0});import{createServer as D}from"node:http";import{chmodSync as ae,existsSync as N,unlinkSync as F}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as G,RUNTIME_VERSION_HEADER as z,minimumRuntimeRefusal as ue}from"../../api/runtime-version.js";import{CONTRACT_HEADER as P,CONTRACT_LEVEL as J,REQUIRED_CONTRACT_HEADER as V,contractRefusal as ce}from"../../api/contract.js";import{crtrVersion as I}from"../../shared/crtr-version.js";import{apiSocketPath as pe}from"../../core/canvas/paths.js";import{resolveNodeToken as de}from"../../core/canvas/node-tokens.js";import{grantFor as me,hasSyncedGrants as fe}from"../../core/grants/mirror.js";import{readConfig as x}from"../../core/config.js";import{peerUid as ge}from"../../native/linux.js";import{findScopedApiToken as he,getApiToken as Ae,listScopedApiTokens as Re}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as ye,envCrtrdToken as ve}from"../../shared/env.js";import{Router as K}from"./router.js";import{handleAttachUpgrade as be,refuseUpgrade as h}from"./bridge.js";import{boundDaemonControl as Ee}from"../control.js";import{attachRoutes as we}from"./handlers/attach.js";import{peerRoutes as Te}from"../peer/handlers.js";import{bashJobRoutes as _e}from"./handlers/bash-jobs.js";import{bashRoutes as Se}from"./handlers/bash.js";import{hookExecRoutes as Ce}from"./handlers/hook-exec.js";import{brokerOperationRoutes as Q}from"./handlers/broker-ops.js";import{brokerSignalRoutes as ke,brokerSignalStreams as Oe}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as X,nodeFaultRoutes as Ue}from"./handlers/broker-recovery.js";import{canvasRoutes as He}from"./handlers/canvas.js";import{chatInventoryRoutes as Ne}from"./handlers/chat-inventory.js";import{daemonRoutes as ze}from"./handlers/daemon.js";import{fileRoutes as Pe}from"./handlers/files.js";import{focusRoutes as Ie}from"./handlers/focus.js";import{analyticsRoutes as xe}from"./handlers/analytics.js";import{memoryReadsRoutes as Be}from"./handlers/memory-reads.js";import{memoryRoutes as We}from"./handlers/memory.js";import{healthRoutes as $e}from"./handlers/health.js";import{humanRequestRoutes as Le}from"./handlers/human-requests.js";import{inboxRoutes as Me}from"./handlers/inbox.js";import{feedbackCommentRoutes as je}from"./handlers/feedback-comments.js";import{objectRoutes as De}from"./handlers/objects.js";import{customObjectRoutes as Fe}from"./handlers/custom-objects.js";import{docRoutes as Ge}from"./handlers/docs.js";import{deliveryRoutes as Y}from"./handlers/delivery.js";import{deliveryRetryRoutes as Je}from"./handlers/delivery-retry.js";import{packageDocRoutes as Ve}from"./handlers/package-docs.js";import{pluginAppRoutes as Ke}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as Z,messageRoutes as Qe}from"./handlers/messages.js";import{modelAuthRoutes as Xe}from"./handlers/modelauth.js";import{llmRoutes as Ye}from"./handlers/llm.js";import{providerRoutes as Ze}from"./handlers/providers.js";import{modelConfigRoutes as qe}from"./handlers/model-config.js";import{nodeRoutes as er}from"./handlers/nodes.js";import{nodeRecordRoutes as rr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as tr}from"./handlers/node-outcomes.js";import{nodeEventRoutes as or}from"./handlers/node-events.js";import{profileRoutes as nr}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as ir}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as sr}from"./handlers/reports.js";import{runRoutes as lr}from"./handlers/run-routes.js";import{reviewCommentRoutes as ar}from"./handlers/review-comments.js";import{reviewRoutes as ur}from"./handlers/reviews.js";import{subscriptionRoutes as cr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as pr}from"./handlers/structured-requests.js";import{cronRoutes as dr}from"./handlers/crons.js";import{setCronRequestHandler as q}from"../cron/run-socket.js";import{worktreeRoutes as mr}from"./handlers/worktree.js";import{limitsRoutes as fr}from"./handlers/limits.js";function gr(r){return new K().registerAll($e(r)).registerAll(ze).registerAll(er).registerAll(rr).registerAll(tr).registerAll(Je).registerAll(or).registerAll(_e).registerAll(Se).registerAll(Ce).registerAll(Q).registerAll(ke).registerAll(Y).registerAll(X).registerAll(Ue).registerAll(mr).registerAll(fr).registerAll(Z).registerAll(Qe).registerAll(sr).registerAll(lr).registerAll(pr).registerAll(we).registerAll(He).registerAll(xe).registerAll(Be).registerAll(We).registerAll(Pe).registerAll(De).registerAll(Fe).registerAll(Ge).registerAll(Ve).registerAll(Ke).registerAll(Ie).registerAll(cr).registerAll(dr).registerAll(nr).registerAll(Xe).registerAll(Ye).registerAll(Ze).registerAll(qe).registerAll(ur).registerAll(ar).registerAll(Me).registerAll(Le).registerAll(Ne).registerAll(ir).registerAll(je).registerAll(Te)}a(gr,"buildRouter");function hr(r,o){if(r.toUpperCase()!=="GET")return null;const l=o.split("/").filter(f=>f.length>0);if(l.length!==4||l[0]!=="v1"||l[1]!=="nodes"||l[3]!=="attach")return null;const p=l[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(hr,"attachNodeId");function Ar(r){const o=r.trim();if(o==="")return null;const l=o.lastIndexOf(":");if(l<0)return null;const p=o.slice(0,l),f=o.slice(l+1),m=Number(f);return!Number.isInteger(m)||m<0||m>65535?null:{host:p===""?"0.0.0.0":p,port:m}}a(Ar,"parseTcp");function Rr(r,o){return`${r.includes(":")?`[${r}]`:r}:${o}`}a(Rr,"formatTcpAddress");const R={code:"unauthorized",message:"missing or invalid bearer token"},v={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},B={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},b=new WeakMap;function ee(r){return b.get(r)}a(ee,"socketPrincipal");function re(r,o){const l=process.platform==="linux"?ge(r.socket):null,p=r.headers.authorization;if(p===void 0)return l===null||o.has(l)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";if(p.slice(7).startsWith("crtr_pub_"))return B;if(p.slice(7).startsWith(W)){const A=O(p.slice(7));return A!==void 0&&(l===null||o.has(l))?A.principal:"unauthorized"}const f=de(p.slice(7));if(!f||l!==null&&l!==f.uid)return"unauthorized";const m=x("user").runtime?.issuer;if(m&&!fe(m.replace(/\/$/,"")))return"runtime_starting";const C=f.grant??me("app:terminal",f.sub)?.id??null;return{class:"broker",...f,grant:C}}a(re,"resolveSocketPrincipal");const W="crtr_app_";function O(r){const o=r.startsWith(W)?he(r):void 0;return o===void 0?void 0:{principal:{class:"app",app:o.grantee,scopes:o.scopes},ceiling:o.scopes}}a(O,"appBearer");function yr(r){const o=new Map;for(const l of Re("user"))o.set(l.token,{principal:{class:"app",app:l.grantee,scopes:l.scopes},ceiling:l.scopes});return o.set(r,{principal:{class:"person"},ceiling:null}),o}a(yr,"resolveBearers");function te(r,o){const l=r.headers.authorization;if(typeof l!="string"||!l.startsWith("Bearer "))return;const p=l.slice(7);return p.startsWith(W)?O(p):o.get(p)}a(te,"authorize");function U(r){r.setHeader(z,I()),r.setHeader(P,J)}a(U,"advertiseRuntime");function _(r){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Expose-Headers",`${z}, ${P}`)}a(_,"exposeRuntimeHeaders");function oe(r,o){return(r.method??"GET").toUpperCase()!=="OPTIONS"?!1:(U(o),o.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${z}, ${P}`,"Access-Control-Allow-Headers":`authorization, content-type, ${G.toLowerCase()}, ${V.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),o.end(),!0)}a(oe,"answerPreflight");function S(r,o=!1){U(r),o&&_(r),r.writeHead(401,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{...R,origin:"runtime"}}))}a(S,"writeUnauthorized");function vr(r,o){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"startup_blocked",message:o,origin:"runtime"}}))}a(vr,"writeStartupBlocked");function ne(r){return new Promise(o=>{try{r.closeAllConnections()}catch{}r.close(()=>o())})}a(ne,"closeServer");function zt(r={}){let o=null;const l=gr(()=>o),p=new K().registerAll(Q).registerAll(Y).registerAll(X).registerAll(Z),f=a((e,t)=>{const i=Ee()?.startupBlock()??null;return i===null||e==="GET"&&(t==="/healthz"||t==="/v1/status")||e==="POST"&&(t==="/v1/daemon/migrate"||t==="/v1/daemon/admit")||i.phase==="recovering"&&p.match(e,t)!==null?null:i},"startupBlockFor"),m=pe(),C=new Set([process.getuid?.()??0,...x("user").runtime?.person_uids??[]]),A=a((e,t,i)=>{U(t);const c=a(u=>Array.isArray(u)?u[0]:u,"first"),E=c(e.headers[G.toLowerCase()]),n=ue(E,I())??ce(c(e.headers[V.toLowerCase()]),J,{legacyMinimum:E,runtimeVersion:I()});if(n!==null){t.writeHead(n.status,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:n.code,message:n.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in n?{param:n.param}:{details:n.details}}}));return}const s=a(u=>{const w=ee(e);g({event:"api.request.failed",level:"error",...w?.class==="broker"?{node_id:w.node}:{},error:u instanceof Error?u:new Error(String(u))});try{t.headersSent||t.writeHead(500,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"internal",message:"internal error",origin:"runtime"}}))}catch{}},"internalFailure");let d;try{d=new URL(e.url??"/","http://127.0.0.1")}catch{try{t.writeHead(400,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid",origin:"runtime"}}))}catch{}return}try{const u=f((e.method??"GET").toUpperCase(),d.pathname);if(u!==null){vr(t,u.message);return}l.handle(e,t,i,ee(e)??{class:"person"}).catch(s)}catch(u){s(u)}},"onRequest"),H=a((e,t,i)=>{t.on("error",()=>{});try{const c=new URL(e.url??"/","http://127.0.0.1"),E=f((e.method??"GET").toUpperCase(),c.pathname);if(E!==null){h(t,503,"Service Unavailable","startup_blocked",E.message);return}const n=hr(e.method??"GET",c.pathname);if(n===null){t.destroy();return}be(e,t,i,n).catch(()=>{try{t.destroy()}catch{}})}catch{try{t.destroy()}catch{}}},"onUpgrade"),ie=a(e=>{e.on("error",t=>{g({event:"api.server.failed",level:"error",error:t})})},"bindErrorHandler"),T=D((e,t)=>{try{const i=re(e,C);if(i==="unauthorized"){g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),S(t);return}if(i==="runtime_starting"){U(t),t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}b.set(e,i),i.class==="broker"&&g({event:"api.request.principal",level:i.app==="app:terminal"?"debug":"info",node_id:i.node,fields:{principal:`${i.app} node:${i.node}`,method:e.method,path:e.url}}),A(e,t,i.class==="app"?i.scopes:null)}catch(i){g({event:"api.principal.failed",level:"error",error:i instanceof Error?i:new Error(String(i))}),S(t)}});T.on("upgrade",(e,t,i)=>{try{const c=re(e,C);if(c==="unauthorized"||c==="runtime_starting"){c==="unauthorized"&&g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),h(t,c==="unauthorized"?401:503,"Unauthorized",c,"socket principal unavailable");return}if(c.class!=="person"&&c.class!=="broker"){h(t,403,"Forbidden",v.code,v.message);return}b.set(e,c),H(e,t,i)}catch(c){g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),h(t,401,"Unauthorized",R.code,R.message)}}),q((e,t,i)=>{b.set(e,i),A(e,t,null)});let $=!1,L,M;const se=new Promise((e,t)=>{L=e,M=t});T.once("listening",()=>{$=!0,L()}),T.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),$||M(e)});try{N(m)&&F(m)}catch{}T.listen(m,()=>{try{ae(m,process.platform==="linux"&&N("/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 y;const k=r.tcp??ye()??x("user").api.tcp;if(k!==void 0&&k!==""){const e=Ar(k);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${k}`)});else{const t=r.token??ve()??Ae("user"),i=t===void 0?void 0:yr(t),c=i===void 0?(n,s)=>{if(oe(n,s))return;const d=n.headers.authorization;if(typeof d=="string"&&d.startsWith("Bearer crtr_pub_"))b.set(n,B),_(s);else if(n.headers.origin!==void 0){S(s,!0);return}else if(d!==void 0){const w=typeof d=="string"&&d.startsWith("Bearer ")?O(d.slice(7)):void 0;if(w===void 0){S(s,!0);return}b.set(n,w.principal),_(s),A(n,s,w.ceiling);return}A(n,s,null)}:(n,s)=>{if(oe(n,s))return;const d=te(n,i);if(d===void 0&&n.headers.authorization?.startsWith("Bearer crtr_pub_")){b.set(n,B),_(s),A(n,s,null);return}if(d===void 0){S(s,!0);return}b.set(n,d.principal),_(s),A(n,s,d.ceiling)},E=i===void 0?(n,s,d)=>{if(n.headers.origin!==void 0){h(s,401,"Unauthorized",R.code,R.message);return}const u=n.headers.authorization;if(u!==void 0){if(typeof u=="string"&&u.startsWith("Bearer crtr_pub_")){h(s,403,"Forbidden",v.code,v.message);return}(typeof u=="string"&&u.startsWith("Bearer ")?O(u.slice(7)):void 0)===void 0?h(s,401,"Unauthorized",R.code,R.message):h(s,403,"Forbidden",v.code,v.message);return}H(n,s,d)}:(n,s,d)=>{const u=te(n,i);if(u===void 0){h(s,401,"Unauthorized",R.code,R.message);return}if(u.ceiling!==null){h(s,403,"Forbidden",v.code,v.message);return}H(n,s,d)};y=D(c),y.on("upgrade",E),ie(y),y.once("listening",()=>{const n=y?.address();if(n!==null&&typeof n=="object"){const{address:s,port:d}=n;o=Rr(s,d)}}),y.listen(e.port,e.host)}}let j=!1;return{ready:se,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!j){j=!0,q(null),Oe.close(),await Promise.all([ne(T),y!==void 0?ne(y):Promise.resolve()]);try{N(m)&&F(m)}catch{}}},"close")}}a(zt,"createApiServer");export{gr as buildRouter,zt as createApiServer,ee as socketPrincipal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var H=Object.defineProperty;var o=(e,t)=>H(e,"name",{value:t,configurable:!0});import{randomUUID as j}from"node:crypto";import{verifyCallToken as z}from"@north-light/identity";import{ENVELOPE_HEADER as I}from"../../core/peer/envelope.js";import{mirrorGrantLink as L,peerAuthority as U}from"./authority.js";import{peerVersionRefusal as q,PEER_VERSION_HEADER as D}from"../../core/peer/version.js";import{auditOutcome as v,writePeerAudit as G}from"../../core/audit.js";import{emitEvent as C}from"../../core/events/emit.js";import{joinedOwner as P}from"../../core/directory/join.js";import{allGrants as N}from"../../core/grants/mirror.js";import{errorCodes as T}from"../../api/error-codes.js";let O;function S(){return O??=import("../api/server.js").then(e=>e.buildRouter(()=>null)),O}o(S,"defaultRouter");async function x(e,t){return(await S()).match(e.toUpperCase(),t)!==null}o(x,"isDaemonRoute");function V(e,t,r,a,i,m){if(e.headersSent){e.destroy();return}const l=T[r];e.writeHead(t,{"content-type":"application/json; charset=utf-8","Request-Id":i,"X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify({error:{code:r,message:a,...m===void 0?{}:{details:m},...l?{type:l.type}:{},request_id:i}}))}o(V,"refuse");const _=o((e,t)=>{const r=e.headers[t.toLowerCase()];return Array.isArray(r)?r[0]:r},"header");function ee(){try{const e=P();if(e!==null)return e;const t=new Set(N().map(r=>r.sub));return t.size===1?[...t][0]:null}catch{return null}}o(ee,"runtimeOwner");async function te(e,t,r,a){const i=t.getHeader("Request-Id")?.toString()??j();t.setHeader("Request-Id",i);const m=_(e,I),l=new URL(e.url??"/","http://peer.local"),E=(e.method??"GET").toUpperCase();let d={class:m===void 0?"machine":"forwarded",grantee:null,sub:null,via:"unauthenticated",operation:`${E} ${l.pathname}`,node_id:null},R=!1;const b=o((n,c={})=>{if(!R){R=!0;try{G({request_id:i,resource:l.pathname,...d,...c,outcome:n})}catch(u){C({level:"error",event:"daemon.peer.audit_failed",error:u instanceof Error?u:new Error(String(u)),fields:{request_id:i}})}}},"record"),s=o((n,c,u,f)=>{b(v(n)),V(t,n,c,u,i,f)},"deny");try{if(r.ready&&!r.ready()){s(503,"runtime_starting","runtime_starting");return}let n;if(a!==void 0&&!("chain"in a)){s(a.status,a.code,a.message);return}if(a!==void 0)n=a;else{const y=r.audience();if(y===null){s(503,"runtime_starting","this machine does not yet know its own address");return}const g=_(e,"authorization");if(!g?.startsWith("Bearer ")||g.length<=7){s(401,"unauthorized","a machine token is required");return}try{n=await z({token:g.slice(7),jwks:r.jwks,issuer:r.issuer,audience:y})}catch{s(401,"unauthorized","invalid machine token");return}}d={...d,grantee:n.sub,sub:n.sub,via:n.chain[0]?.sub??"unauthenticated"};const c=await(r.router??S)(),u=c.match(E,l.pathname);d={...d,operation:u?.operation.name??d.operation,node_id:u?.params.id??null};const f=r.owner(),p=await U(n,m,{self:r.self,relation:o(y=>f!==null&&y===f?"owner":null,"relation"),grantLink:L(r.syncGrants??(async()=>{}))});if("status"in p){s(p.status,p.code,p.message);return}const h=q(_(e,D));if(h!==null){s(426,h.code,h.message,h.details);return}const{principal:w}=p,k=w.class==="forwarded"&&w.actor.kind==="app"?w.actor:null,A={grantee:k?.app??n.sub,node_id:k?.node??d.node_id};t.once("close",()=>b(t.writableFinished?v(t.statusCode):"aborted",A)),await c.handle(e,t,null,w)}catch(n){C({level:"error",event:"daemon.peer.ingress_failed",error:n instanceof Error?n:new Error(String(n)),fields:{request_id:i}}),s(500,"server_failure","peer request failed")}}o(te,"servePeer");export{x as isDaemonRoute,ee as runtimeOwner,te as servePeer};
|
|
1
|
+
var H=Object.defineProperty;var o=(e,t)=>H(e,"name",{value:t,configurable:!0});import{randomUUID as j}from"node:crypto";import{verifyCallToken as z}from"@north-light/identity";import{ENVELOPE_HEADER as I}from"../../core/peer/envelope.js";import{mirrorGrantLink as L,peerAuthority as U}from"./authority.js";import{peerVersionRefusal as q,PEER_VERSION_HEADER as D}from"../../core/peer/version.js";import{auditOutcome as v,writePeerAudit as G}from"../../core/audit.js";import{emitEvent as C}from"../../core/events/emit.js";import{joinedOwner as P}from"../../core/directory/join.js";import{allGrants as N}from"../../core/grants/mirror.js";import{errorCodes as T}from"../../api/error-codes.js";let O;function S(){return O??=import("../api/server.js").then(e=>e.buildRouter(()=>null)),O}o(S,"defaultRouter");async function x(e,t){return(await S()).match(e.toUpperCase(),t)!==null}o(x,"isDaemonRoute");function V(e,t,r,a,i,m){if(e.headersSent){e.destroy();return}const l=T[r];e.writeHead(t,{"content-type":"application/json; charset=utf-8","Request-Id":i,"X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify({error:{code:r,message:a,origin:"runtime",...m===void 0?{}:{details:m},...l?{type:l.type}:{},request_id:i}}))}o(V,"refuse");const _=o((e,t)=>{const r=e.headers[t.toLowerCase()];return Array.isArray(r)?r[0]:r},"header");function ee(){try{const e=P();if(e!==null)return e;const t=new Set(N().map(r=>r.sub));return t.size===1?[...t][0]:null}catch{return null}}o(ee,"runtimeOwner");async function te(e,t,r,a){const i=t.getHeader("Request-Id")?.toString()??j();t.setHeader("Request-Id",i);const m=_(e,I),l=new URL(e.url??"/","http://peer.local"),E=(e.method??"GET").toUpperCase();let d={class:m===void 0?"machine":"forwarded",grantee:null,sub:null,via:"unauthenticated",operation:`${E} ${l.pathname}`,node_id:null},R=!1;const b=o((n,c={})=>{if(!R){R=!0;try{G({request_id:i,resource:l.pathname,...d,...c,outcome:n})}catch(u){C({level:"error",event:"daemon.peer.audit_failed",error:u instanceof Error?u:new Error(String(u)),fields:{request_id:i}})}}},"record"),s=o((n,c,u,f)=>{b(v(n)),V(t,n,c,u,i,f)},"deny");try{if(r.ready&&!r.ready()){s(503,"runtime_starting","runtime_starting");return}let n;if(a!==void 0&&!("chain"in a)){s(a.status,a.code,a.message);return}if(a!==void 0)n=a;else{const y=r.audience();if(y===null){s(503,"runtime_starting","this machine does not yet know its own address");return}const g=_(e,"authorization");if(!g?.startsWith("Bearer ")||g.length<=7){s(401,"unauthorized","a machine token is required");return}try{n=await z({token:g.slice(7),jwks:r.jwks,issuer:r.issuer,audience:y})}catch{s(401,"unauthorized","invalid machine token");return}}d={...d,grantee:n.sub,sub:n.sub,via:n.chain[0]?.sub??"unauthenticated"};const c=await(r.router??S)(),u=c.match(E,l.pathname);d={...d,operation:u?.operation.name??d.operation,node_id:u?.params.id??null};const f=r.owner(),p=await U(n,m,{self:r.self,relation:o(y=>f!==null&&y===f?"owner":null,"relation"),grantLink:L(r.syncGrants??(async()=>{}))});if("status"in p){s(p.status,p.code,p.message);return}const h=q(_(e,D));if(h!==null){s(426,h.code,h.message,h.details);return}const{principal:w}=p,k=w.class==="forwarded"&&w.actor.kind==="app"?w.actor:null,A={grantee:k?.app??n.sub,node_id:k?.node??d.node_id};t.once("close",()=>b(t.writableFinished?v(t.statusCode):"aborted",A)),await c.handle(e,t,null,w)}catch(n){C({level:"error",event:"daemon.peer.ingress_failed",error:n instanceof Error?n:new Error(String(n)),fields:{request_id:i}}),s(500,"server_failure","peer request failed")}}o(te,"servePeer");export{x as isDaemonRoute,ee as runtimeOwner,te as servePeer};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.508",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
},
|
|
139
139
|
"license": "UNLICENSED",
|
|
140
140
|
"dependencies": {
|
|
141
|
-
"@north-light/identity": "0.3.
|
|
141
|
+
"@north-light/identity": "0.3.508",
|
|
142
142
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
143
143
|
"@earendil-works/pi-ai": "1.1.0",
|
|
144
144
|
"@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.508",
|
|
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.508",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"workspaces": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@earendil-works/pi-ai": "1.1.0",
|
|
19
19
|
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
20
20
|
"@earendil-works/pi-tui": "1.1.0",
|
|
21
|
-
"@north-light/identity": "0.3.
|
|
21
|
+
"@north-light/identity": "0.3.508",
|
|
22
22
|
"cron-parser": "^5.6.0",
|
|
23
23
|
"esbuild": "^0.27.7",
|
|
24
24
|
"jose": "^6.2.12",
|
|
@@ -12116,17 +12116,17 @@
|
|
|
12116
12116
|
},
|
|
12117
12117
|
"packages/crouter-api": {
|
|
12118
12118
|
"name": "@north-light/api",
|
|
12119
|
-
"version": "0.3.
|
|
12119
|
+
"version": "0.3.508",
|
|
12120
12120
|
"license": "UNLICENSED"
|
|
12121
12121
|
},
|
|
12122
12122
|
"packages/crouter-env-docker": {
|
|
12123
12123
|
"name": "@north-light/env-docker",
|
|
12124
|
-
"version": "0.3.
|
|
12124
|
+
"version": "0.3.508",
|
|
12125
12125
|
"license": "UNLICENSED"
|
|
12126
12126
|
},
|
|
12127
12127
|
"packages/crouter-identity": {
|
|
12128
12128
|
"name": "@north-light/identity",
|
|
12129
|
-
"version": "0.3.
|
|
12129
|
+
"version": "0.3.508",
|
|
12130
12130
|
"license": "UNLICENSED",
|
|
12131
12131
|
"dependencies": {
|
|
12132
12132
|
"jose": "^6.2.1"
|
|
@@ -12134,20 +12134,20 @@
|
|
|
12134
12134
|
},
|
|
12135
12135
|
"packages/crouter-plugin": {
|
|
12136
12136
|
"name": "@north-light/plugin",
|
|
12137
|
-
"version": "0.3.
|
|
12137
|
+
"version": "0.3.508",
|
|
12138
12138
|
"license": "UNLICENSED",
|
|
12139
12139
|
"dependencies": {
|
|
12140
|
-
"@north-light/api": "0.3.
|
|
12141
|
-
"@north-light/identity": "0.3.
|
|
12140
|
+
"@north-light/api": "0.3.508",
|
|
12141
|
+
"@north-light/identity": "0.3.508"
|
|
12142
12142
|
}
|
|
12143
12143
|
},
|
|
12144
12144
|
"packages/crouter-sdk": {
|
|
12145
12145
|
"name": "@north-light/sdk",
|
|
12146
|
-
"version": "0.3.
|
|
12146
|
+
"version": "0.3.508",
|
|
12147
12147
|
"license": "UNLICENSED",
|
|
12148
12148
|
"dependencies": {
|
|
12149
|
-
"@north-light/api": "0.3.
|
|
12150
|
-
"@north-light/identity": "0.3.
|
|
12149
|
+
"@north-light/api": "0.3.508",
|
|
12150
|
+
"@north-light/identity": "0.3.508",
|
|
12151
12151
|
"jose": "^6.2.1"
|
|
12152
12152
|
},
|
|
12153
12153
|
"bin": {
|