@north-light/cli 0.3.548 → 0.3.550

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.
Files changed (160) hide show
  1. package/dist/api/contract.d.ts +1 -1
  2. package/dist/api/contract.js +1 -1
  3. package/dist/api/dto/custom-objects.d.ts +1 -1
  4. package/dist/api/dto/docs.d.ts +12 -0
  5. package/dist/api/dto/objects.d.ts +17 -1
  6. package/dist/api/dto/objects.js +1 -1
  7. package/dist/api/dto/permissions.d.ts +76 -0
  8. package/dist/api/dto/permissions.js +1 -0
  9. package/dist/api/index.d.ts +3 -2
  10. package/dist/api/index.js +1 -1
  11. package/dist/api/routes.d.ts +4 -0
  12. package/dist/api/routes.js +1 -1
  13. package/dist/builtin-memory/crouter-concepts/documents.md +1 -1
  14. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +2 -2
  15. package/dist/builtin-memory/crouter-sdk/release-notes.md +11 -0
  16. package/dist/builtin-memory/internal/INDEX.md +2 -1
  17. package/dist/builtin-memory/internal/agent-shaping.md +1 -1
  18. package/dist/builtin-memory/internal/storage-tiers.md +1 -1
  19. package/dist/builtin-memory/northlight-apps/guides/files-and-documents.md +3 -3
  20. package/dist/builtin-memory/northlight-apps/guides/many-users.md +1 -1
  21. package/dist/builtin-memory/northlight-apps/guides/test-your-app.md +1 -1
  22. package/dist/clients/attach/viewer.js +9 -9
  23. package/dist/commands/canvas/list.js +2 -2
  24. package/dist/commands/canvas/share.d.ts +2 -0
  25. package/dist/commands/canvas/share.js +2 -0
  26. package/dist/commands/canvas.js +1 -1
  27. package/dist/commands/doc/edit.js +1 -1
  28. package/dist/commands/doc/shared.js +1 -1
  29. package/dist/commands/doc/write.js +1 -1
  30. package/dist/commands/sys/sync-skills.js +2 -2
  31. package/dist/core/canvas/canvas.js +20 -20
  32. package/dist/core/canvas/db.js +4 -4
  33. package/dist/core/canvas/export-sqlite.js +2 -2
  34. package/dist/core/canvas/import-sqlite.js +5 -5
  35. package/dist/core/canvas/outcome-actions.js +3 -3
  36. package/dist/core/canvas/person.js +11 -9
  37. package/dist/core/canvas/schema-pg.sql +49 -5
  38. package/dist/core/environments.js +1 -1
  39. package/dist/core/feed/feed.js +1 -1
  40. package/dist/core/grants/mirror.d.ts +9 -1
  41. package/dist/core/grants/mirror.js +2 -2
  42. package/dist/core/grants/sync.js +1 -1
  43. package/dist/core/graph/access.d.ts +8 -49
  44. package/dist/core/graph/access.js +4 -7
  45. package/dist/core/graph/custom.d.ts +5 -2
  46. package/dist/core/graph/custom.js +9 -9
  47. package/dist/core/graph/deletion.js +5 -4
  48. package/dist/core/graph/documents.d.ts +12 -3
  49. package/dist/core/graph/documents.js +13 -7
  50. package/dist/core/graph/edges.js +3 -3
  51. package/dist/core/graph/events.js +12 -8
  52. package/dist/core/graph/kinds/document.js +4 -4
  53. package/dist/core/graph/kinds/kind.js +1 -1
  54. package/dist/core/graph/kinds/node.js +5 -5
  55. package/dist/core/graph/names.d.ts +16 -1
  56. package/dist/core/graph/names.js +11 -3
  57. package/dist/core/graph/objects.d.ts +19 -2
  58. package/dist/core/graph/objects.js +16 -10
  59. package/dist/core/graph/package-docs.js +5 -5
  60. package/dist/core/graph/package-files.js +2 -2
  61. package/dist/core/graph/reader.js +3 -3
  62. package/dist/core/graph/repo-sync/exchange.js +2 -2
  63. package/dist/core/graph/rules.d.ts +7 -5
  64. package/dist/core/graph/rules.js +3 -3
  65. package/dist/core/graph/types.d.ts +12 -1
  66. package/dist/core/graph/types.js +1 -1
  67. package/dist/core/graph/watches.d.ts +1 -1
  68. package/dist/core/graph/watches.js +9 -8
  69. package/dist/core/peer/envelope.d.ts +1 -1
  70. package/dist/core/peer/envelope.js +1 -1
  71. package/dist/core/peer/stubs.d.ts +1 -1
  72. package/dist/core/peer/stubs.js +1 -1
  73. package/dist/core/permissions/boot.d.ts +17 -0
  74. package/dist/core/permissions/boot.js +18 -0
  75. package/dist/core/permissions/builtin.d.ts +8 -0
  76. package/dist/core/permissions/builtin.js +20 -0
  77. package/dist/core/permissions/ceiling.d.ts +57 -0
  78. package/dist/core/permissions/ceiling.js +22 -0
  79. package/dist/core/permissions/compile.d.ts +14 -0
  80. package/dist/core/permissions/compile.js +1 -0
  81. package/dist/core/permissions/errors.d.ts +7 -0
  82. package/dist/core/permissions/errors.js +1 -0
  83. package/dist/core/permissions/evaluator.d.ts +28 -0
  84. package/dist/core/permissions/evaluator.js +6 -0
  85. package/dist/core/permissions/facts.d.ts +56 -0
  86. package/dist/core/permissions/facts.js +2 -0
  87. package/dist/core/permissions/schema-parser.d.ts +29 -0
  88. package/dist/core/permissions/schema-parser.js +2 -0
  89. package/dist/core/permissions/schemas.d.ts +21 -0
  90. package/dist/core/permissions/schemas.js +2 -0
  91. package/dist/core/permissions/sql.d.ts +16 -0
  92. package/dist/core/permissions/sql.js +1 -0
  93. package/dist/core/runtime/broker/frame-client.d.ts +1 -1
  94. package/dist/core/runtime/broker/frame-client.js +1 -1
  95. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  96. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  97. package/dist/core/runtime/broker/frame-read.d.ts +4 -3
  98. package/dist/core/runtime/broker/frame-read.js +1 -1
  99. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  100. package/dist/core/runtime/host.js +3 -3
  101. package/dist/core/runtime/placement.js +1 -1
  102. package/dist/core/runtime/roadmap.js +1 -1
  103. package/dist/core/substrate/delivery/corpus.d.ts +2 -2
  104. package/dist/core/substrate/delivery/corpus.js +3 -3
  105. package/dist/core/substrate/delivery/deliver.js +2 -2
  106. package/dist/core/substrate/delivery/render-event.js +6 -6
  107. package/dist/core/substrate/subject-fields.d.ts +2 -0
  108. package/dist/core/substrate/subject.js +1 -1
  109. package/dist/daemon/api/app-listener.js +12 -12
  110. package/dist/daemon/api/bridge.d.ts +1 -1
  111. package/dist/daemon/api/bridge.js +4 -4
  112. package/dist/daemon/api/handlers/attach.d.ts +4 -1
  113. package/dist/daemon/api/handlers/attach.js +1 -1
  114. package/dist/daemon/api/handlers/canvas.js +5 -5
  115. package/dist/daemon/api/handlers/check.d.ts +2 -0
  116. package/dist/daemon/api/handlers/check.js +1 -0
  117. package/dist/daemon/api/handlers/custom-objects.js +2 -2
  118. package/dist/daemon/api/handlers/docs.js +1 -1
  119. package/dist/daemon/api/handlers/files.js +1 -1
  120. package/dist/daemon/api/handlers/memory.js +7 -6
  121. package/dist/daemon/api/handlers/nodes.js +1 -1
  122. package/dist/daemon/api/handlers/objects.js +3 -3
  123. package/dist/daemon/api/handlers/relations.d.ts +2 -0
  124. package/dist/daemon/api/handlers/relations.js +1 -0
  125. package/dist/daemon/api/handlers/schemas.d.ts +12 -0
  126. package/dist/daemon/api/handlers/schemas.js +1 -0
  127. package/dist/daemon/api/handlers/shares.d.ts +2 -0
  128. package/dist/daemon/api/handlers/shares.js +1 -0
  129. package/dist/daemon/api/operations.js +1 -1
  130. package/dist/daemon/api/router.d.ts +10 -6
  131. package/dist/daemon/api/router.js +1 -1
  132. package/dist/daemon/api/server.js +1 -1
  133. package/dist/daemon/api/vendor-signin.js +21 -24
  134. package/dist/daemon/crtrd.js +12 -12
  135. package/dist/daemon/reconcilers/delivery-lane.js +2 -2
  136. package/dist/migrations/004-canvas-documents/fields.d.ts +1 -1
  137. package/dist/migrations/004-canvas-documents/fields.js +2 -2
  138. package/docs/apps/guides/files-and-documents.md +3 -3
  139. package/docs/apps/guides/many-users.md +1 -1
  140. package/docs/apps/guides/test-your-app.md +1 -1
  141. package/docs/cli/documents-and-preferences.md +1 -1
  142. package/docs/concepts/documents.md +1 -1
  143. package/docs/concepts/scopes-and-trust.md +2 -2
  144. package/docs/sdk/release-notes.md +11 -0
  145. package/package.json +2 -2
  146. package/packages/crouter-identity/dist/index.js +14 -1
  147. package/packages/crouter-identity/package.json +1 -1
  148. package/runtime.lock.json +13 -13
  149. package/dist/core/graph/spaces/app.d.ts +0 -3
  150. package/dist/core/graph/spaces/app.js +0 -1
  151. package/dist/core/graph/spaces/index.d.ts +0 -18
  152. package/dist/core/graph/spaces/index.js +0 -1
  153. package/dist/core/graph/spaces/own-memory.d.ts +0 -18
  154. package/dist/core/graph/spaces/own-memory.js +0 -1
  155. package/dist/core/graph/spaces/person.d.ts +0 -5
  156. package/dist/core/graph/spaces/person.js +0 -3
  157. package/dist/core/graph/spaces/repo.d.ts +0 -14
  158. package/dist/core/graph/spaces/repo.js +0 -1
  159. package/dist/core/runs/confinement.d.ts +0 -25
  160. package/dist/core/runs/confinement.js +0 -2
@@ -1 +1 @@
1
- var ce=Object.defineProperty;var a=(t,o)=>ce(t,"name",{value:o,configurable:!0});import{createServer as D}from"node:http";import{chmodSync as ue,existsSync as N,unlinkSync as F}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as G,RUNTIME_VERSION_HEADER as z,minimumRuntimeRefusal as pe}from"../../api/runtime-version.js";import{CONTRACT_HEADER as P,CONTRACT_LEVEL as J,REQUIRED_CONTRACT_HEADER as V,contractRefusal as de}from"../../api/contract.js";import{crtrVersion as I}from"../../shared/crtr-version.js";import{apiSocketPath as me}from"../../core/canvas/paths.js";import{resolveNodeToken as fe}from"../../core/canvas/node-tokens.js";import{grantFor as ge,hasSyncedGrants as he}from"../../core/grants/mirror.js";import{readConfig as x}from"../../core/config.js";import{peerUid as Ae}from"../../native/linux.js";import{findScopedApiToken as Re,getApiToken as ye,listScopedApiTokens as ve}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as be,envCrtrdToken as Ee}from"../../shared/env.js";import{Router as K}from"./router.js";import{handleAttachUpgrade as we,refuseUpgrade as h}from"./bridge.js";import{boundDaemonControl as Se}from"../control.js";import{attachRoutes as Te}from"./handlers/attach.js";import{peerRoutes as _e}from"../peer/handlers.js";import{bashJobRoutes as Ce}from"./handlers/bash-jobs.js";import{bashRoutes as ke}from"./handlers/bash.js";import{hookExecRoutes as Oe}from"./handlers/hook-exec.js";import{brokerOperationRoutes as Q}from"./handlers/broker-ops.js";import{brokerSignalRoutes as Ue,brokerSignalStreams as He}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as X,nodeFaultRoutes as Ne}from"./handlers/broker-recovery.js";import{canvasRoutes as ze}from"./handlers/canvas.js";import{chatInventoryRoutes as Pe}from"./handlers/chat-inventory.js";import{daemonRoutes as Ie}from"./handlers/daemon.js";import{fileRoutes as xe}from"./handlers/files.js";import{focusRoutes as Be}from"./handlers/focus.js";import{analyticsRoutes as We}from"./handlers/analytics.js";import{memoryReadsRoutes as $e}from"./handlers/memory-reads.js";import{memoryRoutes as Le}from"./handlers/memory.js";import{healthRoutes as Me}from"./handlers/health.js";import{humanRequestRoutes as je}from"./handlers/human-requests.js";import{inboxRoutes as De}from"./handlers/inbox.js";import{feedbackCommentRoutes as Fe}from"./handlers/feedback-comments.js";import{objectRoutes as Ge}from"./handlers/objects.js";import{customObjectRoutes as Je}from"./handlers/custom-objects.js";import{docRoutes as Ve}from"./handlers/docs.js";import{deliveryRoutes as Y}from"./handlers/delivery.js";import{deliveryRetryRoutes as Ke}from"./handlers/delivery-retry.js";import{packageDocRoutes as Qe}from"./handlers/package-docs.js";import{documentAccessRoutes as Xe}from"./handlers/document-access.js";import{pluginAppRoutes as Ye}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as Z,messageRoutes as Ze}from"./handlers/messages.js";import{modelAuthRoutes as qe}from"./handlers/modelauth.js";import{llmRoutes as er}from"./handlers/llm.js";import{providerRoutes as rr}from"./handlers/providers.js";import{modelConfigRoutes as tr}from"./handlers/model-config.js";import{nodeRoutes as or}from"./handlers/nodes.js";import{nodeRecordRoutes as nr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as ir}from"./handlers/node-outcomes.js";import{nodeEventRoutes as sr}from"./handlers/node-events.js";import{profileRoutes as lr}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as ar}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as cr}from"./handlers/reports.js";import{runRoutes as ur}from"./handlers/run-routes.js";import{reviewCommentRoutes as pr}from"./handlers/review-comments.js";import{reviewRoutes as dr}from"./handlers/reviews.js";import{subscriptionRoutes as mr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as fr}from"./handlers/structured-requests.js";import{cronRoutes as gr}from"./handlers/crons.js";import{setCronRequestHandler as q}from"../cron/run-socket.js";import{worktreeRoutes as hr}from"./handlers/worktree.js";import{limitsRoutes as Ar}from"./handlers/limits.js";function Rr(t){return new K().registerAll(Me(t)).registerAll(Ie).registerAll(or).registerAll(nr).registerAll(ir).registerAll(Ke).registerAll(sr).registerAll(Ce).registerAll(ke).registerAll(Oe).registerAll(Q).registerAll(Ue).registerAll(Y).registerAll(X).registerAll(Ne).registerAll(hr).registerAll(Ar).registerAll(Z).registerAll(Ze).registerAll(cr).registerAll(ur).registerAll(fr).registerAll(Te).registerAll(ze).registerAll(We).registerAll($e).registerAll(Le).registerAll(xe).registerAll(Ge).registerAll(Je).registerAll(Ve).registerAll(Qe).registerAll(Xe).registerAll(Ye).registerAll(Be).registerAll(mr).registerAll(gr).registerAll(lr).registerAll(qe).registerAll(er).registerAll(rr).registerAll(tr).registerAll(dr).registerAll(pr).registerAll(De).registerAll(je).registerAll(Pe).registerAll(ar).registerAll(Fe).registerAll(_e)}a(Rr,"buildRouter");function yr(t,o){if(t.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(yr,"attachNodeId");function vr(t){const o=t.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(vr,"parseTcp");function br(t,o){return`${t.includes(":")?`[${t}]`:t}:${o}`}a(br,"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(t){return b.get(t)}a(ee,"socketPrincipal");async function re(t,o){const l=process.platform==="linux"?Ae(t.socket):null,p=t.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=await fe(p.slice(7));if(!f||l!==null&&l!==f.uid)return"unauthorized";const m=x("user").runtime?.issuer;if(m&&!await he(m.replace(/\/$/,"")))return"runtime_starting";const C=f.grant??(await ge("app:terminal",f.sub))?.id??null;return{class:"broker",...f,grant:C}}a(re,"resolveSocketPrincipal");const W="crtr_app_";function O(t){const o=t.startsWith(W)?Re(t):void 0;return o===void 0?void 0:{principal:{class:"app",app:o.grantee,scopes:o.scopes},ceiling:o.scopes}}a(O,"appBearer");function Er(t){const o=new Map;for(const l of ve("user"))o.set(l.token,{principal:{class:"app",app:l.grantee,scopes:l.scopes},ceiling:l.scopes});return o.set(t,{principal:{class:"person"},ceiling:null}),o}a(Er,"resolveBearers");function te(t,o){const l=t.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(t){t.setHeader(z,I()),t.setHeader(P,J)}a(U,"advertiseRuntime");function T(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Expose-Headers",`${z}, ${P}`)}a(T,"exposeRuntimeHeaders");function oe(t,o){return(t.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 _(t,o=!1){U(t),o&&T(t),t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{...R,origin:"runtime"}}))}a(_,"writeUnauthorized");function wr(t,o){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:o,origin:"runtime"}}))}a(wr,"writeStartupBlocked");function ne(t){return new Promise(o=>{try{t.closeAllConnections()}catch{}t.close(()=>o())})}a(ne,"closeServer");function Bt(t={}){let o=null;const l=Rr(()=>o),p=new K().registerAll(Q).registerAll(Y).registerAll(X).registerAll(Z),f=a((e,r)=>{const n=Se()?.startupBlock()??null;return n===null||e==="GET"&&(r==="/healthz"||r==="/v1/status"||r==="/v1/ready")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||n.phase==="recovering"&&p.match(e,r)!==null?null:n},"startupBlockFor"),m=me(),C=new Set([process.getuid?.()??0,...x("user").runtime?.person_uids??[]]),A=a((e,r,n)=>{U(r);const c=a(u=>Array.isArray(u)?u[0]:u,"first"),E=c(e.headers[G.toLowerCase()]),i=pe(E,I())??de(c(e.headers[V.toLowerCase()]),J,{legacyMinimum:E,runtimeVersion:I()});if(i!==null){r.writeHead(i.status,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:i.code,message:i.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in i?{param:i.param}:{details:i.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{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.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{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.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){wr(r,u.message);return}l.handle(e,r,n,ee(e)??{class:"person"}).catch(s)}catch(u){s(u)}},"onRequest"),H=a((e,r,n)=>{r.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(r,503,"Service Unavailable","startup_blocked",E.message);return}const i=yr(e.method??"GET",c.pathname);if(i===null){r.destroy();return}we(e,r,n,i).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),ie=a(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),se=a(async(e,r)=>{try{const n=await re(e,C);if(n==="unauthorized"){g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),_(r);return}if(n==="runtime_starting"){U(r),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}b.set(e,n),n.class==="broker"&&g({event:"api.request.principal",level:n.app==="app:terminal"?"debug":"info",node_id:n.node,fields:{principal:`${n.app} node:${n.node}`,method:e.method,path:e.url}}),A(e,r,n.class==="app"?n.scopes:null)}catch(n){g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}),_(r)}},"onSocketRequest"),S=D((e,r)=>{se(e,r).catch(n=>g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}))}),le=a(async(e,r,n)=>{try{const c=await re(e,C);if(c==="unauthorized"||c==="runtime_starting"){c==="unauthorized"&&g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),h(r,c==="unauthorized"?401:503,"Unauthorized",c,"socket principal unavailable");return}if(c.class!=="person"&&c.class!=="broker"){h(r,403,"Forbidden",v.code,v.message);return}b.set(e,c),H(e,r,n)}catch(c){g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),h(r,401,"Unauthorized",R.code,R.message)}},"onSocketUpgrade");S.on("upgrade",(e,r,n)=>{le(e,r,n).catch(c=>g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}))}),q((e,r,n)=>{b.set(e,n),A(e,r,null)});let $=!1,L,M;const ae=new Promise((e,r)=>{L=e,M=r});S.once("listening",()=>{$=!0,L()}),S.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),$||M(e)});try{N(m)&&F(m)}catch{}S.listen(m,()=>{try{ue(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=t.tcp??be()??x("user").api.tcp;if(k!==void 0&&k!==""){const e=vr(k);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${k}`)});else{const r=t.token??Ee()??ye("user"),n=r===void 0?void 0:Er(r),c=n===void 0?(i,s)=>{if(oe(i,s))return;const d=i.headers.authorization;if(typeof d=="string"&&d.startsWith("Bearer crtr_pub_"))b.set(i,B),T(s);else if(i.headers.origin!==void 0){_(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,!0);return}b.set(i,w.principal),T(s),A(i,s,w.ceiling);return}A(i,s,null)}:(i,s)=>{if(oe(i,s))return;const d=te(i,n);if(d===void 0&&i.headers.authorization?.startsWith("Bearer crtr_pub_")){b.set(i,B),T(s),A(i,s,null);return}if(d===void 0){_(s,!0);return}b.set(i,d.principal),T(s),A(i,s,d.ceiling)},E=n===void 0?(i,s,d)=>{if(i.headers.origin!==void 0){h(s,401,"Unauthorized",R.code,R.message);return}const u=i.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(i,s,d)}:(i,s,d)=>{const u=te(i,n);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(i,s,d)};y=D(c),y.on("upgrade",E),ie(y),y.once("listening",()=>{const i=y?.address();if(i!==null&&typeof i=="object"){const{address:s,port:d}=i;o=br(s,d)}}),y.listen(e.port,e.host)}}let j=!1;return{ready:ae,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!j){j=!0,q(null),He.close(),await Promise.all([ne(S),y!==void 0?ne(y):Promise.resolve()]);try{N(m)&&F(m)}catch{}}},"close")}}a(Bt,"createApiServer");export{Rr as buildRouter,Bt as createApiServer,ee as socketPrincipal};
1
+ var pe=Object.defineProperty;var a=(t,i)=>pe(t,"name",{value:i,configurable:!0});import{createServer as F}from"node:http";import{chmodSync as de,existsSync as H,unlinkSync as G}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as J,RUNTIME_VERSION_HEADER as P,minimumRuntimeRefusal as me}from"../../api/runtime-version.js";import{CONTRACT_HEADER as I,CONTRACT_LEVEL as V,REQUIRED_CONTRACT_HEADER as K,contractRefusal as fe}from"../../api/contract.js";import{crtrVersion as x}from"../../shared/crtr-version.js";import{apiSocketPath as ge}from"../../core/canvas/paths.js";import{resolveNodeToken as he}from"../../core/canvas/node-tokens.js";import{grantFor as Ae,hasSyncedGrants as Re}from"../../core/grants/mirror.js";import{readConfig as B}from"../../core/config.js";import{peerUid as ye}from"../../native/linux.js";import{findScopedApiToken as ve,getApiToken as be,listScopedApiTokens as we}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as Ee,envCrtrdToken as _e}from"../../shared/env.js";import{Router as Q}from"./router.js";import{handleAttachUpgrade as Se,refuseUpgrade as h}from"./bridge.js";import{boundDaemonControl as Te}from"../control.js";import{attachRoutes as Ce,mayAttachNode as X}from"./handlers/attach.js";import{peerRoutes as ke}from"../peer/handlers.js";import{bashJobRoutes as Oe}from"./handlers/bash-jobs.js";import{bashRoutes as Ue}from"./handlers/bash.js";import{hookExecRoutes as Ne}from"./handlers/hook-exec.js";import{brokerOperationRoutes as Y}from"./handlers/broker-ops.js";import{brokerSignalRoutes as ze,brokerSignalStreams as He}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as Z,nodeFaultRoutes as Pe}from"./handlers/broker-recovery.js";import{canvasRoutes as Ie}from"./handlers/canvas.js";import{chatInventoryRoutes as xe}from"./handlers/chat-inventory.js";import{daemonRoutes as Be}from"./handlers/daemon.js";import{fileRoutes as $e}from"./handlers/files.js";import{focusRoutes as We}from"./handlers/focus.js";import{analyticsRoutes as Le}from"./handlers/analytics.js";import{memoryReadsRoutes as Me}from"./handlers/memory-reads.js";import{memoryRoutes as je}from"./handlers/memory.js";import{healthRoutes as De}from"./handlers/health.js";import{humanRequestRoutes as Fe}from"./handlers/human-requests.js";import{inboxRoutes as Ge}from"./handlers/inbox.js";import{feedbackCommentRoutes as Je}from"./handlers/feedback-comments.js";import{objectRoutes as Ve}from"./handlers/objects.js";import{shareRoutes as Ke}from"./handlers/shares.js";import{customObjectRoutes as Qe}from"./handlers/custom-objects.js";import{docRoutes as Xe}from"./handlers/docs.js";import{deliveryRoutes as q}from"./handlers/delivery.js";import{deliveryRetryRoutes as Ye}from"./handlers/delivery-retry.js";import{packageDocRoutes as Ze}from"./handlers/package-docs.js";import{documentAccessRoutes as qe}from"./handlers/document-access.js";import{pluginAppRoutes as er}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as ee,messageRoutes as rr}from"./handlers/messages.js";import{modelAuthRoutes as tr}from"./handlers/modelauth.js";import{llmRoutes as or}from"./handlers/llm.js";import{providerRoutes as nr}from"./handlers/providers.js";import{modelConfigRoutes as ir}from"./handlers/model-config.js";import{nodeRoutes as sr}from"./handlers/nodes.js";import{nodeRecordRoutes as lr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as ar}from"./handlers/node-outcomes.js";import{nodeEventRoutes as cr}from"./handlers/node-events.js";import{profileRoutes as ur}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as pr}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as dr}from"./handlers/reports.js";import{runRoutes as mr}from"./handlers/run-routes.js";import{reviewCommentRoutes as fr}from"./handlers/review-comments.js";import{reviewRoutes as gr}from"./handlers/reviews.js";import{subscriptionRoutes as hr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as Ar}from"./handlers/structured-requests.js";import{cronRoutes as Rr}from"./handlers/crons.js";import{setCronRequestHandler as re}from"../cron/run-socket.js";import{worktreeRoutes as yr}from"./handlers/worktree.js";import{limitsRoutes as vr}from"./handlers/limits.js";function br(t){return new Q().registerAll(De(t)).registerAll(Be).registerAll(Ke).registerAll(sr).registerAll(lr).registerAll(ar).registerAll(Ye).registerAll(cr).registerAll(Oe).registerAll(Ue).registerAll(Ne).registerAll(Y).registerAll(ze).registerAll(q).registerAll(Z).registerAll(Pe).registerAll(yr).registerAll(vr).registerAll(ee).registerAll(rr).registerAll(dr).registerAll(mr).registerAll(Ar).registerAll(Ce).registerAll(Ie).registerAll(Le).registerAll(Me).registerAll(je).registerAll($e).registerAll(Ve).registerAll(Qe).registerAll(Xe).registerAll(Ze).registerAll(qe).registerAll(er).registerAll(We).registerAll(hr).registerAll(Rr).registerAll(ur).registerAll(tr).registerAll(or).registerAll(nr).registerAll(ir).registerAll(gr).registerAll(fr).registerAll(Ge).registerAll(Fe).registerAll(xe).registerAll(pr).registerAll(Je).registerAll(ke)}a(br,"buildRouter");function wr(t,i){if(t.toUpperCase()!=="GET")return null;const c=i.split("/").filter(f=>f.length>0);if(c.length!==4||c[0]!=="v1"||c[1]!=="nodes"||c[3]!=="attach")return null;const d=c[2];return d===void 0||d===""?null:decodeURIComponent(d)}a(wr,"attachNodeId");function Er(t){const i=t.trim();if(i==="")return null;const c=i.lastIndexOf(":");if(c<0)return null;const d=i.slice(0,c),f=i.slice(c+1),m=Number(f);return!Number.isInteger(m)||m<0||m>65535?null:{host:d===""?"0.0.0.0":d,port:m}}a(Er,"parseTcp");function _r(t,i){return`${t.includes(":")?`[${t}]`:t}:${i}`}a(_r,"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"},$={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},b=new WeakMap;function O(t){return b.get(t)}a(O,"socketPrincipal");async function te(t,i){const c=process.platform==="linux"?ye(t.socket):null,d=t.headers.authorization;if(d===void 0)return c===null||i.has(c)?{class:"person"}:"unauthorized";if(typeof d!="string"||!d.startsWith("Bearer "))return"unauthorized";if(d.slice(7).startsWith("crtr_pub_"))return $;if(d.slice(7).startsWith(W)){const A=U(d.slice(7));return A!==void 0&&(c===null||i.has(c))?A.principal:"unauthorized"}const f=await he(d.slice(7));if(!f||c!==null&&c!==f.uid)return"unauthorized";const m=B("user").runtime?.issuer;if(m&&!await Re(m.replace(/\/$/,"")))return"runtime_starting";const C=f.grant??(await Ae("app:terminal",f.sub))?.id??null;return{class:"broker",...f,grant:C}}a(te,"resolveSocketPrincipal");const W="crtr_app_";function U(t){const i=t.startsWith(W)?ve(t):void 0;return i===void 0?void 0:{principal:{class:"app",app:i.grantee,scopes:i.scopes},ceiling:i.scopes}}a(U,"appBearer");function Sr(t){const i=new Map;for(const c of we("user"))i.set(c.token,{principal:{class:"app",app:c.grantee,scopes:c.scopes},ceiling:c.scopes});return i.set(t,{principal:{class:"person"},ceiling:null}),i}a(Sr,"resolveBearers");function oe(t,i){const c=t.headers.authorization;if(typeof c!="string"||!c.startsWith("Bearer "))return;const d=c.slice(7);return d.startsWith(W)?U(d):i.get(d)}a(oe,"authorize");function N(t){t.setHeader(P,x()),t.setHeader(I,V)}a(N,"advertiseRuntime");function S(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Expose-Headers",`${P}, ${I}`)}a(S,"exposeRuntimeHeaders");function ne(t,i){return(t.method??"GET").toUpperCase()!=="OPTIONS"?!1:(N(i),i.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${P}, ${I}`,"Access-Control-Allow-Headers":`authorization, content-type, ${J.toLowerCase()}, ${K.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),i.end(),!0)}a(ne,"answerPreflight");function T(t,i=!1){N(t),i&&S(t),t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{...R,origin:"runtime"}}))}a(T,"writeUnauthorized");function Tr(t,i){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:i,origin:"runtime"}}))}a(Tr,"writeStartupBlocked");function ie(t){return new Promise(i=>{try{t.closeAllConnections()}catch{}t.close(()=>i())})}a(ie,"closeServer");function Mt(t={}){let i=null;const c=br(()=>i),d=new Q().registerAll(Y).registerAll(q).registerAll(Z).registerAll(ee),f=a((e,r)=>{const o=Te()?.startupBlock()??null;return o===null||e==="GET"&&(r==="/healthz"||r==="/v1/status"||r==="/v1/ready")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||o.phase==="recovering"&&d.match(e,r)!==null?null:o},"startupBlockFor"),m=ge(),C=new Set([process.getuid?.()??0,...B("user").runtime?.person_uids??[]]),A=a((e,r,o)=>{N(r);const l=a(u=>Array.isArray(u)?u[0]:u,"first"),w=l(e.headers[J.toLowerCase()]),n=me(w,x())??fe(l(e.headers[K.toLowerCase()]),V,{legacyMinimum:w,runtimeVersion:x()});if(n!==null){r.writeHead(n.status,{"content-type":"application/json; charset=utf-8"}),r.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 E=O(e);g({event:"api.request.failed",level:"error",...E?.class==="broker"?{node_id:E.node}:{},error:u instanceof Error?u:new Error(String(u))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error",origin:"runtime"}}))}catch{}},"internalFailure");let p;try{p=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",origin:"runtime"}}))}catch{}return}try{const u=f((e.method??"GET").toUpperCase(),p.pathname);if(u!==null){Tr(r,u.message);return}c.handle(e,r,o,O(e)??{class:"person"}).catch(s)}catch(u){s(u)}},"onRequest"),se=a(async(e,r,o)=>{const l=O(e);return l===void 0||l.class==="person"||await X(l,"either",o)?!0:(h(r,404,"Not Found","node_not_found",`no node ${o}`),!1)},"authorizeAttachUpgrade"),z=a((e,r,o)=>{r.on("error",()=>{});try{const l=new URL(e.url??"/","http://127.0.0.1"),w=f((e.method??"GET").toUpperCase(),l.pathname);if(w!==null){h(r,503,"Service Unavailable","startup_blocked",w.message);return}const n=wr(e.method??"GET",l.pathname);if(n===null){r.destroy();return}se(e,r,n).then(s=>s?Se(e,r,o,n,async p=>{const u=O(e);return u===void 0||u.class==="person"||await X(u,p,n)}):void 0).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),le=a(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),ae=a(async(e,r)=>{try{const o=await te(e,C);if(o==="unauthorized"){g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),T(r);return}if(o==="runtime_starting"){N(r),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}b.set(e,o),o.class==="broker"&&g({event:"api.request.principal",level:o.app==="app:terminal"?"debug":"info",node_id:o.node,fields:{principal:`${o.app} node:${o.node}`,method:e.method,path:e.url}}),A(e,r,o.class==="app"?o.scopes:null)}catch(o){g({event:"api.principal.failed",level:"error",error:o instanceof Error?o:new Error(String(o))}),T(r)}},"onSocketRequest"),_=F((e,r)=>{ae(e,r).catch(o=>g({event:"api.principal.failed",level:"error",error:o instanceof Error?o:new Error(String(o))}))}),ce=a(async(e,r,o)=>{try{const l=await te(e,C);if(l==="unauthorized"||l==="runtime_starting"){l==="unauthorized"&&g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),h(r,l==="unauthorized"?401:503,"Unauthorized",l,"socket principal unavailable");return}if(l.class!=="person"&&l.class!=="broker"){h(r,403,"Forbidden",v.code,v.message);return}b.set(e,l),z(e,r,o)}catch(l){g({event:"api.principal.failed",level:"error",error:l instanceof Error?l:new Error(String(l))}),h(r,401,"Unauthorized",R.code,R.message)}},"onSocketUpgrade");_.on("upgrade",(e,r,o)=>{ce(e,r,o).catch(l=>g({event:"api.principal.failed",level:"error",error:l instanceof Error?l:new Error(String(l))}))}),re((e,r,o)=>{b.set(e,o),A(e,r,null)});let L=!1,M,j;const ue=new Promise((e,r)=>{M=e,j=r});_.once("listening",()=>{L=!0,M()}),_.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),L||j(e)});try{H(m)&&G(m)}catch{}_.listen(m,()=>{try{de(m,process.platform==="linux"&&H("/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=t.tcp??Ee()??B("user").api.tcp;if(k!==void 0&&k!==""){const e=Er(k);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${k}`)});else{const r=t.token??_e()??be("user"),o=r===void 0?void 0:Sr(r),l=o===void 0?(n,s)=>{if(ne(n,s))return;const p=n.headers.authorization;if(typeof p=="string"&&p.startsWith("Bearer crtr_pub_"))b.set(n,$),S(s);else if(n.headers.origin!==void 0){T(s,!0);return}else if(p!==void 0){const E=typeof p=="string"&&p.startsWith("Bearer ")?U(p.slice(7)):void 0;if(E===void 0){T(s,!0);return}b.set(n,E.principal),S(s),A(n,s,E.ceiling);return}A(n,s,null)}:(n,s)=>{if(ne(n,s))return;const p=oe(n,o);if(p===void 0&&n.headers.authorization?.startsWith("Bearer crtr_pub_")){b.set(n,$),S(s),A(n,s,null);return}if(p===void 0){T(s,!0);return}b.set(n,p.principal),S(s),A(n,s,p.ceiling)},w=o===void 0?(n,s,p)=>{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 ")?U(u.slice(7)):void 0)===void 0?h(s,401,"Unauthorized",R.code,R.message):h(s,403,"Forbidden",v.code,v.message);return}z(n,s,p)}:(n,s,p)=>{const u=oe(n,o);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}z(n,s,p)};y=F(l),y.on("upgrade",w),le(y),y.once("listening",()=>{const n=y?.address();if(n!==null&&typeof n=="object"){const{address:s,port:p}=n;i=_r(s,p)}}),y.listen(e.port,e.host)}}let D=!1;return{ready:ue,tcpAddress:a(()=>i,"tcpAddress"),close:a(async()=>{if(!D){D=!0,re(null),He.close(),await Promise.all([ie(_),y!==void 0?ie(y):Promise.resolve()]);try{H(m)&&G(m)}catch{}}},"close")}}a(Mt,"createApiServer");export{br as buildRouter,Mt as createApiServer,O as socketPrincipal};
@@ -1,4 +1,4 @@
1
- var P=Object.defineProperty;var o=(e,t)=>P(e,"name",{value:t,configurable:!0});import{randomBytes as j}from"node:crypto";import{joinedOwner as N}from"../../core/directory/join.js";import{consumeHandoffJti as R,handoffJtiConsumed as z}from"../../core/model-auth/handoff-jti.js";import{completeModelAuthFlow as H,modelAuthFlowFailure as V,modelAuthProvider as F,readModelAuthFlow as k,startModelAuthFlow as I,waitModelAuthFlow as D,VendorSignInError as x}from"../../core/model-auth/flows.js";import{emitEvent as m}from"../../core/events/emit.js";import{RunError as d}from"../../core/runs/operations.js";import{LONG_POLL_MAX_WAIT_SECONDS as B}from"../../api/long-poll.js";const h="/signin/vendor",$=900,G=B*1e3,U="https://chatgpt.com/#settings/Security";function m1(e){return e===h||e.startsWith(`${h}/`)}o(m1,"isVendorSignInPath");function p(){return new d(401,"unauthorized","invalid vendor sign-in handoff")}o(p,"unauthorized");async function _(e,t){const r=await e.verifyHandoff(t);let n;try{n=N()}catch{n=null}if(r.sub!==n)throw p();return r}o(_,"verifyOwnerHandoff");function J(e){const t=e.headers.authorization;return t?.startsWith("Bearer ")&&t.length>7?t.slice(7):void 0}o(J,"bearer");function y(e,t){const r=e.getAll(t);return r.length===1?r[0]:void 0}o(y,"single");function Z(e,t,r,n){const a=new URL(e);return a.searchParams.set("status",t),r&&a.searchParams.set("reason",r),n&&a.searchParams.set("step",n),a.toString()}o(Z,"returnUrl");function v(e){return e.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}o(v,"escapeHtml");function C(e,t,r){e.writeHead(t,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),e.end(JSON.stringify(r))}o(C,"sendJson");async function q(e){const t=[];let r=0;for await(const a of e){if(r+=a.length,r>64*1024)throw new d(400,"invalid_request","request body too large");t.push(a)}let n;try{n=JSON.parse(Buffer.concat(t).toString("utf8"))}catch{throw new d(400,"invalid_request","invalid JSON body")}if(typeof n!="object"||n===null||Array.isArray(n))throw new d(400,"invalid_request","request body must be a JSON object");return n}o(q,"jsonBody");const W=`
1
+ var O=Object.defineProperty;var o=(e,t)=>O(e,"name",{value:t,configurable:!0});import{randomBytes as P}from"node:crypto";import{joinedOwner as N}from"../../core/directory/join.js";import{consumeHandoffJti as R,handoffJtiConsumed as z}from"../../core/model-auth/handoff-jti.js";import{completeModelAuthFlow as H,modelAuthFlowFailure as V,modelAuthProvider as F,readModelAuthFlow as k,startModelAuthFlow as D,waitModelAuthFlow as B,VendorSignInError as x}from"../../core/model-auth/flows.js";import{emitEvent as m}from"../../core/events/emit.js";import{RunError as s}from"../../core/runs/operations.js";import{LONG_POLL_MAX_WAIT_SECONDS as I}from"../../api/long-poll.js";const f="/signin/vendor",$=900,U=I*1e3,G="https://chatgpt.com/#settings/Security";function m1(e){return e===f||e.startsWith(`${f}/`)}o(m1,"isVendorSignInPath");function p(){return new s(401,"unauthorized","invalid vendor sign-in handoff")}o(p,"unauthorized");async function _(e,t){const r=await e.verifyHandoff(t);let n;try{n=N()}catch{n=null}if(r.sub!==n)throw p();return r}o(_,"verifyOwnerHandoff");function J(e){const t=e.headers.authorization;return t?.startsWith("Bearer ")&&t.length>7?t.slice(7):void 0}o(J,"bearer");function y(e,t){const r=e.getAll(t);return r.length===1?r[0]:void 0}o(y,"single");function Z(e,t,r,n){const a=new URL(e);return a.searchParams.set("status",t),r&&a.searchParams.set("reason",r),n&&a.searchParams.set("step",n),a.toString()}o(Z,"returnUrl");function v(e){return e.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}o(v,"escapeHtml");function C(e,t,r){e.writeHead(t,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),e.end(JSON.stringify(r))}o(C,"sendJson");async function q(e){const t=[];let r=0;for await(const a of e){if(r+=a.length,r>64*1024)throw new s(400,"invalid_request","request body too large");t.push(a)}let n;try{n=JSON.parse(Buffer.concat(t).toString("utf8"))}catch{throw new s(400,"invalid_request","invalid JSON body")}if(typeof n!="object"||n===null||Array.isArray(n))throw new s(400,"invalid_request","request body must be a JSON object");return n}o(q,"jsonBody");const W=`
2
2
  :root{color-scheme:light dark;
3
3
  --canvas:#f0f2f4;--surface:#fff;--sunken:#e5e7ea;--zone:#e5e7ea;--neutral:#e5e7ea;--neutral-hover:#d7d9dc;--neutral-pressed:#cbcdd0;
4
4
  --accent:#217f51;--accent-hover:#1e6e46;--accent-pressed:#1a5e3c;--accent-border:#217f51;--accent-subtle:#d5f7e1;--accent-fg:#1e6e46;--on-accent:#fff;
@@ -27,8 +27,7 @@ main{flex:1;display:flex;flex-direction:column;align-items:center;padding:2.5rem
27
27
  .logo{position:relative;flex:none;width:3.5rem;height:3.5rem;border-radius:12px;overflow:hidden}
28
28
  .logo svg{display:block;width:100%;height:100%}
29
29
  .logo::after{content:"";position:absolute;inset:0;border:1px solid var(--line);border-radius:inherit}
30
- .eyebrow{display:block;font-size:.8125rem;line-height:1.2308;font-weight:500;color:var(--muted)}
31
- h1{margin-top:.25rem;font-size:1.25rem;line-height:1.3;font-weight:600;letter-spacing:-.02em}
30
+ h1{font-size:1.25rem;line-height:1.3;font-weight:600;letter-spacing:-.02em}
32
31
  .steps{list-style:none;padding:0;display:flex;flex-direction:column;gap:1.25rem}
33
32
  .steps>li{display:flex;gap:.875rem}
34
33
  .n{position:relative;flex:none;display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border-radius:9999px;background:var(--neutral);font-size:.8125rem;font-weight:500;font-variant-numeric:tabular-nums}
@@ -132,7 +131,7 @@ if(cfg.kind==='anthropic'){
132
131
  clearInterval(timer);
133
132
  $('user-code').className='code expired';$('copy').hidden=true;$('expired-badge').hidden=false;
134
133
  var link=$('device-link');link.removeAttribute('href');link.setAttribute('aria-disabled','true');
135
- $('settings').hidden=true;$('waiting').hidden=true;$('expired').hidden=false;
134
+ $('waiting').hidden=true;$('expired').hidden=false;
136
135
  }
137
136
  (function poll(){
138
137
  fetch(cfg.base+'/wait',{headers:auth})
@@ -147,7 +146,7 @@ if(cfg.kind==='anthropic'){
147
146
  })();
148
147
  }
149
148
  })();
150
- `,Y={arrow:'<path d="M7 7h10v10"/><path d="M7 17 17 7"/>',copy:'<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',clock:'<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>',warn:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',alert:'<circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/>',check:'<path d="M20 6 9 18l-5-5"/>'};function s(e,t=""){return`<svg class="ic${t}" viewBox="0 0 24 24" aria-hidden="true" focusable="false">${Y[e]}</svg>`}o(s,"icon");const K='<svg viewBox="-77.5 12 931 931" aria-hidden="true" focusable="false"><path fill="currentColor" d="M234 294m0 0h2l-1 5-6 16-5 15-6 25-4 23-2 22-1 5v47l5 38 5 26 6 22 10 24 8 16 9 14 14 19 13 16 11 13 9 11 11 12 7 8 13 16 11 14 14 19 12 19 12 23 7 17 6 23 3 14 3-1 5-15 20-84 6-24 6-21 10-33 10-25 8-16 8-15 8-12 9-12 8-10 9-10 7-8 6-7 20-20h2l2-4 17-17 7-8 10-13 14-21 8-16 8-18 5-15 2-7 2 1 6 36 2 18v41l-4 28-5 19-7 19-10 21-8 13-10 15-13 17-11 13-12 14-9 10-7 8-9 11h-2l-2 4-9 11-14 19-8 12-15 25-11 21-12 26-9 23-5 12-13 38-12 39-5 18-5 17h-2l-9-29-9-27-14-38-13-29-8-16-11-18-10-13-7-9-25-25-3-2v-2l-3-1v-2l-4-2-10-9-8-7-14-12-20-18-13-13-9-11-12-16-12-20-12-25-7-19-6-23-4-24-1-11-1-3v-39l3-23 6-27 7-23 5-11 11-23 9-16 10-14 8-11 9-11 10-11zM430 22m0 0h2v2h2l7 8 10 11 9 11 12 16 9 15 8 16 6 15 5 19 2 11 1 12v18l-1 16-5 24-5 16-7 15-9 17-7 11-10 15-10 13-9 11-13 14-7 8-11 12-7 8-13 16-11 15-13 20-10 18-8 16-7 18-5 15-4 18-2 14-1 27 2 24 3 17 5 23 8 30 12 36 9 28 3 8 4 12v2l-4-2-68-102-13-22-11-23-9-24-7-26-4-23-2-16v-31l3-25 6-27 7-21 7-15 8-16 14-21 11-14 26-30 12-13 8-10h2l2-4 10-11 7-9 14-19 7-10 13-24 7-19 4-15 3-14 3-22 2-24v-20l-2-31zM615 384m0 0 2 1 6 36 2 18v41l-4 28-5 19-7 19-10 21-8 13-10 15-13 17-11 13-12 14-9 10-7 8-9 11h-2l-2 4-9 11-14 19-8 12-15 25-11 21-2 5h-3l-2 2h-13l-6-5-11-6 1-9h-2l2-14-2 3 1-8 9-36 6-21 10-33 10-25 8-16 8-15 8-12 9-12 8-10 9-10 7-8 6-7 20-20h2l2-4 17-17 7-8 10-13 14-21 8-16 8-18 5-15zM557 254m0 0 2 1 4 16 2 16v34l-2 18-5 20-8 24-14 28-10 16-11 16-13 15-12 14-11 13-11 14-14 19-12 20-8 16-7 19-6 20-4 20-4 35-3 41-3 52-4 28-1 3h-2l-8-42-10-52-7-33-7-43v-54l4-24 5-17 8-20 10-19 7-10 10-13 9-11 19-19 8-7 16-15 8-7 9-9 8-7 11-11 1-2h2l2-4 11-13 10-14 11-17 9-19 8-21zM185 615m0 0 4 5 6 10 9 12 2 1 3 5 5-2 1-1h8l5 5 2 3 7 3 6 3 4 5 8 6 5 3v2h2v2h6l4 3 6 1 1 8 10 3 4 2 9 2 5 6 6 1h6l8 8 7 1 9 7h5l1-4-4-6-10-13-7-9-1-3h-2l-7-9v-3l7 6 7 9 11 14 14 19 12 19 12 23 7 17 6 23 3 14 3-1 5-15 10-42 5-22h2l1-4 1 4-1 8h-2l3 4-1 8 11 6 5 4h13l4-3-1 6-8 17-9 23-5 12-13 38-12 39-5 18-5 17h-2l-9-29-9-27-14-38-13-29-8-16-11-18-10-13-7-9-25-25-3-2v-2l-3-1v-2l-4-2-10-9-8-7-14-12-20-18-13-13-9-11-12-16-9-15zM369 553m0 0h1l1 43 2 3 3 4-1 6-1 1v7l1 2 1 15 7 1 5-2 5 1v-2l3-1 4 1 1-2h-3l1-3 6-2 2 11-1 8-3 12h2v2l3-1 2-12h-2l1-4 1-1 3-21 4-21h1v10l-4 30-3 34-4 69-4 28-1 3h-2l-8-42-10-52-7-33-6-37zM430 22m0 0h2v2h2l7 8 10 11 9 11 4 5 1 5 2 4 1 7 2 2-1 3-5-1h-7l-8-2-5 1v7l-1 1h-5l-2-8-1-2-1-15h-2l-2-31zM417 598m0 0h1v10l-4 30-3 34-4 69-4 28-1 3h-2l-7-37-1-16h8l2 1v-2h2l1-2 2-35v-13l-2-3-3-5-1-8 1-9-1-4-5-2v-2l-3-1v-2l3-1 4 1 1-2h-3l1-3 6-2 2 11-1 8-3 12h2v2l3-1 2-12h-2l1-4 1-1 3-21zM417 598m0 0h1v10l-4 30-3 34-1 17h-2v15l-1 12h-1v-18l1-17v-13l-2-3-3-5-1-8 1-9-1-4-5-2v-2l-3-1v-2l3-1 4 1 1-2h-3l1-3 6-2 2 11-1 8-3 12h2v2l3-1 2-12h-2l1-4 1-1 3-21zM310 619m0 0 4 2 4 6 5 8 7 9 3 5 2-1 2 1 2 10 6-1 2 1v2h-5l3 7 9 13 6 9 3 1v-2l-4-14h3l5 16 3 8 4 12v2l-4-2-60-90zM255 597m0 0 5 3 12 16 9 11 11 13 9 11 11 12 4 5-1 3-7-7-4-1-7-4v-2l-4-2-4-4 4 1 3-1v-3l-5-2-3-5v-2h-2l-6-8v-2l-3-1-1-2-8-1 1-2-2-8-3-4v-2h-2l-4-6-3-4zM425 181m0 0 7 1 1 3 12 2 2 3 3 1v-2h3l1 3-6 2-1 3h-2v2h-2l-1 7-5 1-2-5 2-3h3l1-5-3 1-3 3-1-4-5-2v-5h-6l-3-3zM369 553m0 0h1l1 43 2 3 3 4-1 6-1 1v7l1 2 1 15 2 1h-2l3 13 2 10v5l-3-4-5-25-4-26zM340 614m0 0 1 2h2l6 20 6 18 3 15-2-1-5-15-2-4v-5h-6l-3-2-9-2 2-3v2l5-4h4 2l-1-5-3-12zM296 649m0 0 5 2 11 12 4 5-1 3-7-7-4-1-7-4v-2l-4-2-4-4 4 1 3-1zM403 625m0 0h2l2 11-1 8-2 7-2 1v-9l-1-4-5-2v-2l-3-1v-2l3-1 4 1 1-2h-3l1-3zM417 598m0 0h1v10l-4 30-2 24h-1l-1-17h-2l1-4 1-1 3-21zM163 561m0 0 2 3 5 16 2 6 2 1 3 9 2 4 4-1 1-2 1 3h-2l-2 5 3 6-1 2-3-3-11-24-4-11-2-10zM439 685m0 0 1 2h9l3 4v6l7 2 3 7-4-1-6-4-5-4v-7h-9l-2-2zM369 553m0 0h1l1 43 2 3 3 4-1 6-1 1-1 7-2-2v-7h-2zM434 687m0 0h1v6l-3 9-7 29-4 5 1-8 9-36zM317 672m0 0 6 4 9 11 11 14 6 8v2l-4-2-10-13-7-9-1-3h-2l-7-9zM276 622m0 0 5 5 11 13 7 8-1 2-7-4-3-5v-2h-2l-6-8v-2l-3-1-2-4zM310 619m0 0 4 2 4 6 5 8 7 9-1 4-4-5-8-11-7-11zM416 172m0 0 2 1-1 7h-2v5l4-1-1 3-5 2-3-1v-7l4-8zM381 664m0 0 2 4 6 27v5l-1-2h-2l-5-24zM443 655m0 0 1 4-7 25-1 2h-2l1-7 6-22h2zM163 561m0 0 2 3 5 16 2 6 2 1v5l-2 1-7-18-2-10zM490 702m0 0 1 3-10 15-3 5-4 3v-5l5-5 7-11zM387 698m0 0 1 2h2l3 16v14h-1l-5-26zM426 139m0 0 1 3-1 5-7 22-2-1 2-9 5-18h2zM466 739m0 0h2l-1 6-8 15-3 1 2-7 7-12zM411 636m0 0h2v12l-1 14h-1l-1-17h-2l1-4zM349 645m0 0h3l3 9 3 15-2-1-5-15-2-4zM335 694m0 0 5 3 9 12v2l-4-2-10-13zM386 633m0 0 7 1-3 2-4 1-2 4h-4l-2-6h5zM547 287m0 0 3 2-3 7-1 5h-2l-1 4-2-1 1-5zM557 254m0 0 2 1 3 13-4-1 1-2h-2l-1 3-1-3zM560 311m0 0 3 1-2 5-3 6-9-3v-1l9-1zM409 664m0 0h1v25h-1l-2-24zM340 614m0 0 1 2h2l4 16-4-2-3-12zM438 705m0 0 10 2 1 7-3-1-4-4h-5zM502 685m0 0 1 3-8 11-3 1 2-5zM422 191m0 0 4 1 3 4-2 4-5-3zM359 675m0 0h3l4 13-1 4-4-9zM225 599m0 0 5 2 12 6-3 1-9-4-6-3zM255 597m0 0 5 3 6 8-1 2-3-1-4-6-3-4zM414 180m0 0h1v5l4-1-1 3-5 2-3-1 1-5zM341 665m0 0 3 1 6 9-1 4-8-12zM370 608m0 0h1l1 9 3 1-2 10h-1l-2-12zM439 671m0 0 1 2-4 13h-2l1-7 3-7zM341 658m0 0 6 1v2h-5l-1 5-3-3 1-4zM373 625m0 0h2l1 9 2 1h-2l-1 5h-1l-1-6zM185 615m0 0 4 5 5 8-1 3-4-5-4-7zM434 687m0 0h1v6l-3 9-2 3 1-13zM385 686m0 0h2l2 9v5l-1-2h-2l-1-5zM390 711m0 0h2l1 8v11h-1l-2-10zM355 657m0 0 2 3 4 12v3l-3-1-2-10zM413 624m0 0h1v14l-1-2h-2l1-11zM494 120m0 0h2l2 6v10l-2-3-2-9zM163 561m0 0 2 3 4 13-1 3v-2h-2l-3-13zM489 106m0 0h2l4 10-2 4-4-11zM230 609m0 0 5 1 4 5 3 2-6-1-3-3v-2l-3-1zM392 660m0 0h2v2h2l5 5 2 1-1 4-10-10zM254 615m0 0 8 1 1 1v5l-2-1v-2l-6-2zM190 587m0 0 6 1 2-1 4 2 1 3-13-2zM417 598m0 0h1v10l-1 5-2-1 1-9zM273 545m0 0 2 3 3 8v3h-2l-3-8z"/></svg>',Q={claude:'<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false"><rect width="48" height="48" fill="#F3E9D7"/><path transform="translate(24 24) scale(.13) translate(-124 -124)" fill="#D97757" d="M52.4285 162.873L98.7844 136.879L99.5485 134.602L98.7844 133.334H96.4921L88.7237 132.862L62.2346 132.153L39.3113 131.207L17.0249 130.026L11.4214 128.844L6.2 121.873L6.7094 118.447L11.4214 115.257L18.171 115.847L33.0711 116.911L55.485 118.447L71.6586 119.392L95.728 121.873H99.5485L100.058 120.337L98.7844 119.392L97.7656 118.447L74.5877 102.732L49.4995 86.1905L36.3823 76.62L29.3779 71.7757L25.8121 67.2858L24.2839 57.3608L30.6515 50.2716L39.3113 50.8623L41.4763 51.4531L50.2636 58.1879L68.9842 72.7209L93.4357 90.6804L97.0015 93.6343L98.4374 92.6652L98.6571 91.9801L97.0015 89.2625L83.757 65.2772L69.621 40.8192L63.2534 30.6579L61.5978 24.632C60.9565 22.1032 60.579 20.0111 60.579 17.4246L67.8381 7.49965L71.9133 6.19995L81.7193 7.49965L85.7946 11.0443L91.9074 24.9865L101.714 46.8451L116.996 76.62L121.453 85.4816L123.873 93.6343L124.764 96.1155H126.292V94.6976L127.566 77.9197L129.858 57.3608L132.15 30.8942L132.915 23.4505L136.608 14.4708L143.994 9.62643L149.725 12.344L154.437 19.0788L153.8 23.4505L150.998 41.6463L145.522 70.1215L141.957 89.2625H143.994L146.414 86.7813L156.093 74.0206L172.266 53.698L179.398 45.6635L187.803 36.802L193.152 32.5484H203.34L210.726 43.6549L207.415 55.1159L196.972 68.3492L188.312 79.5739L175.896 96.2095L168.191 109.585L168.882 110.689L170.738 110.53L198.755 104.504L213.91 101.787L231.994 98.7149L240.144 102.496L241.036 106.395L237.852 114.311L218.495 119.037L195.826 123.645L162.07 131.592L161.696 131.893L162.137 132.547L177.36 133.925L183.855 134.279H199.774L229.447 136.524L237.215 141.605L241.8 147.867L241.036 152.711L229.065 158.737L213.019 154.956L175.45 145.977L162.587 142.787H160.805V143.85L171.502 154.366L191.242 172.089L215.82 195.011L217.094 200.682L213.91 205.172L210.599 204.699L188.949 188.394L180.544 181.069L161.696 165.118H160.422V166.772L164.752 173.152L187.803 207.771L188.949 218.405L187.294 221.832L181.308 223.959L174.813 222.777L161.187 203.754L147.305 182.486L136.098 163.345L134.745 164.2L128.075 235.42L125.019 239.082L117.887 241.8L111.902 237.31L108.718 229.984L111.902 215.452L115.722 196.547L118.779 181.541L121.58 162.873L123.291 156.636L123.14 156.219L121.773 156.449L107.699 175.752L86.304 204.699L69.3663 222.777L65.291 224.431L58.2867 220.768L58.9235 214.27L62.8713 208.48L86.304 178.705L100.44 160.155L109.551 149.507L109.462 147.967L108.959 147.924L46.6977 188.512L35.6182 189.93L30.7788 185.44L31.4156 178.115L33.7079 175.752L52.4285 162.873Z"/></svg>',chatgpt:'<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false"><rect width="48" height="48" fill="#0D0D0D"/><path transform="translate(24 24) scale(2.35) translate(-7.98 -8)" fill="#FFF" d="M12.9851 6.93777C13.1163 6.54364 13.1618 6.12607 13.1186 5.71295C13.0754 5.29983 12.9444 4.90072 12.7344 4.54231C12.4232 4.00021 11.9478 3.57101 11.3768 3.31664C10.8058 3.06227 10.1687 2.99589 9.55751 3.12706C9.28184 2.81639 8.943 2.56818 8.56362 2.39905C8.18425 2.22993 7.77314 2.14379 7.3578 2.1464C6.73292 2.1449 6.1237 2.34187 5.61797 2.70892C5.11225 3.07598 4.73616 3.59415 4.54391 4.18873C4.13684 4.27206 3.75225 4.44139 3.41591 4.68539C3.07957 4.92938 2.79924 5.24241 2.59368 5.60352C2.27994 6.14413 2.14602 6.77039 2.21123 7.39205C2.27644 8.01367 2.5374 8.59851 2.95649 9.06224C2.82527 9.45637 2.77975 9.87394 2.82297 10.2871C2.8662 10.7002 2.99718 11.0993 3.20713 11.4577C3.51841 11.9998 3.99385 12.4289 4.56484 12.6833C5.13584 12.9377 5.77289 13.0041 6.38407 12.8729C6.65975 13.1836 6.99862 13.4318 7.37796 13.601C7.75734 13.7701 8.16844 13.8562 8.58379 13.8536C9.20899 13.8552 9.81853 13.6582 10.3244 13.2909C10.8304 12.9236 11.2065 12.4051 11.3986 11.8101C11.8057 11.7268 12.1903 11.5575 12.5266 11.3135C12.8629 11.0695 13.1433 10.7564 13.3488 10.3953C13.6622 9.85477 13.7958 9.22866 13.7304 8.60726C13.6651 7.98587 13.4041 7.40129 12.9851 6.93777ZM8.58472 13.0883C8.0715 13.089 7.57441 12.9093 7.18031 12.5805C7.19808 12.5708 7.22925 12.5537 7.24956 12.5413L9.58061 11.1948C9.63911 11.1615 9.6877 11.1133 9.72136 11.055C9.75505 10.9967 9.77258 10.9305 9.77217 10.8632V7.57684L10.7575 8.14576C10.7626 8.14834 10.7671 8.15214 10.7704 8.15685C10.7738 8.16157 10.7759 8.16704 10.7766 8.17275V10.8943C10.7759 11.4756 10.5448 12.0329 10.1339 12.4441C9.72308 12.8554 9.16599 13.087 8.58472 13.0883ZM3.87091 11.075C3.61385 10.6309 3.5212 10.1105 3.60918 9.60485C3.62649 9.61524 3.65673 9.6337 3.67842 9.64617L6.00947 10.9926C6.06756 11.0266 6.13365 11.0445 6.20094 11.0445C6.2682 11.0445 6.33428 11.0266 6.39238 10.9926L9.23834 9.34936V10.4872C9.23867 10.493 9.23755 10.4988 9.23509 10.5041C9.23264 10.5094 9.22892 10.5139 9.22427 10.5174L6.86782 11.878C6.36379 12.1683 5.76516 12.2467 5.20333 12.0962C4.64148 11.9457 4.1623 11.5784 3.87091 11.075ZM3.25768 5.98617C3.51363 5.54141 3.91789 5.2009 4.39966 5.02421C4.39966 5.04429 4.39851 5.07985 4.39851 5.10452V7.79747C4.3981 7.86473 4.41561 7.93087 4.44924 7.98915C4.48287 8.04739 4.5314 8.09563 4.58984 8.1289L7.4358 9.77197L6.45054 10.3409C6.44568 10.3441 6.44009 10.346 6.43429 10.3465C6.4285 10.3471 6.42265 10.3462 6.41729 10.3439L4.06062 8.98216C3.55747 8.69077 3.19039 8.21176 3.03987 7.65013C2.88935 7.08853 2.96768 6.49014 3.25768 5.98617ZM11.3527 7.86994L8.50669 6.22667L9.49198 5.65799C9.49684 5.6548 9.50243 5.65283 9.50823 5.65231C9.51402 5.65178 9.51985 5.65272 9.5252 5.655L11.8819 7.01554C12.2429 7.2241 12.5371 7.53119 12.7299 7.90087C12.9228 8.27056 13.0063 8.68752 12.9707 9.10295C12.9351 9.51839 12.7819 9.91509 12.5291 10.2466C12.2762 10.5781 11.9341 10.8307 11.5428 10.9749C11.5428 10.9546 11.5428 10.919 11.5428 10.8943V8.20137C11.5434 8.13423 11.5261 8.06814 11.4926 8.0099C11.4592 7.95165 11.4109 7.90336 11.3527 7.86994ZM12.3333 6.394C12.316 6.38337 12.2858 6.36514 12.2641 6.3527L9.93303 5.00621C9.87493 4.97232 9.80887 4.95444 9.74158 4.95444C9.67432 4.95444 9.60824 4.97232 9.55014 5.00621L6.70418 6.64951V5.51167C6.70386 5.50585 6.70497 5.50005 6.70743 5.49479C6.70988 5.48952 6.7136 5.48492 6.71826 5.48144L9.0747 4.12203C9.4357 3.91387 9.84853 3.81281 10.2649 3.83068C10.6812 3.84856 11.0838 3.98462 11.4257 4.22296C11.7675 4.46129 12.0344 4.79204 12.1951 5.17652C12.3559 5.56099 12.4038 5.98327 12.3333 6.394ZM6.16851 8.42203L5.18299 7.85311C5.17784 7.85053 5.17336 7.84673 5.17002 7.84202C5.16668 7.8373 5.16455 7.83183 5.16385 7.82609V5.10452C5.16411 4.6877 5.28311 4.27956 5.5069 3.9279C5.73071 3.57623 6.05006 3.29559 6.42756 3.11883C6.80507 2.94206 7.22509 2.87649 7.63851 2.92977C8.05195 2.98306 8.44163 3.153 8.76197 3.41971C8.74421 3.42941 8.71327 3.44649 8.69272 3.45895L6.36168 4.80542C6.30317 4.83867 6.25462 4.8869 6.22093 4.94516C6.18727 5.0034 6.16974 5.06958 6.17012 5.13683L6.16851 8.42203ZM6.70371 7.26803L7.97126 6.53595L9.23878 7.26757V8.73127L7.97126 9.46292L6.70371 8.73127V7.26803Z"/></svg>'},S="team@northlight.ai";function T(e){const t=JSON.stringify(e.config).replace(/</g,"\\u003c");return`<!doctype html>
149
+ `,Y={arrow:'<path d="M7 7h10v10"/><path d="M7 17 17 7"/>',copy:'<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',clock:'<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>',warn:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',alert:'<circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/>',check:'<path d="M20 6 9 18l-5-5"/>'};function d(e,t=""){return`<svg class="ic${t}" viewBox="0 0 24 24" aria-hidden="true" focusable="false">${Y[e]}</svg>`}o(d,"icon");const K='<svg viewBox="-77.5 12 931 931" aria-hidden="true" focusable="false"><path fill="currentColor" d="M234 294m0 0h2l-1 5-6 16-5 15-6 25-4 23-2 22-1 5v47l5 38 5 26 6 22 10 24 8 16 9 14 14 19 13 16 11 13 9 11 11 12 7 8 13 16 11 14 14 19 12 19 12 23 7 17 6 23 3 14 3-1 5-15 20-84 6-24 6-21 10-33 10-25 8-16 8-15 8-12 9-12 8-10 9-10 7-8 6-7 20-20h2l2-4 17-17 7-8 10-13 14-21 8-16 8-18 5-15 2-7 2 1 6 36 2 18v41l-4 28-5 19-7 19-10 21-8 13-10 15-13 17-11 13-12 14-9 10-7 8-9 11h-2l-2 4-9 11-14 19-8 12-15 25-11 21-12 26-9 23-5 12-13 38-12 39-5 18-5 17h-2l-9-29-9-27-14-38-13-29-8-16-11-18-10-13-7-9-25-25-3-2v-2l-3-1v-2l-4-2-10-9-8-7-14-12-20-18-13-13-9-11-12-16-12-20-12-25-7-19-6-23-4-24-1-11-1-3v-39l3-23 6-27 7-23 5-11 11-23 9-16 10-14 8-11 9-11 10-11zM430 22m0 0h2v2h2l7 8 10 11 9 11 12 16 9 15 8 16 6 15 5 19 2 11 1 12v18l-1 16-5 24-5 16-7 15-9 17-7 11-10 15-10 13-9 11-13 14-7 8-11 12-7 8-13 16-11 15-13 20-10 18-8 16-7 18-5 15-4 18-2 14-1 27 2 24 3 17 5 23 8 30 12 36 9 28 3 8 4 12v2l-4-2-68-102-13-22-11-23-9-24-7-26-4-23-2-16v-31l3-25 6-27 7-21 7-15 8-16 14-21 11-14 26-30 12-13 8-10h2l2-4 10-11 7-9 14-19 7-10 13-24 7-19 4-15 3-14 3-22 2-24v-20l-2-31zM615 384m0 0 2 1 6 36 2 18v41l-4 28-5 19-7 19-10 21-8 13-10 15-13 17-11 13-12 14-9 10-7 8-9 11h-2l-2 4-9 11-14 19-8 12-15 25-11 21-2 5h-3l-2 2h-13l-6-5-11-6 1-9h-2l2-14-2 3 1-8 9-36 6-21 10-33 10-25 8-16 8-15 8-12 9-12 8-10 9-10 7-8 6-7 20-20h2l2-4 17-17 7-8 10-13 14-21 8-16 8-18 5-15zM557 254m0 0 2 1 4 16 2 16v34l-2 18-5 20-8 24-14 28-10 16-11 16-13 15-12 14-11 13-11 14-14 19-12 20-8 16-7 19-6 20-4 20-4 35-3 41-3 52-4 28-1 3h-2l-8-42-10-52-7-33-7-43v-54l4-24 5-17 8-20 10-19 7-10 10-13 9-11 19-19 8-7 16-15 8-7 9-9 8-7 11-11 1-2h2l2-4 11-13 10-14 11-17 9-19 8-21zM185 615m0 0 4 5 6 10 9 12 2 1 3 5 5-2 1-1h8l5 5 2 3 7 3 6 3 4 5 8 6 5 3v2h2v2h6l4 3 6 1 1 8 10 3 4 2 9 2 5 6 6 1h6l8 8 7 1 9 7h5l1-4-4-6-10-13-7-9-1-3h-2l-7-9v-3l7 6 7 9 11 14 14 19 12 19 12 23 7 17 6 23 3 14 3-1 5-15 10-42 5-22h2l1-4 1 4-1 8h-2l3 4-1 8 11 6 5 4h13l4-3-1 6-8 17-9 23-5 12-13 38-12 39-5 18-5 17h-2l-9-29-9-27-14-38-13-29-8-16-11-18-10-13-7-9-25-25-3-2v-2l-3-1v-2l-4-2-10-9-8-7-14-12-20-18-13-13-9-11-12-16-9-15zM369 553m0 0h1l1 43 2 3 3 4-1 6-1 1v7l1 2 1 15 7 1 5-2 5 1v-2l3-1 4 1 1-2h-3l1-3 6-2 2 11-1 8-3 12h2v2l3-1 2-12h-2l1-4 1-1 3-21 4-21h1v10l-4 30-3 34-4 69-4 28-1 3h-2l-8-42-10-52-7-33-6-37zM430 22m0 0h2v2h2l7 8 10 11 9 11 4 5 1 5 2 4 1 7 2 2-1 3-5-1h-7l-8-2-5 1v7l-1 1h-5l-2-8-1-2-1-15h-2l-2-31zM417 598m0 0h1v10l-4 30-3 34-4 69-4 28-1 3h-2l-7-37-1-16h8l2 1v-2h2l1-2 2-35v-13l-2-3-3-5-1-8 1-9-1-4-5-2v-2l-3-1v-2l3-1 4 1 1-2h-3l1-3 6-2 2 11-1 8-3 12h2v2l3-1 2-12h-2l1-4 1-1 3-21zM417 598m0 0h1v10l-4 30-3 34-1 17h-2v15l-1 12h-1v-18l1-17v-13l-2-3-3-5-1-8 1-9-1-4-5-2v-2l-3-1v-2l3-1 4 1 1-2h-3l1-3 6-2 2 11-1 8-3 12h2v2l3-1 2-12h-2l1-4 1-1 3-21zM310 619m0 0 4 2 4 6 5 8 7 9 3 5 2-1 2 1 2 10 6-1 2 1v2h-5l3 7 9 13 6 9 3 1v-2l-4-14h3l5 16 3 8 4 12v2l-4-2-60-90zM255 597m0 0 5 3 12 16 9 11 11 13 9 11 11 12 4 5-1 3-7-7-4-1-7-4v-2l-4-2-4-4 4 1 3-1v-3l-5-2-3-5v-2h-2l-6-8v-2l-3-1-1-2-8-1 1-2-2-8-3-4v-2h-2l-4-6-3-4zM425 181m0 0 7 1 1 3 12 2 2 3 3 1v-2h3l1 3-6 2-1 3h-2v2h-2l-1 7-5 1-2-5 2-3h3l1-5-3 1-3 3-1-4-5-2v-5h-6l-3-3zM369 553m0 0h1l1 43 2 3 3 4-1 6-1 1v7l1 2 1 15 2 1h-2l3 13 2 10v5l-3-4-5-25-4-26zM340 614m0 0 1 2h2l6 20 6 18 3 15-2-1-5-15-2-4v-5h-6l-3-2-9-2 2-3v2l5-4h4 2l-1-5-3-12zM296 649m0 0 5 2 11 12 4 5-1 3-7-7-4-1-7-4v-2l-4-2-4-4 4 1 3-1zM403 625m0 0h2l2 11-1 8-2 7-2 1v-9l-1-4-5-2v-2l-3-1v-2l3-1 4 1 1-2h-3l1-3zM417 598m0 0h1v10l-4 30-2 24h-1l-1-17h-2l1-4 1-1 3-21zM163 561m0 0 2 3 5 16 2 6 2 1 3 9 2 4 4-1 1-2 1 3h-2l-2 5 3 6-1 2-3-3-11-24-4-11-2-10zM439 685m0 0 1 2h9l3 4v6l7 2 3 7-4-1-6-4-5-4v-7h-9l-2-2zM369 553m0 0h1l1 43 2 3 3 4-1 6-1 1-1 7-2-2v-7h-2zM434 687m0 0h1v6l-3 9-7 29-4 5 1-8 9-36zM317 672m0 0 6 4 9 11 11 14 6 8v2l-4-2-10-13-7-9-1-3h-2l-7-9zM276 622m0 0 5 5 11 13 7 8-1 2-7-4-3-5v-2h-2l-6-8v-2l-3-1-2-4zM310 619m0 0 4 2 4 6 5 8 7 9-1 4-4-5-8-11-7-11zM416 172m0 0 2 1-1 7h-2v5l4-1-1 3-5 2-3-1v-7l4-8zM381 664m0 0 2 4 6 27v5l-1-2h-2l-5-24zM443 655m0 0 1 4-7 25-1 2h-2l1-7 6-22h2zM163 561m0 0 2 3 5 16 2 6 2 1v5l-2 1-7-18-2-10zM490 702m0 0 1 3-10 15-3 5-4 3v-5l5-5 7-11zM387 698m0 0 1 2h2l3 16v14h-1l-5-26zM426 139m0 0 1 3-1 5-7 22-2-1 2-9 5-18h2zM466 739m0 0h2l-1 6-8 15-3 1 2-7 7-12zM411 636m0 0h2v12l-1 14h-1l-1-17h-2l1-4zM349 645m0 0h3l3 9 3 15-2-1-5-15-2-4zM335 694m0 0 5 3 9 12v2l-4-2-10-13zM386 633m0 0 7 1-3 2-4 1-2 4h-4l-2-6h5zM547 287m0 0 3 2-3 7-1 5h-2l-1 4-2-1 1-5zM557 254m0 0 2 1 3 13-4-1 1-2h-2l-1 3-1-3zM560 311m0 0 3 1-2 5-3 6-9-3v-1l9-1zM409 664m0 0h1v25h-1l-2-24zM340 614m0 0 1 2h2l4 16-4-2-3-12zM438 705m0 0 10 2 1 7-3-1-4-4h-5zM502 685m0 0 1 3-8 11-3 1 2-5zM422 191m0 0 4 1 3 4-2 4-5-3zM359 675m0 0h3l4 13-1 4-4-9zM225 599m0 0 5 2 12 6-3 1-9-4-6-3zM255 597m0 0 5 3 6 8-1 2-3-1-4-6-3-4zM414 180m0 0h1v5l4-1-1 3-5 2-3-1 1-5zM341 665m0 0 3 1 6 9-1 4-8-12zM370 608m0 0h1l1 9 3 1-2 10h-1l-2-12zM439 671m0 0 1 2-4 13h-2l1-7 3-7zM341 658m0 0 6 1v2h-5l-1 5-3-3 1-4zM373 625m0 0h2l1 9 2 1h-2l-1 5h-1l-1-6zM185 615m0 0 4 5 5 8-1 3-4-5-4-7zM434 687m0 0h1v6l-3 9-2 3 1-13zM385 686m0 0h2l2 9v5l-1-2h-2l-1-5zM390 711m0 0h2l1 8v11h-1l-2-10zM355 657m0 0 2 3 4 12v3l-3-1-2-10zM413 624m0 0h1v14l-1-2h-2l1-11zM494 120m0 0h2l2 6v10l-2-3-2-9zM163 561m0 0 2 3 4 13-1 3v-2h-2l-3-13zM489 106m0 0h2l4 10-2 4-4-11zM230 609m0 0 5 1 4 5 3 2-6-1-3-3v-2l-3-1zM392 660m0 0h2v2h2l5 5 2 1-1 4-10-10zM254 615m0 0 8 1 1 1v5l-2-1v-2l-6-2zM190 587m0 0 6 1 2-1 4 2 1 3-13-2zM417 598m0 0h1v10l-1 5-2-1 1-9zM273 545m0 0 2 3 3 8v3h-2l-3-8z"/></svg>',Q={claude:'<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false"><rect width="48" height="48" fill="#F3E9D7"/><path transform="translate(24 24) scale(.13) translate(-124 -124)" fill="#D97757" d="M52.4285 162.873L98.7844 136.879L99.5485 134.602L98.7844 133.334H96.4921L88.7237 132.862L62.2346 132.153L39.3113 131.207L17.0249 130.026L11.4214 128.844L6.2 121.873L6.7094 118.447L11.4214 115.257L18.171 115.847L33.0711 116.911L55.485 118.447L71.6586 119.392L95.728 121.873H99.5485L100.058 120.337L98.7844 119.392L97.7656 118.447L74.5877 102.732L49.4995 86.1905L36.3823 76.62L29.3779 71.7757L25.8121 67.2858L24.2839 57.3608L30.6515 50.2716L39.3113 50.8623L41.4763 51.4531L50.2636 58.1879L68.9842 72.7209L93.4357 90.6804L97.0015 93.6343L98.4374 92.6652L98.6571 91.9801L97.0015 89.2625L83.757 65.2772L69.621 40.8192L63.2534 30.6579L61.5978 24.632C60.9565 22.1032 60.579 20.0111 60.579 17.4246L67.8381 7.49965L71.9133 6.19995L81.7193 7.49965L85.7946 11.0443L91.9074 24.9865L101.714 46.8451L116.996 76.62L121.453 85.4816L123.873 93.6343L124.764 96.1155H126.292V94.6976L127.566 77.9197L129.858 57.3608L132.15 30.8942L132.915 23.4505L136.608 14.4708L143.994 9.62643L149.725 12.344L154.437 19.0788L153.8 23.4505L150.998 41.6463L145.522 70.1215L141.957 89.2625H143.994L146.414 86.7813L156.093 74.0206L172.266 53.698L179.398 45.6635L187.803 36.802L193.152 32.5484H203.34L210.726 43.6549L207.415 55.1159L196.972 68.3492L188.312 79.5739L175.896 96.2095L168.191 109.585L168.882 110.689L170.738 110.53L198.755 104.504L213.91 101.787L231.994 98.7149L240.144 102.496L241.036 106.395L237.852 114.311L218.495 119.037L195.826 123.645L162.07 131.592L161.696 131.893L162.137 132.547L177.36 133.925L183.855 134.279H199.774L229.447 136.524L237.215 141.605L241.8 147.867L241.036 152.711L229.065 158.737L213.019 154.956L175.45 145.977L162.587 142.787H160.805V143.85L171.502 154.366L191.242 172.089L215.82 195.011L217.094 200.682L213.91 205.172L210.599 204.699L188.949 188.394L180.544 181.069L161.696 165.118H160.422V166.772L164.752 173.152L187.803 207.771L188.949 218.405L187.294 221.832L181.308 223.959L174.813 222.777L161.187 203.754L147.305 182.486L136.098 163.345L134.745 164.2L128.075 235.42L125.019 239.082L117.887 241.8L111.902 237.31L108.718 229.984L111.902 215.452L115.722 196.547L118.779 181.541L121.58 162.873L123.291 156.636L123.14 156.219L121.773 156.449L107.699 175.752L86.304 204.699L69.3663 222.777L65.291 224.431L58.2867 220.768L58.9235 214.27L62.8713 208.48L86.304 178.705L100.44 160.155L109.551 149.507L109.462 147.967L108.959 147.924L46.6977 188.512L35.6182 189.93L30.7788 185.44L31.4156 178.115L33.7079 175.752L52.4285 162.873Z"/></svg>',chatgpt:'<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false"><rect width="48" height="48" fill="#0D0D0D"/><path transform="translate(24 24) scale(2.35) translate(-7.98 -8)" fill="#FFF" d="M12.9851 6.93777C13.1163 6.54364 13.1618 6.12607 13.1186 5.71295C13.0754 5.29983 12.9444 4.90072 12.7344 4.54231C12.4232 4.00021 11.9478 3.57101 11.3768 3.31664C10.8058 3.06227 10.1687 2.99589 9.55751 3.12706C9.28184 2.81639 8.943 2.56818 8.56362 2.39905C8.18425 2.22993 7.77314 2.14379 7.3578 2.1464C6.73292 2.1449 6.1237 2.34187 5.61797 2.70892C5.11225 3.07598 4.73616 3.59415 4.54391 4.18873C4.13684 4.27206 3.75225 4.44139 3.41591 4.68539C3.07957 4.92938 2.79924 5.24241 2.59368 5.60352C2.27994 6.14413 2.14602 6.77039 2.21123 7.39205C2.27644 8.01367 2.5374 8.59851 2.95649 9.06224C2.82527 9.45637 2.77975 9.87394 2.82297 10.2871C2.8662 10.7002 2.99718 11.0993 3.20713 11.4577C3.51841 11.9998 3.99385 12.4289 4.56484 12.6833C5.13584 12.9377 5.77289 13.0041 6.38407 12.8729C6.65975 13.1836 6.99862 13.4318 7.37796 13.601C7.75734 13.7701 8.16844 13.8562 8.58379 13.8536C9.20899 13.8552 9.81853 13.6582 10.3244 13.2909C10.8304 12.9236 11.2065 12.4051 11.3986 11.8101C11.8057 11.7268 12.1903 11.5575 12.5266 11.3135C12.8629 11.0695 13.1433 10.7564 13.3488 10.3953C13.6622 9.85477 13.7958 9.22866 13.7304 8.60726C13.6651 7.98587 13.4041 7.40129 12.9851 6.93777ZM8.58472 13.0883C8.0715 13.089 7.57441 12.9093 7.18031 12.5805C7.19808 12.5708 7.22925 12.5537 7.24956 12.5413L9.58061 11.1948C9.63911 11.1615 9.6877 11.1133 9.72136 11.055C9.75505 10.9967 9.77258 10.9305 9.77217 10.8632V7.57684L10.7575 8.14576C10.7626 8.14834 10.7671 8.15214 10.7704 8.15685C10.7738 8.16157 10.7759 8.16704 10.7766 8.17275V10.8943C10.7759 11.4756 10.5448 12.0329 10.1339 12.4441C9.72308 12.8554 9.16599 13.087 8.58472 13.0883ZM3.87091 11.075C3.61385 10.6309 3.5212 10.1105 3.60918 9.60485C3.62649 9.61524 3.65673 9.6337 3.67842 9.64617L6.00947 10.9926C6.06756 11.0266 6.13365 11.0445 6.20094 11.0445C6.2682 11.0445 6.33428 11.0266 6.39238 10.9926L9.23834 9.34936V10.4872C9.23867 10.493 9.23755 10.4988 9.23509 10.5041C9.23264 10.5094 9.22892 10.5139 9.22427 10.5174L6.86782 11.878C6.36379 12.1683 5.76516 12.2467 5.20333 12.0962C4.64148 11.9457 4.1623 11.5784 3.87091 11.075ZM3.25768 5.98617C3.51363 5.54141 3.91789 5.2009 4.39966 5.02421C4.39966 5.04429 4.39851 5.07985 4.39851 5.10452V7.79747C4.3981 7.86473 4.41561 7.93087 4.44924 7.98915C4.48287 8.04739 4.5314 8.09563 4.58984 8.1289L7.4358 9.77197L6.45054 10.3409C6.44568 10.3441 6.44009 10.346 6.43429 10.3465C6.4285 10.3471 6.42265 10.3462 6.41729 10.3439L4.06062 8.98216C3.55747 8.69077 3.19039 8.21176 3.03987 7.65013C2.88935 7.08853 2.96768 6.49014 3.25768 5.98617ZM11.3527 7.86994L8.50669 6.22667L9.49198 5.65799C9.49684 5.6548 9.50243 5.65283 9.50823 5.65231C9.51402 5.65178 9.51985 5.65272 9.5252 5.655L11.8819 7.01554C12.2429 7.2241 12.5371 7.53119 12.7299 7.90087C12.9228 8.27056 13.0063 8.68752 12.9707 9.10295C12.9351 9.51839 12.7819 9.91509 12.5291 10.2466C12.2762 10.5781 11.9341 10.8307 11.5428 10.9749C11.5428 10.9546 11.5428 10.919 11.5428 10.8943V8.20137C11.5434 8.13423 11.5261 8.06814 11.4926 8.0099C11.4592 7.95165 11.4109 7.90336 11.3527 7.86994ZM12.3333 6.394C12.316 6.38337 12.2858 6.36514 12.2641 6.3527L9.93303 5.00621C9.87493 4.97232 9.80887 4.95444 9.74158 4.95444C9.67432 4.95444 9.60824 4.97232 9.55014 5.00621L6.70418 6.64951V5.51167C6.70386 5.50585 6.70497 5.50005 6.70743 5.49479C6.70988 5.48952 6.7136 5.48492 6.71826 5.48144L9.0747 4.12203C9.4357 3.91387 9.84853 3.81281 10.2649 3.83068C10.6812 3.84856 11.0838 3.98462 11.4257 4.22296C11.7675 4.46129 12.0344 4.79204 12.1951 5.17652C12.3559 5.56099 12.4038 5.98327 12.3333 6.394ZM6.16851 8.42203L5.18299 7.85311C5.17784 7.85053 5.17336 7.84673 5.17002 7.84202C5.16668 7.8373 5.16455 7.83183 5.16385 7.82609V5.10452C5.16411 4.6877 5.28311 4.27956 5.5069 3.9279C5.73071 3.57623 6.05006 3.29559 6.42756 3.11883C6.80507 2.94206 7.22509 2.87649 7.63851 2.92977C8.05195 2.98306 8.44163 3.153 8.76197 3.41971C8.74421 3.42941 8.71327 3.44649 8.69272 3.45895L6.36168 4.80542C6.30317 4.83867 6.25462 4.8869 6.22093 4.94516C6.18727 5.0034 6.16974 5.06958 6.17012 5.13683L6.16851 8.42203ZM6.70371 7.26803L7.97126 6.53595L9.23878 7.26757V8.73127L7.97126 9.46292L6.70371 8.73127V7.26803Z"/></svg>'},S="team@northlight.ai";function T(e){const t=JSON.stringify(e.config).replace(/</g,"\\u003c");return`<!doctype html>
151
150
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
152
151
  <meta name="color-scheme" content="light dark">
153
152
  <title>${v(e.title)}</title><style nonce="${e.nonce}">${W}</style></head>
@@ -157,36 +156,34 @@ if(cfg.kind==='anthropic'){
157
156
  <footer class="foot"><span>Need help? Email <a href="mailto:${S}">${S}</a></span></footer>
158
157
  <script type="application/json" id="cfg">${t}<\/script>
159
158
  <script nonce="${e.nonce}">${X}<\/script>
160
- </body></html>`}o(T,"page");function A(e,t){return`<div class="head"><div class="logo">${Q[e]}</div><div><span class="eyebrow">AI subscription</span><h1>Connect your ${t} account</h1></div></div>`}o(A,"header");function f(e,t,r="",n=""){return`<li${n}><span class="n"><span>${e}</span>${s("check")}</span><div class="body"><span class="title">${t}</span>${r}</div></li>`}o(f,"step");function e1(e,t,r,n){return T({nonce:t,title:"Connect Claude",body:`<div class="card">
161
- ${A("claude","Claude")}
159
+ </body></html>`}o(T,"page");function A(e,t){return`<div class="head"><div class="logo">${Q[e]}</div><h1>${t}</h1></div>`}o(A,"header");function h(e,t,r="",n=""){return`<li${n}><span class="n"><span>${e}</span>${d("check")}</span><div class="body"><span class="title">${t}</span>${r}</div></li>`}o(h,"step");function e1(e,t,r,n){return T({nonce:t,title:"Sign in with Claude Code",body:`<div class="card">
160
+ ${A("claude","Sign in with Claude Code")}
162
161
  <ol class="steps">
163
- ${f(1,"Sign in to Claude in a new tab",`<div><a class="btn" href="${v(e.url)}" target="_blank" rel="noopener noreferrer">Open claude.ai${s("arrow")}</a></div>`," data-pre")}
164
- ${f(2,"Copy the code Claude shows you",""," data-pre")}
165
- ${f(3,"Paste it here",`<form id="paste" autocomplete="off">
162
+ ${h(1,"Sign in at claude.ai",`<div><a class="btn" href="${v(e.url)}" target="_blank" rel="noopener noreferrer">Open claude.ai${d("arrow")}</a></div>`," data-pre")}
163
+ ${h(2,"Copy the code it shows",""," data-pre")}
164
+ ${h(3,"Paste it here",`<form id="paste" autocomplete="off">
166
165
  <div class="field"><label for="code">Code from Claude</label>
167
166
  <input type="text" id="code" name="code" required spellcheck="false" autocapitalize="off" aria-describedby="error">
168
- <div id="error" class="err" role="alert">${s("alert")}<span id="error-text"></span></div></div>
169
- <button class="btn primary lg wide" type="submit">Connect Claude</button>
167
+ <div id="error" class="err" role="alert">${d("alert")}<span id="error-text"></span></div></div>
168
+ <button class="btn primary lg wide" type="submit">Continue</button>
170
169
  </form>`)}
171
170
  </ol>
172
- </div>`,config:{kind:"anthropic",base:`${h}/${encodeURIComponent(e.flow_id)}`,returnTo:r,handoff:n}})}o(e1,"anthropicPage");function t1(e,t){const r=Date.parse(e.expires_at)-t;return Math.max(0,Math.floor(Math.min(Number.isNaN(r)?$*1e3:r,$*1e3)/1e3))}o(t1,"codeSecondsLeft");function n1(e,t,r,n,a=Date.now()){const i=e.user_code??"";return T({nonce:t,title:"Connect ChatGPT",body:`<div class="card">
173
- ${A("chatgpt","ChatGPT")}
174
- <div class="alert" id="settings" role="alert">${s("warn")}
175
- <div class="text"><strong>Turn on device code sign-in first</strong>OpenAI refuses this sign-in unless device code authorization for Codex is on in ChatGPT's Security settings.</div>
176
- <div class="act"><a class="btn sm" href="${U}" target="_blank" rel="noopener noreferrer">Open settings${s("arrow")}</a></div></div>
171
+ </div>`,config:{kind:"anthropic",base:`${f}/${encodeURIComponent(e.flow_id)}`,returnTo:r,handoff:n}})}o(e1,"anthropicPage");function t1(e,t){const r=Date.parse(e.expires_at)-t;return Math.max(0,Math.floor(Math.min(Number.isNaN(r)?$*1e3:r,$*1e3)/1e3))}o(t1,"codeSecondsLeft");function n1(e,t,r,n,a=Date.now()){const i=e.user_code??"";return T({nonce:t,title:"Sign in with Codex",body:`<div class="card">
172
+ ${A("chatgpt","Sign in with Codex")}
177
173
  <ol class="steps" id="device">
178
- ${f(1,"Open the OpenAI device page",`<div><a class="btn" id="device-link" href="${v(e.url)}" target="_blank" rel="noopener noreferrer">${v(e.url.replace(/^https:\/\//,""))}${s("arrow")}</a></div>`)}
179
- ${f(2,"Enter this code",`<div class="codebox"><span class="code" id="user-code">${v(i)}</span>
174
+ ${h(1,"Turn on device code sign-in in ChatGPT settings",`<div><a class="btn" href="${G}" target="_blank" rel="noopener noreferrer">Open settings${d("arrow")}</a></div>`)}
175
+ ${h(2,"Open the OpenAI device page",`<div><a class="btn" id="device-link" href="${v(e.url)}" target="_blank" rel="noopener noreferrer">${v(e.url.replace(/^https:\/\//,""))}${d("arrow")}</a></div>`)}
176
+ ${h(3,"Enter this code",`<div class="codebox"><span class="code" id="user-code">${v(i)}</span>
180
177
  <span class="badge" id="expired-badge" hidden>Expired</span>
181
- <button class="btn sm" type="button" id="copy">${s("copy")}<span id="copy-label">Copy</span></button></div>`)}
182
- ${f(3,"Approve the sign-in",`<span class="small">When OpenAI shows an account email, check it's the account you want to use: approving connects that account.</span>`)}
178
+ <button class="btn sm" type="button" id="copy">${d("copy")}<span id="copy-label">Copy</span></button></div>`)}
179
+ ${h(4,"Approve the sign-in",`<span class="small">Make sure it's the account you want to use.</span>`)}
183
180
  </ol>
184
181
  <div class="wait" id="waiting">
185
182
  <svg class="spin" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M21 12a9 9 0 1 1-9-9"/></svg>
186
183
  <div class="msg" aria-live="polite"><b>Waiting for your approval at OpenAI</b><span>This page moves on by itself.</span></div>
187
- <div class="clock">${s("clock")}<span id="left" aria-hidden="true"></span><span class="sr" id="left-live" aria-live="polite"></span></div>
184
+ <div class="clock">${d("clock")}<span id="left" aria-hidden="true"></span><span class="sr" id="left-live" aria-live="polite"></span></div>
188
185
  </div>
189
- <div class="alert" id="expired" role="alert" hidden>${s("warn")}
186
+ <div class="alert" id="expired" role="alert" hidden>${d("warn")}
190
187
  <div class="text"><strong>The code expired before it was approved</strong>Codes last 15 minutes. Getting a new one starts the sign-in over.</div>
191
188
  <div class="act"><button class="btn primary sm" type="button" id="renew">Get a new code</button></div></div>
192
- </div>`,config:{kind:"openai",base:`${h}/${encodeURIComponent(e.flow_id)}`,returnTo:r,handoff:n,userCode:i,expiresAt:e.expires_at,remainingSeconds:t1(e,a)}})}o(n1,"openaiPage");async function r1(e,t,r,n){const a=y(r.searchParams,"handoff"),i=await _(n,a);if(z(i.jti))throw p();const l=y(r.searchParams,"return_to");let L;try{L=l===void 0?void 0:new URL(l).origin}catch{L=void 0}if(l===void 0||L!==new URL(n.issuer).origin)throw new d(400,"invalid_request","return_to must be an absolute URL on the directory origin","return_to");const u=y(r.searchParams,"vendor");if(u!=="anthropic"&&u!=="openai")throw new d(400,"invalid_request","vendor must be anthropic or openai","vendor");if(!R(i.jti,i.exp))throw p();let w;try{w=await I({provider:F(u),jti:i.jti})}catch(c){const M=c instanceof x?c.category:"runtime";m({level:"error",event:"vendor_signin.start_failed",error:c,fields:{vendor:u,...c instanceof x?c.logFields():{category:M}}}),t.writeHead(303,{Location:Z(l,"failed",M,c instanceof x?c.step:void 0),"Cache-Control":"no-store","Referrer-Policy":"no-referrer"}),t.end();return}const b=j(16).toString("base64"),O=u==="anthropic"?e1(w,b,l,a):n1(w,b,l,a);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store","Referrer-Policy":"no-referrer","X-Content-Type-Options":"nosniff","Content-Security-Policy":`default-src 'none'; script-src 'nonce-${b}'; style-src 'nonce-${b}'; connect-src 'self'; form-action 'none'; base-uri 'none'; frame-ancestors 'none'`}),t.end(O)}o(r1,"startPage");function g(e,t,r){const{category:n,step:a,fields:i}=V(t);m({level:"warn",event:"vendor_signin.failed",fields:{flow_id:t,message:r,...i}}),C(e,200,{status:"failed",reason:n,...a===void 0?{}:{step:a}})}o(g,"sendFailed");async function E(e,t,r){let n;try{n=await _(t,J(e))}catch(i){throw m({level:"warn",event:"vendor_signin.handoff_rejected",error:i,fields:{flow_id:r}}),i}const a=k(r);if(!a){if(z(n.jti))return!1;throw m({level:"warn",event:"vendor_signin.unauthorized",fields:{flow_id:r,reason:"unknown flow, handoff never started one"}}),p()}if(a.jti===void 0||a.jti!==n.jti)throw m({level:"warn",event:"vendor_signin.unauthorized",fields:{flow_id:r,reason:"handoff did not start this flow"}}),p();return!0}o(E,"followUpFlow");async function a1(e,t,r,n){if(!await E(e,r,n)){g(t,n,"flow_gone");return}const a=await q(e);try{await H(n,a.input),C(t,200,{status:"connected"})}catch(i){const l=k(n);if(l&&l.status!=="pending"){g(t,n,l.message??l.status);return}throw i}}o(a1,"submitCode");async function i1(e,t,r,n){if(!await E(e,r,n)){g(t,n,"flow_gone");return}const a=new AbortController;t.once("close",()=>a.abort());const i=await D(n,G,a.signal);if(!i){g(t,n,"flow_gone");return}if(i.status==="failed"){g(t,n,i.message??"failed");return}C(t,200,{status:i.status})}o(i1,"waitFlow");async function p1(e,t,r,n){const a=e.method??"GET";if(r.pathname===h&&a==="GET"){await r1(e,t,r,n);return}const i=r.pathname.slice(h.length+1).split("/");let l="";try{l=i[0]?decodeURIComponent(i[0]):""}catch{throw new d(404,"not_found","unknown operation")}if(l&&i.length===1&&a==="POST"){await a1(e,t,n,l);return}if(l&&i.length===2&&i[1]==="wait"&&a==="GET"){await i1(e,t,n,l);return}throw new d(404,"not_found","unknown operation")}o(p1,"handleVendorSignIn");export{h as VENDOR_SIGNIN_PATH,e1 as anthropicPage,v as escapeHtml,p1 as handleVendorSignIn,m1 as isVendorSignInPath,n1 as openaiPage};
189
+ </div>`,config:{kind:"openai",base:`${f}/${encodeURIComponent(e.flow_id)}`,returnTo:r,handoff:n,userCode:i,expiresAt:e.expires_at,remainingSeconds:t1(e,a)}})}o(n1,"openaiPage");async function r1(e,t,r,n){const a=y(r.searchParams,"handoff"),i=await _(n,a);if(z(i.jti))throw p();const l=y(r.searchParams,"return_to");let L;try{L=l===void 0?void 0:new URL(l).origin}catch{L=void 0}if(l===void 0||L!==new URL(n.issuer).origin)throw new s(400,"invalid_request","return_to must be an absolute URL on the directory origin","return_to");const u=y(r.searchParams,"vendor");if(u!=="anthropic"&&u!=="openai")throw new s(400,"invalid_request","vendor must be anthropic or openai","vendor");if(!R(i.jti,i.exp))throw p();let w;try{w=await D({provider:F(u),jti:i.jti})}catch(c){const M=c instanceof x?c.category:"runtime";m({level:"error",event:"vendor_signin.start_failed",error:c,fields:{vendor:u,...c instanceof x?c.logFields():{category:M}}}),t.writeHead(303,{Location:Z(l,"failed",M,c instanceof x?c.step:void 0),"Cache-Control":"no-store","Referrer-Policy":"no-referrer"}),t.end();return}const b=P(16).toString("base64"),j=u==="anthropic"?e1(w,b,l,a):n1(w,b,l,a);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store","Referrer-Policy":"no-referrer","X-Content-Type-Options":"nosniff","Content-Security-Policy":`default-src 'none'; script-src 'nonce-${b}'; style-src 'nonce-${b}'; connect-src 'self'; form-action 'none'; base-uri 'none'; frame-ancestors 'none'`}),t.end(j)}o(r1,"startPage");function g(e,t,r){const{category:n,step:a,fields:i}=V(t);m({level:"warn",event:"vendor_signin.failed",fields:{flow_id:t,message:r,...i}}),C(e,200,{status:"failed",reason:n,...a===void 0?{}:{step:a}})}o(g,"sendFailed");async function E(e,t,r){let n;try{n=await _(t,J(e))}catch(i){throw m({level:"warn",event:"vendor_signin.handoff_rejected",error:i,fields:{flow_id:r}}),i}const a=k(r);if(!a){if(z(n.jti))return!1;throw m({level:"warn",event:"vendor_signin.unauthorized",fields:{flow_id:r,reason:"unknown flow, handoff never started one"}}),p()}if(a.jti===void 0||a.jti!==n.jti)throw m({level:"warn",event:"vendor_signin.unauthorized",fields:{flow_id:r,reason:"handoff did not start this flow"}}),p();return!0}o(E,"followUpFlow");async function a1(e,t,r,n){if(!await E(e,r,n)){g(t,n,"flow_gone");return}const a=await q(e);try{await H(n,a.input),C(t,200,{status:"connected"})}catch(i){const l=k(n);if(l&&l.status!=="pending"){g(t,n,l.message??l.status);return}throw i}}o(a1,"submitCode");async function i1(e,t,r,n){if(!await E(e,r,n)){g(t,n,"flow_gone");return}const a=new AbortController;t.once("close",()=>a.abort());const i=await B(n,U,a.signal);if(!i){g(t,n,"flow_gone");return}if(i.status==="failed"){g(t,n,i.message??"failed");return}C(t,200,{status:i.status})}o(i1,"waitFlow");async function p1(e,t,r,n){const a=e.method??"GET";if(r.pathname===f&&a==="GET"){await r1(e,t,r,n);return}const i=r.pathname.slice(f.length+1).split("/");let l="";try{l=i[0]?decodeURIComponent(i[0]):""}catch{throw new s(404,"not_found","unknown operation")}if(l&&i.length===1&&a==="POST"){await a1(e,t,n,l);return}if(l&&i.length===2&&i[1]==="wait"&&a==="GET"){await i1(e,t,n,l);return}throw new s(404,"not_found","unknown operation")}o(p1,"handleVendorSignIn");export{f as VENDOR_SIGNIN_PATH,e1 as anthropicPage,v as escapeHtml,p1 as handleVendorSignIn,m1 as isVendorSignInPath,n1 as openaiPage};
@@ -1,17 +1,17 @@
1
- var $e=Object.defineProperty;var a=(n,s)=>$e(n,"name",{value:s,configurable:!0});import{startPeerOutbox as Ae}from"./peer/outbox.js";import{reportMachineStatus as Me}from"../core/peer/directory.js";import{createPeerRelay as Ne}from"./peer/relay-service.js";import{writeFileSync as Fe,readFileSync as Ge,rmSync as Oe,mkdirSync as ae,existsSync as P,chmodSync as Be}from"node:fs";import{createServer as se}from"node:http";import{dirname as He}from"node:path";import{envCrtrdTcp as je,envDocumentPort as qe}from"../shared/env.js";import{serveCanvasConversationStore as ze}from"../core/canvas/sessions.js";import{pollRunObservers as We}from"./runs/observer.js";import{randomBytes as ce}from"node:crypto";import{apiSocketPath as Ue,crtrHome as Ke}from"../core/canvas/paths.js";import{activeAppUsers as Je}from"../core/spaces/users.js";import{ensureAppSpace as Ve,ensureUserFiles as Qe}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as x}from"../launcher/spec.js";import{launcherRequest as C}from"../launcher/client.js";import{installLauncherEventSink as Ye}from"./launcher-events.js";import{initializeEmptyLayout as Xe,layoutNeedsMigration as Ze,socketDir as de}from"../core/layout.js";import{migrateLooseKeys as er}from"../core/layout-migrate/loose-keys.js";import{relocateProfileFolders as rr}from"../core/profiles/relocate.js";import{getNode as tr,listNodesForSupervision as le,listParkedResidentsWithWakeMail as nr,setFrozen as pe}from"../core/canvas/index.js";import{createApiServer as or}from"./api/server.js";import{createDocumentListener as ir}from"./api/document-listener.js";import{documentSecret as ar}from"./api/document-secret.js";import{createAppListener as sr}from"./api/app-listener.js";import{registerMachineEnvironment as cr}from"../core/environments.js";import{resolvePerson as dr,retireLocalPerson as lr,setPersonId as pr}from"../core/canvas/person.js";import{onRunEventAppended as mr}from"../core/runs/events.js";import{runNotices as fr}from"./run-notices.js";import{createGrantSync as ur,GRANT_SYNC_INTERVAL_S as wr}from"../core/grants/sync.js";import{runRemovalCascades as hr}from"../core/grants/remove.js";import{sweepSandboxes as vr}from"../core/grants/on-sync.js";import{rebuildCronExecutions as gr}from"./cron/run-socket.js";import{hasSyncedGrants as yr}from"../core/grants/mirror.js";import{readConfig as me}from"../core/config.js";import{reconcileUndeliveredTickets as Sr}from"./human/sweep.js";import{resetHandedOffDeliveries as _r}from"../core/canvas/deliveries.js";import{resetHandedOffDaemonActions as br}from"../core/canvas/daemon-actions.js";import{sweepReviews as kr}from"./review/sweep.js";import{pidfilePath as U}from"./pidfile.js";import{rendererWarning as Pr}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as Er}from"./supervise-cadence.js";import{createResumeDetector as Rr}from"./resume-detector.js";import{setFatalFaultAnnouncer as Ir}from"../core/canvas/recovery.js";import{BrokerSupervisionReconciler as xr}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as Dr}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Tr}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as Cr}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as Lr}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as $r}from"./reconcilers/delivery-lane.js";import{ActionLaneReconciler as Ar}from"./reconcilers/action-lane.js";import{endLiveExecution as Mr,migrateLegacyExecutionIdentities as Nr}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as Fr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as Gr}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as Or}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as Br}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as Hr}from"./reconcilers/bash-deadline.js";import{FaultRetryBackstopReconciler as jr}from"./reconcilers/fault-retry-backstop.js";import{StructuredRequestReconciler as qr}from"./reconcilers/structured-request-lane.js";import{reconcileStructuredRequestSidecars as zr}from"./structured-requests/boot.js";import{captureLivenessSnapshot as fe,capturePidCommand as Wr,captureTeardownSnapshot as ue,isPidAlive as Ur,isAnyPidAlive as we,killProcessTreePids as he}from"../core/canvas/pid.js";import{bindFleet as Kr,boundFleet as Jr}from"../core/runtime/fleet.js";import{bindDaemonControl as Vr,clearDaemonControl as Qr}from"./control.js";import{execDaemon as Yr,spawnDaemon as Xr}from"./manage.js";import{reconcileAndMigrateBoot as Zr}from"../core/canvas/boot.js";import{resolveInstallId as et}from"../core/canvas/install-id.js";import{setInstallId as rt}from"../core/runtime/nodes.js";import{claimDaemonOwnership as ve,daemonOwnershipClaimed as tt,releaseDaemonOwnership as ge}from"../core/canvas/daemon-owner.js";import{canvasDatabaseUrl as nt,closeAllDbs as K,openDb as ye,withCanvasWrite as ot}from"../core/canvas/db.js";import{importSqliteCanvasIfPresent as it}from"../core/canvas/import-sqlite.js";import{ensurePostgres as at,ensurePostgresHealthy as st,stopPostgres as ct,withPostgresStartLock as dt}from"./postgres/index.js";import{brokerSignalBus as J}from"./broker-signals/bus.js";import{brokerSignalStreams as lt}from"./api/handlers/broker-signals.js";import{reconcilePackages as pt}from"../core/graph/package-reconcile.js";import{startRepoSync as mt}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as ft,reapStaleSpares as ut}from"../core/runtime/warm-pool.js";import{DaemonFleet as wt}from"./fleet.js";import{BOOT_MIGRATIONS as ht}from"./boot-migrations.js";import{emitEvent as m}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as vt}from"../core/events/source.js";import{activateCanvasImport as gt,MigrationBlockedError as yt,runForcedCanvasImport as St}from"../migrations/activation.js";import{convertLegacyProviderStore as _t,convertLegacyScopedStore as bt}from"../core/scoped-state/migrate.js";import{userScopeRoot as kt}from"../core/scope.js";import{secretsDir as Pt}from"../core/layout.js";function V(n,s){return n.includes(` --canvas-home ${s} `)}a(V,"brokerCommandDeclaresCanvasHome");function Q(n){return/ --epoch (\S+) /.exec(n)?.[1]??null}a(Q,"brokerCommandEpoch");const Et=5e3,Se=150;async function Rt(n){const s=fe();if(s===null)throw m({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const l=Ke(),w=[];for(const[c,f]of s.processes){const S=f.command;if(f.zombie||!S.includes("broker-cli.js")||!V(S,l)||Q(S)===n)continue;const k=S.trim().split(/\s+/).at(-1)??"";k===""||k.endsWith("broker-cli.js")||w.push({pid:c,nodeId:k})}let d=0;const t=[];for(const c of w){const f=Wr(c.pid);if(f===null||!f.includes("broker-cli.js")||!V(f,l)||Q(f)===n||f.trim().split(/\s+/).at(-1)!==c.nodeId)continue;const S=ue(c.pid,null);if(!S.reused){try{process.platform==="linux"&&P(x)?await C({operation:"stop",pid:c.pid}):process.kill(c.pid,"SIGTERM")}catch{continue}d++,t.push({pid:c.pid,snap:S})}}const g=Date.now()+Et;for(;Date.now()<g&&t.some(c=>we(c.snap.tree.length>0?c.snap.tree:[c.pid]));)await new Promise(c=>setTimeout(c,Se));let h=0;for(const c of t){const f=c.snap.tree.length>0?c.snap.tree:[c.pid];we(f)&&(process.platform==="linux"&&P(x)?await C({operation:"stop",pid:c.pid}):he(f,"SIGKILL",c.snap.identities),h++)}h>0&&await new Promise(c=>setTimeout(c,Se));const u=fe();if(u===null)throw m({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const i=[];for(const[c,f]of u.processes){const S=f.command;f.zombie||!S.includes("broker-cli.js")||V(S,l)&&Q(S)!==n&&i.push(c)}if(i.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${i.join(", ")}`);m({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:w.length,sigtermed:d,sigkilled:h}})}a(Rt,"reapPriorEpochBrokers");const It=5e3;async function xt(n){const s=Array.from(n.entries());if(s.length===0)return;for(const[t]of s){const g=(await tr(t))?.status;(g==="active"||g==="idle")&&await pe(t,new Date().toISOString())}const l=s.map(([,t])=>({pid:t.pid,snap:ue(t.pid,null),exited:t.handle.exited}));for(const t of l)if(!t.snap.reused)try{process.platform==="linux"&&P(x)?await C({operation:"stop",pid:t.pid}):process.kill(t.pid,"SIGTERM")}catch{}const w=new Promise(t=>{setTimeout(t,It).unref()});await Promise.allSettled(l.map(t=>Promise.race([t.exited.then(()=>{}),w])));const d=[];for(const t of l)Ur(t.pid)&&(process.platform==="linux"&&P(x)?await C({operation:"stop",pid:t.pid}):he(t.snap.tree.length>0?t.snap.tree:[t.pid],"SIGKILL",t.snap.identities),d.push(t));await Promise.all(d.map(t=>t.exited));for(const[t]of s)await Mr(t,{reason:"daemon-teardown"});m({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:l.length,sigkilled:d.length}})}a(xt,"teardownFleet");function _e(){ae(He(U()),{recursive:!0}),Fe(U(),String(process.pid),"utf8")}a(_e,"writePidfile");function be(n){return typeof n=="object"&&n!==null&&n.code==="ENOENT"}a(be,"isMissingPathError");function ke(n){const s=U();let l;try{l=Ge(s,"utf8")}catch(w){if(be(w))return;throw w}if(l.trim()!==String(n))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${n})`);try{Oe(s)}catch(w){if(be(w))return;throw w}}a(ke,"removeOwnedPidfileMirror");const Dt={acceptsDetachedWork:a(()=>!0,"acceptsDetachedWork"),registerDetached:a(n=>{n.catch(()=>{})},"registerDetached")},B=new xr;Ir(n=>B.handleFatalFault(n,!1));const Tt=new Dr,Ct=new Tr,Lt=new Cr,$t=new Lr,At=new $r,Mt=new Ar,Nt=new Gr,Ft=new Or,Gt=new Br,Ot=new Hr,Bt=new jr,Ht=new qr;async function jt(n=Date.now(),s=Dt){const l=Jr(),w=await B.runFleetPreamble(l);let d,t;try{const h=await le();d=h.filter(i=>i.status==="active"||i.status==="idle"),t=h.filter(i=>i.status==="done"||i.status==="canceled"||i.status==="dead");const u=new Set(t.map(i=>i.node_id));t.push(...(await nr()).filter(i=>!u.has(i.node_id)))}catch(h){m({level:"error",event:"canvas.node_list.failed",error:h});return}await B.run(n,{rows:d,fleet:l,lifecycle:s}),await Tt.run(n,{rows:d});const g=await Ct.run(n,{rows:[...d,...t],fleet:l});await Lt.run(n),await Ht.run(n),await $t.run(n,{lifecycle:s}),await At.run(n,{lifecycle:s}),await Mt.run(n,{lifecycle:s}),await Nt.run(n,{lifecycle:s}),await Ft.run(n,{lifecycle:s,fleet:l}),Gt.run(n,{lifecycle:s}),await We(),Bt.run(n,{fleet:l,lifecycle:s}),await Ot.run(n,{rows:d}),B.warnIfSaturated({fleet:l,lifecycle:s,thresholds:w,frozen:g})}a(jt,"superviseTick");async function qt(n){ae(de(),{recursive:!0,mode:493}),process.platform==="linux"&&Be(de(),493);const s=Ue();if(P(s))throw new Error(`layout refusal cannot bind occupied socket: ${s}`);const l=se((u,i)=>{if(u.method==="GET"&&u.url==="/healthz"){i.writeHead(200,{"content-type":"application/json; charset=utf-8"}),i.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}i.writeHead(503,{"content-type":"application/json; charset=utf-8"}),i.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((u,i)=>{l.once("error",i),l.listen(s,()=>{l.off("error",i),u()})});let w;const d=n.tcp??je();if(d){const u=/^(.*):(\d+)$/.exec(d);if(!u||Number(u[2])>65535)throw new Error(`invalid refusal TCP address: ${d}`);const i=se(l.listeners("request")[0]);await new Promise((c,f)=>{i.once("error",f),i.listen(Number(u[2]),u[1],()=>{i.off("error",f),c()})}),w=i}_e();let t;const g=a(()=>(t??=(async()=>{l.closeAllConnections(),w?.closeAllConnections(),await Promise.all([l,w].filter(u=>u!==void 0).map(u=>new Promise((i,c)=>u.close(f=>f?c(f):i())))),ke(process.pid),process.off("SIGINT",h),process.off("SIGTERM",h)})(),t),"cleanup"),h=a(()=>{g().then(()=>process.exit(0),u=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(u)}
2
- `),process.exit(1)})},"onSignal");return process.on("SIGINT",h),process.on("SIGTERM",h),g}a(qt,"serveLayoutRefusal");async function zt(n={}){if(Ze())return qt(n);Xe();const s=a(r=>{process.stderr.write(`[crtrd] ${r}
3
- `)},"logPostgres"),l=!!process.env.CRTR_TEST_PG_URL,{database:w,ownership:d}=l?{database:{url:await nt()},ownership:await ve(ce(16).toString("hex"))}:await dt(async()=>({database:await at({log:s,startLockHeld:!0}),ownership:await ve(ce(16).toString("hex"))}));if(!d.claimed){if(d.reason==="incumbent_alive")process.stderr.write(`[crtrd] already running (pid ${d.incumbentPid??"?"})
4
- `);else{const r=[d.incumbentPid!==void 0?`pid ${d.incumbentPid}`:void 0,d.verdict!==void 0?`verdict ${d.verdict}`:void 0].filter(y=>y!==void 0),e=r.length>0?` (${r.join(", ")})`:"";process.stderr.write(`[crtrd] claim lost: ${d.reason}${e}
5
- `),d.reason==="own_identity_indeterminate"&&process.stderr.write("[crtrd] cannot read its own process identity. crouter needs /proc on Linux, or the `ps` command elsewhere (Debian/Ubuntu: apt-get install procps).\n"),(d.reason==="own_identity_indeterminate"||d.reason==="incumbent_malformed")&&(process.exitCode=1)}return async()=>{}}const t=d.claim;let g=null,h=null,u="";try{await Rt(t.token),bt({kind:"user",root:kt()});for(const e of rr())process.stderr.write(`[crtrd] ${e}
6
- `);if(process.platform==="darwin"){const{readConfig:e,updateConfig:y}=await import("../core/config.js");if(e("user").paths?.user_files===void 0){const{homedir:o}=await import("node:os");y("user",p=>{p.paths??={},p.paths.user_files??=o()})}}await _t(Pt());for(const e of er())process.stderr.write(`[crtrd] ${e}
7
- `);await ye(),await it(w.url,s),await J.listen(w.url);const r=await ot(async e=>await pt(e));for(const e of r.conflicts)process.stderr.write(`[crtrd] plugin documents not reconciled: ${e.message}
1
+ var Ae=Object.defineProperty;var i=(n,s)=>Ae(n,"name",{value:s,configurable:!0});import{startPeerOutbox as Me}from"./peer/outbox.js";import{reportMachineStatus as Ne}from"../core/peer/directory.js";import{createPeerRelay as Fe}from"./peer/relay-service.js";import{writeFileSync as Ge,readFileSync as Oe,rmSync as Be,mkdirSync as se,existsSync as k,chmodSync as He}from"node:fs";import{createServer as ce}from"node:http";import{dirname as je}from"node:path";import{envCrtrdTcp as qe,envDocumentPort as ze}from"../shared/env.js";import{serveCanvasConversationStore as We}from"../core/canvas/sessions.js";import{pollRunObservers as Ue}from"./runs/observer.js";import{randomBytes as de}from"node:crypto";import{apiSocketPath as Ke,crtrHome as Je}from"../core/canvas/paths.js";import{activeAppUsers as Ve}from"../core/spaces/users.js";import{ensureAppSpace as Qe,ensureUserFiles as Ye}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as x}from"../launcher/spec.js";import{launcherRequest as C}from"../launcher/client.js";import{installLauncherEventSink as Xe}from"./launcher-events.js";import{initializeEmptyLayout as Ze,layoutNeedsMigration as er,socketDir as le}from"../core/layout.js";import{migrateLooseKeys as rr}from"../core/layout-migrate/loose-keys.js";import{relocateProfileFolders as tr}from"../core/profiles/relocate.js";import{getNode as nr,listNodesForSupervision as pe,listParkedResidentsWithWakeMail as or,setFrozen as me}from"../core/canvas/index.js";import{createApiServer as ir}from"./api/server.js";import{createDocumentListener as ar}from"./api/document-listener.js";import{documentSecret as sr}from"./api/document-secret.js";import{createAppListener as cr}from"./api/app-listener.js";import{registerMachineEnvironment as dr}from"../core/environments.js";import{resolvePerson as lr,retireLocalPerson as pr,setPersonId as mr}from"../core/canvas/person.js";import{backfillNodeApps as fr,runPermissionsBoot as ur}from"../core/permissions/boot.js";import{onRunEventAppended as wr}from"../core/runs/events.js";import{runNotices as hr}from"./run-notices.js";import{createGrantSync as vr,GRANT_SYNC_INTERVAL_S as gr}from"../core/grants/sync.js";import{runRemovalCascades as yr}from"../core/grants/remove.js";import{sweepSandboxes as Sr}from"../core/grants/on-sync.js";import{rebuildCronExecutions as _r}from"./cron/run-socket.js";import{hasSyncedGrants as br}from"../core/grants/mirror.js";import{readConfig as fe}from"../core/config.js";import{reconcileUndeliveredTickets as kr}from"./human/sweep.js";import{resetHandedOffDeliveries as Pr}from"../core/canvas/deliveries.js";import{resetHandedOffDaemonActions as Er}from"../core/canvas/daemon-actions.js";import{sweepReviews as Rr}from"./review/sweep.js";import{pidfilePath as K}from"./pidfile.js";import{rendererWarning as Ir}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as xr}from"./supervise-cadence.js";import{createResumeDetector as Dr}from"./resume-detector.js";import{setFatalFaultAnnouncer as Tr}from"../core/canvas/recovery.js";import{BrokerSupervisionReconciler as Cr}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as Lr}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as $r}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as Ar}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as Mr}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as Nr}from"./reconcilers/delivery-lane.js";import{ActionLaneReconciler as Fr}from"./reconcilers/action-lane.js";import{endLiveExecution as Gr,migrateLegacyExecutionIdentities as Or}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as Br}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as Hr}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as jr}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as qr}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as zr}from"./reconcilers/bash-deadline.js";import{FaultRetryBackstopReconciler as Wr}from"./reconcilers/fault-retry-backstop.js";import{StructuredRequestReconciler as Ur}from"./reconcilers/structured-request-lane.js";import{reconcileStructuredRequestSidecars as Kr}from"./structured-requests/boot.js";import{captureLivenessSnapshot as ue,capturePidCommand as Jr,captureTeardownSnapshot as we,isPidAlive as Vr,isAnyPidAlive as he,killProcessTreePids as ve}from"../core/canvas/pid.js";import{bindFleet as Qr,boundFleet as Yr}from"../core/runtime/fleet.js";import{bindDaemonControl as Xr,clearDaemonControl as Zr}from"./control.js";import{execDaemon as et,spawnDaemon as rt}from"./manage.js";import{reconcileAndMigrateBoot as tt}from"../core/canvas/boot.js";import{resolveInstallId as nt}from"../core/canvas/install-id.js";import{setInstallId as ot}from"../core/runtime/nodes.js";import{claimDaemonOwnership as ge,daemonOwnershipClaimed as it,releaseDaemonOwnership as ye}from"../core/canvas/daemon-owner.js";import{canvasDatabaseUrl as at,closeAllDbs as J,openDb as Se,withCanvasWrite as st}from"../core/canvas/db.js";import{importSqliteCanvasIfPresent as ct}from"../core/canvas/import-sqlite.js";import{ensurePostgres as dt,ensurePostgresHealthy as lt,stopPostgres as pt,withPostgresStartLock as mt}from"./postgres/index.js";import{brokerSignalBus as V}from"./broker-signals/bus.js";import{brokerSignalStreams as ft}from"./api/handlers/broker-signals.js";import{reconcilePackages as ut}from"../core/graph/package-reconcile.js";import{startRepoSync as wt}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as ht,reapStaleSpares as vt}from"../core/runtime/warm-pool.js";import{DaemonFleet as gt}from"./fleet.js";import{BOOT_MIGRATIONS as yt}from"./boot-migrations.js";import{emitEvent as m}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as St}from"../core/events/source.js";import{activateCanvasImport as _t,MigrationBlockedError as bt,runForcedCanvasImport as kt}from"../migrations/activation.js";import{convertLegacyProviderStore as Pt,convertLegacyScopedStore as Et}from"../core/scoped-state/migrate.js";import{userScopeRoot as Rt}from"../core/scope.js";import{secretsDir as It}from"../core/layout.js";function Q(n,s){return n.includes(` --canvas-home ${s} `)}i(Q,"brokerCommandDeclaresCanvasHome");function Y(n){return/ --epoch (\S+) /.exec(n)?.[1]??null}i(Y,"brokerCommandEpoch");const xt=5e3,_e=150;async function Dt(n){const s=ue();if(s===null)throw m({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const l=Je(),w=[];for(const[a,u]of s.processes){const y=u.command;if(u.zombie||!y.includes("broker-cli.js")||!Q(y,l)||Y(y)===n)continue;const P=y.trim().split(/\s+/).at(-1)??"";P===""||P.endsWith("broker-cli.js")||w.push({pid:a,nodeId:P})}let d=0;const t=[];for(const a of w){const u=Jr(a.pid);if(u===null||!u.includes("broker-cli.js")||!Q(u,l)||Y(u)===n||u.trim().split(/\s+/).at(-1)!==a.nodeId)continue;const y=we(a.pid,null);if(!y.reused){try{process.platform==="linux"&&k(x)?await C({operation:"stop",pid:a.pid}):process.kill(a.pid,"SIGTERM")}catch{continue}d++,t.push({pid:a.pid,snap:y})}}const g=Date.now()+xt;for(;Date.now()<g&&t.some(a=>he(a.snap.tree.length>0?a.snap.tree:[a.pid]));)await new Promise(a=>setTimeout(a,_e));let h=0;for(const a of t){const u=a.snap.tree.length>0?a.snap.tree:[a.pid];he(u)&&(process.platform==="linux"&&k(x)?await C({operation:"stop",pid:a.pid}):ve(u,"SIGKILL",a.snap.identities),h++)}h>0&&await new Promise(a=>setTimeout(a,_e));const f=ue();if(f===null)throw m({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const c=[];for(const[a,u]of f.processes){const y=u.command;u.zombie||!y.includes("broker-cli.js")||Q(y,l)&&Y(y)!==n&&c.push(a)}if(c.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${c.join(", ")}`);m({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:w.length,sigtermed:d,sigkilled:h}})}i(Dt,"reapPriorEpochBrokers");const Tt=5e3;async function Ct(n){const s=Array.from(n.entries());if(s.length===0)return;for(const[t]of s){const g=(await nr(t))?.status;(g==="active"||g==="idle")&&await me(t,new Date().toISOString())}const l=s.map(([,t])=>({pid:t.pid,snap:we(t.pid,null),exited:t.handle.exited}));for(const t of l)if(!t.snap.reused)try{process.platform==="linux"&&k(x)?await C({operation:"stop",pid:t.pid}):process.kill(t.pid,"SIGTERM")}catch{}const w=new Promise(t=>{setTimeout(t,Tt).unref()});await Promise.allSettled(l.map(t=>Promise.race([t.exited.then(()=>{}),w])));const d=[];for(const t of l)Vr(t.pid)&&(process.platform==="linux"&&k(x)?await C({operation:"stop",pid:t.pid}):ve(t.snap.tree.length>0?t.snap.tree:[t.pid],"SIGKILL",t.snap.identities),d.push(t));await Promise.all(d.map(t=>t.exited));for(const[t]of s)await Gr(t,{reason:"daemon-teardown"});m({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:l.length,sigkilled:d.length}})}i(Ct,"teardownFleet");function be(){se(je(K()),{recursive:!0}),Ge(K(),String(process.pid),"utf8")}i(be,"writePidfile");function ke(n){return typeof n=="object"&&n!==null&&n.code==="ENOENT"}i(ke,"isMissingPathError");function Pe(n){const s=K();let l;try{l=Oe(s,"utf8")}catch(w){if(ke(w))return;throw w}if(l.trim()!==String(n))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${n})`);try{Be(s)}catch(w){if(ke(w))return;throw w}}i(Pe,"removeOwnedPidfileMirror");const Lt={acceptsDetachedWork:i(()=>!0,"acceptsDetachedWork"),registerDetached:i(n=>{n.catch(()=>{})},"registerDetached")},H=new Cr;Tr(n=>H.handleFatalFault(n,!1));const $t=new Lr,At=new $r,Mt=new Ar,Nt=new Mr,Ft=new Nr,Gt=new Fr,Ot=new Hr,Bt=new jr,Ht=new qr,jt=new zr,qt=new Wr,zt=new Ur;async function Wt(n=Date.now(),s=Lt){const l=Yr(),w=await H.runFleetPreamble(l);let d,t;try{const h=await pe();d=h.filter(c=>c.status==="active"||c.status==="idle"),t=h.filter(c=>c.status==="done"||c.status==="canceled"||c.status==="dead");const f=new Set(t.map(c=>c.node_id));t.push(...(await or()).filter(c=>!f.has(c.node_id)))}catch(h){m({level:"error",event:"canvas.node_list.failed",error:h});return}await H.run(n,{rows:d,fleet:l,lifecycle:s}),await $t.run(n,{rows:d});const g=await At.run(n,{rows:[...d,...t],fleet:l});await Mt.run(n),await zt.run(n),await Nt.run(n,{lifecycle:s}),await Ft.run(n,{lifecycle:s}),await Gt.run(n,{lifecycle:s}),await Ot.run(n,{lifecycle:s}),await Bt.run(n,{lifecycle:s,fleet:l}),Ht.run(n,{lifecycle:s}),await Ue(),qt.run(n,{fleet:l,lifecycle:s}),await jt.run(n,{rows:d}),H.warnIfSaturated({fleet:l,lifecycle:s,thresholds:w,frozen:g})}i(Wt,"superviseTick");async function Ut(n){se(le(),{recursive:!0,mode:493}),process.platform==="linux"&&He(le(),493);const s=Ke();if(k(s))throw new Error(`layout refusal cannot bind occupied socket: ${s}`);const l=ce((f,c)=>{if(f.method==="GET"&&f.url==="/healthz"){c.writeHead(200,{"content-type":"application/json; charset=utf-8"}),c.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}c.writeHead(503,{"content-type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((f,c)=>{l.once("error",c),l.listen(s,()=>{l.off("error",c),f()})});let w;const d=n.tcp??qe();if(d){const f=/^(.*):(\d+)$/.exec(d);if(!f||Number(f[2])>65535)throw new Error(`invalid refusal TCP address: ${d}`);const c=ce(l.listeners("request")[0]);await new Promise((a,u)=>{c.once("error",u),c.listen(Number(f[2]),f[1],()=>{c.off("error",u),a()})}),w=c}be();let t;const g=i(()=>(t??=(async()=>{l.closeAllConnections(),w?.closeAllConnections(),await Promise.all([l,w].filter(f=>f!==void 0).map(f=>new Promise((c,a)=>f.close(u=>u?a(u):c())))),Pe(process.pid),process.off("SIGINT",h),process.off("SIGTERM",h)})(),t),"cleanup"),h=i(()=>{g().then(()=>process.exit(0),f=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(f)}
2
+ `),process.exit(1)})},"onSignal");return process.on("SIGINT",h),process.on("SIGTERM",h),g}i(Ut,"serveLayoutRefusal");async function Kt(n={}){if(er())return Ut(n);Ze();const s=i(r=>{process.stderr.write(`[crtrd] ${r}
3
+ `)},"logPostgres"),l=!!process.env.CRTR_TEST_PG_URL,{database:w,ownership:d}=l?{database:{url:await at()},ownership:await ge(de(16).toString("hex"))}:await mt(async()=>({database:await dt({log:s,startLockHeld:!0}),ownership:await ge(de(16).toString("hex"))}));if(!d.claimed){if(d.reason==="incumbent_alive")process.stderr.write(`[crtrd] already running (pid ${d.incumbentPid??"?"})
4
+ `);else{const r=[d.incumbentPid!==void 0?`pid ${d.incumbentPid}`:void 0,d.verdict!==void 0?`verdict ${d.verdict}`:void 0].filter(S=>S!==void 0),e=r.length>0?` (${r.join(", ")})`:"";process.stderr.write(`[crtrd] claim lost: ${d.reason}${e}
5
+ `),d.reason==="own_identity_indeterminate"&&process.stderr.write("[crtrd] cannot read its own process identity. crouter needs /proc on Linux, or the `ps` command elsewhere (Debian/Ubuntu: apt-get install procps).\n"),(d.reason==="own_identity_indeterminate"||d.reason==="incumbent_malformed")&&(process.exitCode=1)}return async()=>{}}const t=d.claim;let g=null,h=null,f=null,c="";try{await Dt(t.token),Et({kind:"user",root:Rt()});for(const e of tr())process.stderr.write(`[crtrd] ${e}
6
+ `);if(process.platform==="darwin"){const{readConfig:e,updateConfig:S}=await import("../core/config.js");if(e("user").paths?.user_files===void 0){const{homedir:o}=await import("node:os");S("user",p=>{p.paths??={},p.paths.user_files??=o()})}}await Pt(It());for(const e of rr())process.stderr.write(`[crtrd] ${e}
7
+ `);await Se(),await ct(w.url,s),await V.listen(w.url);const r=await st(async e=>(await fr(e),await ut(e)));for(const e of r.conflicts)process.stderr.write(`[crtrd] plugin documents not reconciled: ${e.message}
8
8
  `);for(const e of r.invalid)process.stderr.write(`[crtrd] package file is not a document: ${e.path}: ${e.error}
9
9
  `);for(const e of r.quarantined)process.stderr.write(`[crtrd] plugin "${e.name}" has a damaged ${e.file} (${e.reason}); ${e.movedTo!==void 0?`moved to ${e.movedTo}`:"left in place and skipped"}
10
10
  `);for(const e of r.kinds.refused)process.stderr.write(`[crtrd] plugin "${e.plugin}" kind ${e.kind} not registered: ${e.message}
11
11
  `);for(const e of r.kinds.invalid)process.stderr.write(`[crtrd] plugin "${e.plugin}" declares invalid object kinds or scopes; no kinds registered and no app token: ${e.error}
12
- `);u=await et(),rt(u),g=await dr(),g!==null&&(pr(g.id),h=await lr()),process.platform==="linux"&&P(x)&&(Ye(),await C({operation:"users.sync",users:await Je()})),await Fr(t.token)}catch(r){await J.close();try{const{released:e}=await ge(t);if(!e)throw new Error("daemon ownership claim was not released");await K()}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}let i=!0,c,f=Promise.resolve(),S=!1,k,D;const N=new Set;let H=!1,Y=!1,E,F,j,X=!1,G,L,$,A,q;const Pe=Rr();let R,v={phase:"initializing",message:"daemon startup is running the canvas import and normal services are unavailable",blockerPaths:[]},T="initial startup activation",Ee=null;function Re(){return v.phase==="ready"?null:{phase:v.phase,message:v.message,blockerPaths:v.blockerPaths}}a(Re,"startupBlock");function b(r){N.add(r),r.finally(()=>{N.delete(r)}).catch(()=>{})}a(b,"registerDetached");const Z={acceptsDetachedWork:a(()=>i,"acceptsDetachedWork"),registerDetached:b};await mt(Z,ye);async function Ie(){try{i=!1,lt.close(),await J.close(),k!==void 0&&(clearInterval(k),k=void 0),$!==void 0&&(clearInterval($),$=void 0),q?.(),q=void 0;let r;do r=f,await r;while(r!==f);for(;N.size>0;)await Promise.allSettled([...N]);if(D!==void 0&&(await xt(D),await D.exitsSettled(),D.dispose()),j!==void 0&&await j.close(),F!==void 0&&!X&&(X=!0,await F.close()),A!==void 0){const e=A;A=void 0,await e.stop()}if(L!==void 0){const e=L;L=void 0,await e.close()}if(G!==void 0){const e=G;G=void 0,await e.close()}if(H||(ke(process.pid),H=!0),H&&!Y){const{released:e}=await ge(t);if(!e)throw new Error("daemon ownership claim was not released");Y=!0,await K()}}finally{Qr(),process.off("SIGINT",te),process.off("SIGTERM",ne),process.off("exit",oe)}}a(Ie,"cleanupAttempt");const O=1e3;let ee=!1;function xe(){return ee?{graceMs:O}:(ee=!0,_.fresh(()=>{m({level:"info",event:"daemon.handover.armed",fields:{pid:process.pid,grace_ms:O}})}),setTimeout(()=>{De()},O),{graceMs:O})}a(xe,"requestHandover");async function De(){try{await I()}catch(r){const e=r instanceof Error?r.stack??r.message:String(r);process.stderr.write(`[crtrd] handover cleanup failed:
12
+ `);c=await nt(),ot(c),g=await lr(),g!==null&&(mr(g.id),h=await pr(),f=await ur()),process.platform==="linux"&&k(x)&&(Xe(),await C({operation:"users.sync",users:await Ve()})),await Br(t.token)}catch(r){await V.close();try{const{released:e}=await ye(t);if(!e)throw new Error("daemon ownership claim was not released");await J()}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}let a=!0,u,y=Promise.resolve(),P=!1,N,D;const F=new Set;let j=!1,X=!1,E,G,q,Z=!1,O,L,$,A,z;const Ee=Dr();let R,v={phase:"initializing",message:"daemon startup is running the canvas import and normal services are unavailable",blockerPaths:[]},T="initial startup activation",Re=null;function Ie(){return v.phase==="ready"?null:{phase:v.phase,message:v.message,blockerPaths:v.blockerPaths}}i(Ie,"startupBlock");function b(r){F.add(r),r.finally(()=>{F.delete(r)}).catch(()=>{})}i(b,"registerDetached");const ee={acceptsDetachedWork:i(()=>a,"acceptsDetachedWork"),registerDetached:b};await wt(ee,Se);async function xe(){try{a=!1,ft.close(),await V.close(),N!==void 0&&(clearInterval(N),N=void 0),$!==void 0&&(clearInterval($),$=void 0),z?.(),z=void 0;let r;do r=y,await r;while(r!==y);for(;F.size>0;)await Promise.allSettled([...F]);if(D!==void 0&&(await Ct(D),await D.exitsSettled(),D.dispose()),q!==void 0&&await q.close(),G!==void 0&&!Z&&(Z=!0,await G.close()),A!==void 0){const e=A;A=void 0,await e.stop()}if(L!==void 0){const e=L;L=void 0,await e.close()}if(O!==void 0){const e=O;O=void 0,await e.close()}if(j||(Pe(process.pid),j=!0),j&&!X){const{released:e}=await ye(t);if(!e)throw new Error("daemon ownership claim was not released");X=!0,await J()}}finally{Zr(),process.off("SIGINT",ne),process.off("SIGTERM",oe),process.off("exit",ie)}}i(xe,"cleanupAttempt");const B=1e3;let re=!1;function De(){return re?{graceMs:B}:(re=!0,_.fresh(()=>{m({level:"info",event:"daemon.handover.armed",fields:{pid:process.pid,grace_ms:B}})}),setTimeout(()=>{Te()},B),{graceMs:B})}i(De,"requestHandover");async function Te(){try{await I()}catch(r){const e=r instanceof Error?r.stack??r.message:String(r);process.stderr.write(`[crtrd] handover cleanup failed:
13
13
  ${e}
14
- `),process.exit(1)}try{process.platform==="linux"&&P(x)&&(await C({operation:"daemon.handover"}),process.exit(0)),process.pid===1&&await Yr();const r=await Xr({waitForJoinLock:!0});_.fresh(()=>{m({level:"info",event:"daemon.handover.completed",fields:{predecessor_pid:process.pid,successor_pid:r.pid??r.existing_pid??null,spawned:r.started}})})}catch(r){_.fresh(()=>{m({level:"error",event:"daemon.handover.successor_failed",error:r})});const e=r instanceof Error?r.message:String(r);process.stderr.write(`[crtrd] handover successor failed to start: ${e}
15
- `),process.exit(1)}process.exit(0)}a(De,"performHandover");function I(){if(E!==void 0)return E;const r=Ie();return E=r,r.then(()=>{E===r&&(E=void 0)},()=>{E===r&&(E=void 0)}),r}a(I,"requestCleanup");async function re(r){try{await I(),await ct({claimed:a(async()=>{try{return await tt()}finally{await K()}},"claimed")}),process.exit(0)}catch(e){process.exitCode=1;const y=e instanceof Error?e.stack??`${e.name}: ${e.message}`:String(e);process.stderr.write(`[crtrd] ${r} cleanup failed:
16
- ${y}
17
- `),process.exit(1)}}a(re,"handleSignal");function te(){re("SIGINT")}a(te,"onSigint");function ne(){re("SIGTERM")}a(ne,"onSigterm");function oe(){I().catch(()=>{})}a(oe,"onExit");async function z(r){i&&(f=f.then(r).then(()=>{},e=>{_.fresh(()=>{m({level:"error",event:"daemon.lane_job.failed",error:e})})}))}a(z,"enqueue");async function ie(){!i||S||(Pe.check()&&R&&(m({level:"info",event:"daemon.resume.detected"}),b(R().catch(()=>{}))),S=!0,await z(async()=>{if(S=!1,!!i)try{l||await st({log:s}),await jt(Date.now(),Z)}catch(r){_.fresh(()=>{m({level:"error",event:"daemon.tick.failed",error:r})})}}))}a(ie,"enqueueTick");let M=null;async function Te(){if(M!==null)throw{status:500,code:"admission_failed",message:`daemon admission previously failed: ${M instanceof Error?M.message:String(M)}`};if(v.phase==="ready")return{admitted:!1,already_admitted:!0,startup_phase:"ready"};if(v.phase!=="prepared"&&v.phase!=="recovering")throw{status:409,code:"not_prepared",message:v.message};const r=v.phase==="prepared";try{return await W(),v={phase:"ready",message:"",blockerPaths:[]},r?{admitted:!0,already_admitted:!1,startup_phase:"ready"}:{admitted:!1,already_admitted:!0,startup_phase:"ready"}}catch(e){throw M=e,{status:500,code:"admission_failed",message:`daemon admission failed: ${e instanceof Error?e.message:String(e)}`}}}a(Te,"admitStartup");async function Ce(r){if(T!==null)throw{status:409,code:"migration_in_progress",message:`the canvas import is already running (${T})`};T="repair";try{const e=await St({dryRun:r.dryRun});if(r.dryRun||e.pending||v.phase!=="blocked")return{result:e,resumed:!1};if(n.prepare)return v={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]},{result:e,resumed:!1};try{return await W(),v={phase:"ready",message:"",blockerPaths:[]},{result:e,resumed:!0}}catch(y){const o=y instanceof Error?y.message:String(y);return setTimeout(()=>{I().catch(()=>{})},1e3),{result:e,resumed:!1,resumeError:o}}}finally{T=null}}a(Ce,"repairMigrations");async function Le(){c=n.intervalMs??Er;const r=t.token;D=new wt({epoch:r,enqueue:z}),Kr(D),v={phase:"recovering",message:"daemon startup recovery is running and normal services are unavailable",blockerPaths:[]},_.fresh(()=>{m({level:"info",event:"daemon.started",fields:{pid:process.pid,interval_ms:c}})});const e=u;_.fresh(()=>{m({level:"info",event:"daemon.install_id.resolved",fields:{install_id:e}})});const y=await cr(e);if(_.fresh(()=>{m({level:"info",event:"daemon.environment.registered",fields:{environment_id:y.environmentId,created:y.created}})}),_.fresh(()=>{let o;try{o=Pr()}catch{return}o!==null&&m({level:"warn",event:"daemon.startup.warning",fields:{stage:"termrender",warning:o.slice(0,2048)}})}),await _.fresh(async()=>{await kr(),await Sr(),await _r(Date.now()),await br(Date.now())}),await _.fresh(async()=>{const{reconcile:o,migrated:p}=await Zr(Nr);o.changed&&m({level:"info",event:"daemon.boot_change.reconciled",fields:{cleared_count:o.cleared.length,same_boot_proven:o.sameBootProven}}),p.length>0&&m({level:"info",event:"daemon.pid_identity.migrated",fields:{migrated_count:p.length}})}),await _.fresh(async()=>{for(const o of await le())o.status!=="active"||o.pi_pid!=null||o.frozen_at!=null||o.respawn_not_before!=null||(await pe(o.node_id,new Date().toISOString()),m({level:"warn",event:"daemon.startup.launch_debt_recorded",node_id:o.node_id}))}),await _.fresh(async()=>{await zr();for(const o of ht){const p=o.apply();p.changed&&m({level:"info",event:"daemon.boot_migration.applied",fields:{migration:o.id,...p.summary}})}}),b(gr()),R){const o=a(()=>{b(R().catch(()=>{})),b(Me().then(p=>A?.observe(p)).then(()=>{},p=>{m({level:"warn",event:"daemon.peer.status_failed",error:p})}))},"refresh");b(hr().catch(()=>{})),b(vr().then(({completion:p})=>p).catch(p=>{m({level:"error",event:"daemon.grants.sweep_failed",error:p})})),o(),$=setInterval(o,wr*1e3),$.unref(),q=Ae({joined:!0,register:b})}await z(async()=>{await ut(),await ft()}),k=setInterval(()=>{ie().catch(o=>m({level:"error",event:"daemon.tick.failed",error:o}))},c),await ie()}a(Le,"completeStartup");function W(){return Ee??=Le().catch(r=>{throw v={phase:"initializing",message:"daemon startup recovery failed and normal services are unavailable",blockerPaths:[]},r})}a(W,"resumeStartup");try{process.on("SIGINT",te),process.on("SIGTERM",ne),process.on("exit",oe),vt(),g!==null&&m({level:"info",event:"daemon.person.resolved",fields:{person_id:g.id,source:g.source}}),h!==null&&m({level:"info",event:"daemon.person.retired",fields:{person_id:h.person,joined_from:h.joinedFrom,retired:h.retired,columns:h.columns}}),G=await ze();const r=t.token;Vr({epoch:r,requestHandover:xe,registerDetached:b,startupBlock:Re,admitStartup:Te,repairMigrations:Ce}),_e(),F=or({tcp:n.tcp}),await F.ready;const e=qe()??me("user").document_port,y=ir(e,ar());try{await y.ready,j=y}catch(p){m({level:"warn",event:"daemon.document_listener.bind_failed",fields:{port:e,error:p instanceof Error?p.message:String(p)}})}const o=me("user").runtime;o?.issuer&&(R=ur(o.issuer,b),o.unsandboxed===!0&&(A=Ne({syncGrants:R})),mr(p=>fr().appended(p))),o?.unsandboxed===!0&&o.listener!==void 0&&m({level:"warn",event:"daemon.app_listener.refused_unsandboxed",fields:{reason:"runtime.unsandboxed is set; runtime.listener is ignored"}}),o!==void 0&&o.listener!==void 0&&o.unsandboxed!==!0&&(L=await sr(o,async()=>await yr(o.issuer.replace(/\/$/,"")),R),await L.ready);try{await gt()}catch(p){if(T=null,p instanceof yt)return v={phase:"blocked",message:p.message,blockerPaths:p.blockerPaths},I;throw p}process.platform==="linux"&&P(x)&&(Qe(),await Ve("app:terminal"));try{n.prepare?v={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]}:(await W(),v={phase:"ready",message:"",blockerPaths:[]})}finally{T=null}return I}catch(r){try{await I()}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}}a(zt,"runDaemon");var Po=zt;export{V as brokerCommandDeclaresCanvasHome,Q as brokerCommandEpoch,Po as default,zt as runDaemon,jt as superviseTick,xt as teardownFleet};
14
+ `),process.exit(1)}try{process.platform==="linux"&&k(x)&&(await C({operation:"daemon.handover"}),process.exit(0)),process.pid===1&&await et();const r=await rt({waitForJoinLock:!0});_.fresh(()=>{m({level:"info",event:"daemon.handover.completed",fields:{predecessor_pid:process.pid,successor_pid:r.pid??r.existing_pid??null,spawned:r.started}})})}catch(r){_.fresh(()=>{m({level:"error",event:"daemon.handover.successor_failed",error:r})});const e=r instanceof Error?r.message:String(r);process.stderr.write(`[crtrd] handover successor failed to start: ${e}
15
+ `),process.exit(1)}process.exit(0)}i(Te,"performHandover");function I(){if(E!==void 0)return E;const r=xe();return E=r,r.then(()=>{E===r&&(E=void 0)},()=>{E===r&&(E=void 0)}),r}i(I,"requestCleanup");async function te(r){try{await I(),await pt({claimed:i(async()=>{try{return await it()}finally{await J()}},"claimed")}),process.exit(0)}catch(e){process.exitCode=1;const S=e instanceof Error?e.stack??`${e.name}: ${e.message}`:String(e);process.stderr.write(`[crtrd] ${r} cleanup failed:
16
+ ${S}
17
+ `),process.exit(1)}}i(te,"handleSignal");function ne(){te("SIGINT")}i(ne,"onSigint");function oe(){te("SIGTERM")}i(oe,"onSigterm");function ie(){I().catch(()=>{})}i(ie,"onExit");async function W(r){a&&(y=y.then(r).then(()=>{},e=>{_.fresh(()=>{m({level:"error",event:"daemon.lane_job.failed",error:e})})}))}i(W,"enqueue");async function ae(){!a||P||(Ee.check()&&R&&(m({level:"info",event:"daemon.resume.detected"}),b(R().catch(()=>{}))),P=!0,await W(async()=>{if(P=!1,!!a)try{l||await lt({log:s}),await Wt(Date.now(),ee)}catch(r){_.fresh(()=>{m({level:"error",event:"daemon.tick.failed",error:r})})}}))}i(ae,"enqueueTick");let M=null;async function Ce(){if(M!==null)throw{status:500,code:"admission_failed",message:`daemon admission previously failed: ${M instanceof Error?M.message:String(M)}`};if(v.phase==="ready")return{admitted:!1,already_admitted:!0,startup_phase:"ready"};if(v.phase!=="prepared"&&v.phase!=="recovering")throw{status:409,code:"not_prepared",message:v.message};const r=v.phase==="prepared";try{return await U(),v={phase:"ready",message:"",blockerPaths:[]},r?{admitted:!0,already_admitted:!1,startup_phase:"ready"}:{admitted:!1,already_admitted:!0,startup_phase:"ready"}}catch(e){throw M=e,{status:500,code:"admission_failed",message:`daemon admission failed: ${e instanceof Error?e.message:String(e)}`}}}i(Ce,"admitStartup");async function Le(r){if(T!==null)throw{status:409,code:"migration_in_progress",message:`the canvas import is already running (${T})`};T="repair";try{const e=await kt({dryRun:r.dryRun});if(r.dryRun||e.pending||v.phase!=="blocked")return{result:e,resumed:!1};if(n.prepare)return v={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]},{result:e,resumed:!1};try{return await U(),v={phase:"ready",message:"",blockerPaths:[]},{result:e,resumed:!0}}catch(S){const o=S instanceof Error?S.message:String(S);return setTimeout(()=>{I().catch(()=>{})},1e3),{result:e,resumed:!1,resumeError:o}}}finally{T=null}}i(Le,"repairMigrations");async function $e(){u=n.intervalMs??xr;const r=t.token;D=new gt({epoch:r,enqueue:W}),Qr(D),v={phase:"recovering",message:"daemon startup recovery is running and normal services are unavailable",blockerPaths:[]},_.fresh(()=>{m({level:"info",event:"daemon.started",fields:{pid:process.pid,interval_ms:u}})});const e=c;_.fresh(()=>{m({level:"info",event:"daemon.install_id.resolved",fields:{install_id:e}})});const S=await dr(e);if(_.fresh(()=>{m({level:"info",event:"daemon.environment.registered",fields:{environment_id:S.environmentId,created:S.created}})}),_.fresh(()=>{let o;try{o=Ir()}catch{return}o!==null&&m({level:"warn",event:"daemon.startup.warning",fields:{stage:"termrender",warning:o.slice(0,2048)}})}),await _.fresh(async()=>{await Rr(),await kr(),await Pr(Date.now()),await Er(Date.now())}),await _.fresh(async()=>{const{reconcile:o,migrated:p}=await tt(Or);o.changed&&m({level:"info",event:"daemon.boot_change.reconciled",fields:{cleared_count:o.cleared.length,same_boot_proven:o.sameBootProven}}),p.length>0&&m({level:"info",event:"daemon.pid_identity.migrated",fields:{migrated_count:p.length}})}),await _.fresh(async()=>{for(const o of await pe())o.status!=="active"||o.pi_pid!=null||o.frozen_at!=null||o.respawn_not_before!=null||(await me(o.node_id,new Date().toISOString()),m({level:"warn",event:"daemon.startup.launch_debt_recorded",node_id:o.node_id}))}),await _.fresh(async()=>{await Kr();for(const o of yt){const p=o.apply();p.changed&&m({level:"info",event:"daemon.boot_migration.applied",fields:{migration:o.id,...p.summary}})}}),b(_r()),R){const o=i(()=>{b(R().catch(()=>{})),b(Ne().then(p=>A?.observe(p)).then(()=>{},p=>{m({level:"warn",event:"daemon.peer.status_failed",error:p})}))},"refresh");b(yr().catch(()=>{})),b(Sr().then(({completion:p})=>p).catch(p=>{m({level:"error",event:"daemon.grants.sweep_failed",error:p})})),o(),$=setInterval(o,gr*1e3),$.unref(),z=Me({joined:!0,register:b})}await W(async()=>{await vt(),await ht()}),N=setInterval(()=>{ae().catch(o=>m({level:"error",event:"daemon.tick.failed",error:o}))},u),await ae()}i($e,"completeStartup");function U(){return Re??=$e().catch(r=>{throw v={phase:"initializing",message:"daemon startup recovery failed and normal services are unavailable",blockerPaths:[]},r})}i(U,"resumeStartup");try{process.on("SIGINT",ne),process.on("SIGTERM",oe),process.on("exit",ie),St(),g!==null&&m({level:"info",event:"daemon.person.resolved",fields:{person_id:g.id,source:g.source}}),f!==null&&m({level:"info",event:"daemon.permissions.boot",fields:{...f}}),h!==null&&m({level:"info",event:"daemon.person.retired",fields:{person_id:h.person,joined_from:h.joinedFrom,retired:h.retired,columns:h.columns}}),O=await We();const r=t.token;Xr({epoch:r,requestHandover:De,registerDetached:b,startupBlock:Ie,admitStartup:Ce,repairMigrations:Le}),be(),G=ir({tcp:n.tcp}),await G.ready;const e=ze()??fe("user").document_port,S=ar(e,sr());try{await S.ready,q=S}catch(p){m({level:"warn",event:"daemon.document_listener.bind_failed",fields:{port:e,error:p instanceof Error?p.message:String(p)}})}const o=fe("user").runtime;o?.issuer&&(R=vr(o.issuer,b),o.unsandboxed===!0&&(A=Fe({syncGrants:R})),wr(p=>hr().appended(p))),o?.unsandboxed===!0&&o.listener!==void 0&&m({level:"warn",event:"daemon.app_listener.refused_unsandboxed",fields:{reason:"runtime.unsandboxed is set; runtime.listener is ignored"}}),o!==void 0&&o.listener!==void 0&&o.unsandboxed!==!0&&(L=await cr(o,async()=>await br(o.issuer.replace(/\/$/,"")),R),await L.ready);try{await _t()}catch(p){if(T=null,p instanceof bt)return v={phase:"blocked",message:p.message,blockerPaths:p.blockerPaths},I;throw p}process.platform==="linux"&&k(x)&&(Ye(),await Qe("app:terminal"));try{n.prepare?v={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]}:(await U(),v={phase:"ready",message:"",blockerPaths:[]})}finally{T=null}return I}catch(r){try{await I()}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}}i(Kt,"runDaemon");var xo=Kt;export{Q as brokerCommandDeclaresCanvasHome,Y as brokerCommandEpoch,xo as default,Kt as runDaemon,Wt as superviseTick,Ct as teardownFleet};
@@ -1,8 +1,8 @@
1
- var g=Object.defineProperty;var c=(e,t)=>g(e,"name",{value:t,configurable:!0});import{randomUUID as D}from"node:crypto";import{claimPushDelivery as h,duePushDeliveries as j,messageBodyForDelivery as N,pushDeliveryClaimIsCurrent as O,settleDelivery as d}from"../../core/canvas/deliveries.js";import{deliveryBackoffMs as f}from"../../core/canvas/delivery-contract.js";import{openDb as p}from"../../core/canvas/db.js";import{pushLineFor as u}from"../../core/graph/custom.js";import{postReceiverUrl as b}from"../../core/graph/receiver-url.js";import{emitEvent as l}from"../../core/events/emit.js";import{operationIdContext as m}from"../../core/events/operation-id.js";import{runDelivery as w,DELIVERY_TIMEOUT_MS as E}from"../delivery/run-delivery.js";const v=D();async function o(e,t,a){await d(e.deliveryId,e.attempts,t,{state:"permanent_failed",failure:{kind:"spawn_error",message:a}},Date.now())}c(o,"failed");async function T(e,t){const a=await(await p()).prepare(`SELECT o.type, o.name, c.receiver_json, c.payload_json, m.object_id, i.external_id AS app,
1
+ var g=Object.defineProperty;var p=(e,t)=>g(e,"name",{value:t,configurable:!0});import{randomUUID as D}from"node:crypto";import{claimPushDelivery as h,duePushDeliveries as j,messageBodyForDelivery as N,pushDeliveryClaimIsCurrent as O,settleDelivery as d}from"../../core/canvas/deliveries.js";import{deliveryBackoffMs as f}from"../../core/canvas/delivery-contract.js";import{openDb as c}from"../../core/canvas/db.js";import{pushLineFor as u}from"../../core/graph/custom.js";import{postReceiverUrl as b}from"../../core/graph/receiver-url.js";import{emitEvent as l}from"../../core/events/emit.js";import{operationIdContext as m}from"../../core/events/operation-id.js";import{runDelivery as w,DELIVERY_TIMEOUT_MS as E}from"../delivery/run-delivery.js";const v=D();async function o(e,t,a){await d(e.deliveryId,e.attempts,t,{state:"permanent_failed",failure:{kind:"spawn_error",message:a}},Date.now())}p(o,"failed");async function T(e,t){const a=await(await c()).prepare(`SELECT o.type, o.name, c.receiver_json, c.payload_json, m.object_id, i.external_id AS app,
2
2
  d.message_id, owner.type AS owner_type, parent.external_id AS parent_app
3
3
  FROM deliveries d JOIN objects o ON o.id = d.destination_id
4
4
  JOIN custom_objects c ON c.object = o.id JOIN messages m ON m.message_id = d.message_id
5
5
  LEFT JOIN objects owner ON owner.id = o.owner
6
6
  LEFT JOIN identities i ON i.object = o.owner AND i.scheme = 'app'
7
7
  LEFT JOIN identities parent ON parent.object = owner.owner AND parent.scheme = 'app'
8
- WHERE d.delivery_id = ?`).get(e.deliveryId);if(!a||!a.receiver_json){await o(e,t,`delivery ${e.deliveryId} has no supported receiver`);return}const i=JSON.parse(a.receiver_json);if(!await O(e,t)){await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now());return}if(typeof i=="object"&&typeof i.url=="string"&&a.type!=="action"){const n=await u(await p(),e.deliveryId);if(!n){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}try{const r=await b(i.url,JSON.stringify(n),{"Content-Type":"application/json","X-Crtr-Delivery":e.deliveryId,"X-Crtr-Event":a.message_id},E);r>=200&&r<300?await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now()):r>=300&&r<400?await o(e,t,`url receiver returned HTTP ${r}; redirects are not followed \u2014 register the final URL`):r>=400&&r<500&&r!==408&&r!==429?await o(e,t,`url receiver returned HTTP ${r}`):await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:`url receiver returned HTTP ${r}`}},Date.now())}catch(r){await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:String(r)}},Date.now())}return}if(typeof i!="object"||!Array.isArray(i.argv)||typeof i.cwd!="string"){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}if(a.type==="action"){if(typeof i.name!="string"||!a.object_id){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}const n=await N(e.deliveryId);if(n===null){await o(e,t,`delivery ${e.deliveryId} has no message body`);return}const{push:r,...y}=n,I={...y,action:{name:i.name,payload:a.payload_json===null?null:JSON.parse(a.payload_json)}};await w({argv:i.argv,cwd:i.cwd,document:I,attempt:e.attempts,nodeId:a.object_id,...a.app?{app:a.app}:{}},async _=>{await d(e.deliveryId,e.attempts,t,_,Date.now())});return}const s=await u(await p(),e.deliveryId);if(!s){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}await w({argv:i.argv,cwd:i.cwd,document:s,attempt:e.attempts,app:a.app??a.parent_app??"app:terminal",custom:{deliveryId:e.deliveryId,messageId:a.message_id}},async n=>{await d(e.deliveryId,e.attempts,t,n,Date.now())})}c(T,"deliverExternal");class P{static{c(this,"DeliveryLaneReconciler")}async run(t,a){if(!a.lifecycle.acceptsDetachedWork())return;let i;try{i=await j(t)}catch(s){m.fresh(()=>l({level:"error",event:"delivery.scan_failed",error:s}));return}for(const s of i)try{const n=await h(s.deliveryId,t,v);if(n===null)continue;a.lifecycle.registerDetached(T(n,v).catch(r=>{m.fresh(()=>l({level:"error",event:"delivery.failed",error:r,fields:{delivery_id:n.deliveryId}}))}))}catch(n){m.fresh(()=>l({level:"error",event:"delivery.claim_failed",error:n,fields:{delivery_id:s.deliveryId}}))}}}export{P as DeliveryLaneReconciler,v as deliveryDaemonInstanceId};
8
+ WHERE d.delivery_id = ?`).get(e.deliveryId);if(!a||!a.receiver_json){await o(e,t,`delivery ${e.deliveryId} has no supported receiver`);return}const i=JSON.parse(a.receiver_json);if(!await O(e,t)){await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now());return}if(typeof i=="object"&&typeof i.url=="string"&&a.type!=="action"){const n=await u(await c(),e.deliveryId);if(!n){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}try{const r=await b(i.url,JSON.stringify(n),{"Content-Type":"application/json","X-Crtr-Delivery":e.deliveryId,"X-Crtr-Event":a.message_id},E);r>=200&&r<300?await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now()):r>=300&&r<400?await o(e,t,`url receiver returned HTTP ${r}; redirects are not followed \u2014 register the final URL`):r>=400&&r<500&&r!==408&&r!==429?await o(e,t,`url receiver returned HTTP ${r}`):await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:`url receiver returned HTTP ${r}`}},Date.now())}catch(r){await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:String(r)}},Date.now())}return}if(typeof i!="object"||!Array.isArray(i.argv)||typeof i.cwd!="string"){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}if(a.type==="action"){if(typeof i.name!="string"||!a.object_id){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}const n=await N(e.deliveryId);if(n===null){await o(e,t,`delivery ${e.deliveryId} has no message body`);return}const{push:r,...y}=n,I={...y,action:{name:i.name,payload:a.payload_json===null?null:JSON.parse(a.payload_json)}};await w({argv:i.argv,cwd:i.cwd,document:I,attempt:e.attempts,nodeId:a.object_id,...a.app??a.parent_app?{app:a.app??a.parent_app}:{}},async _=>{await d(e.deliveryId,e.attempts,t,_,Date.now())});return}const s=await u(await c(),e.deliveryId);if(!s){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}await w({argv:i.argv,cwd:i.cwd,document:s,attempt:e.attempts,app:a.app??a.parent_app??"app:terminal",custom:{deliveryId:e.deliveryId,messageId:a.message_id}},async n=>{await d(e.deliveryId,e.attempts,t,n,Date.now())})}p(T,"deliverExternal");class P{static{p(this,"DeliveryLaneReconciler")}async run(t,a){if(!a.lifecycle.acceptsDetachedWork())return;let i;try{i=await j(t)}catch(s){m.fresh(()=>l({level:"error",event:"delivery.scan_failed",error:s}));return}for(const s of i)try{const n=await h(s.deliveryId,t,v);if(n===null)continue;a.lifecycle.registerDetached(T(n,v).catch(r=>{m.fresh(()=>l({level:"error",event:"delivery.failed",error:r,fields:{delivery_id:n.deliveryId}}))}))}catch(n){m.fresh(()=>l({level:"error",event:"delivery.claim_failed",error:n,fields:{delivery_id:s.deliveryId}}))}}}export{P as DeliveryLaneReconciler,v as deliveryDaemonInstanceId};
@@ -1,4 +1,4 @@
1
- import type { Privacy, RuleSpec } from '../../core/graph/types.js';
1
+ import { type Privacy, type RuleSpec } from '../../core/graph/types.js';
2
2
  export type DocumentKind = 'knowledge' | 'preference' | 'report';
3
3
  export interface DocumentFields {
4
4
  kind: DocumentKind;
@@ -1,2 +1,2 @@
1
- var c=Object.defineProperty;var r=(e,t)=>c(e,"name",{value:t,configurable:!0});import{rulesFromFrontmatter as u}from"../../core/graph/rules.js";const f=new Set(["kind","privacy","unlisted","lint-ignore","extensions","when-and-why-to-read","short-form","rationale","surfaces","gate","slash","origin","last-updated","name","namespace"]),p=["public","friends","private"],s=r(e=>typeof e=="string"&&e.trim()!==""?e.trim():null,"str");function m(e){for(const t of e.split(`
2
- `)){const i=t.trim().replace(/^#+\s*/,"").replace(/^[-*]\s+/,"").trim();if(i!==""&&i!=="---")return i}return""}r(m,"firstLine");function g(e,t,i){const n=e??{},o=Object.keys(n).filter(a=>!f.has(a));let l=i.kind??"knowledge";i.kind===void 0&&n.kind!==void 0&&(n.kind==="knowledge"||n.kind==="preference"?l=n.kind:o.push("kind"));const d=typeof n.privacy=="string"&&p.includes(n.privacy)?n.privacy:i.missingPrivacy;return{kind:l,privacy:d,preview:s(n["when-and-why-to-read"])?.replace(/\s+/g," ")??m(t),summary:s(n["short-form"]),whyItExists:s(n.rationale),unlisted:n.unlisted===!0,lintIgnore:n["lint-ignore"]??null,extensions:n.extensions??null,rules:u(n),dropped:o}}r(g,"documentFields");function h(e,t){return e.map(i=>({...i,if:i.if===void 0?t:{all:[i.if,t]}}))}r(h,"andIntoRules");export{h as andIntoRules,g as documentFields,m as firstLine};
1
+ var u=Object.defineProperty;var r=(n,t)=>u(n,"name",{value:t,configurable:!0});import{rulesFromFrontmatter as f}from"../../core/graph/rules.js";import{readLegacyPrivacy as p}from"../../core/graph/types.js";const m=new Set(["kind","privacy","unlisted","lint-ignore","extensions","when-and-why-to-read","short-form","rationale","surfaces","gate","slash","origin","last-updated","name","namespace"]),g=["public","private"],o=r(n=>typeof n=="string"&&n.trim()!==""?n.trim():null,"str");function y(n){for(const t of n.split(`
2
+ `)){const i=t.trim().replace(/^#+\s*/,"").replace(/^[-*]\s+/,"").trim();if(i!==""&&i!=="---")return i}return""}r(y,"firstLine");function v(n,t,i){const e=n??{},l=Object.keys(e).filter(c=>!m.has(c));let d=i.kind??"knowledge";i.kind===void 0&&e.kind!==void 0&&(e.kind==="knowledge"||e.kind==="preference"?d=e.kind:l.push("kind"));const s=p(e.privacy),a=typeof s=="string"&&g.includes(s)?s:i.missingPrivacy;return{kind:d,privacy:a,preview:o(e["when-and-why-to-read"])?.replace(/\s+/g," ")??y(t),summary:o(e["short-form"]),whyItExists:o(e.rationale),unlisted:e.unlisted===!0,lintIgnore:e["lint-ignore"]??null,extensions:e.extensions??null,rules:f(e),dropped:l}}r(v,"documentFields");function x(n,t){return n.map(i=>({...i,if:i.if===void 0?t:{all:[i.if,t]}}))}r(x,"andIntoRules");export{x as andIntoRules,v as documentFields,y as firstLine};
@@ -19,7 +19,7 @@ A non-2xx answer is thrown as an `APIError`, never returned as bytes. A bad `ran
19
19
 
20
20
  ## Read the person's public documents
21
21
 
22
- `runtime.memory` is a read-only view of the `knowledge` and `preference` documents the person owns (`memory` and the `/v1/memory` routes are the API's names for this). An app reads the person's `public` documents with `memory.list` and `memory.get`, and needs no scope to do it. Without more, it never sees a `friends` or `private` document and cannot tell one from a document that does not exist: both answer `404 not_found`. The optional scope [`crtr:memory:read_private:user`](#private-memory) adds `private`. The list is what the app's agents can read about the person, so an app can show the person exactly which of their documents it draws on.
22
+ `runtime.memory` is a read-only view of the `knowledge` and `preference` documents the person owns (`memory` and the `/v1/memory` routes are the API's names for this). An app reads the person's `public` documents with `memory.list` and `memory.get`, and needs no scope to do it. Without more, it never sees a `private` document and cannot tell one from a document that does not exist: both answer `404 not_found`. The optional scope [`crtr:memory:read_private:user`](#private-memory) adds `private`. The list is what the app's agents can read about the person, so an app can show the person exactly which of their documents it draws on.
23
23
 
24
24
  ```ts
25
25
  const page = await runtime.memory.list({store: 'user'});
@@ -56,13 +56,13 @@ for await (const item of runtime.memory.listAll({store: 'user', path: 'work'}))
56
56
 
57
57
  - `body` is the current markdown as stored; `[[links]]` are not resolved. A body over 1 MiB is cut to its longest whole-character prefix of at most 1 MiB, with `truncated: true`; `size` is always the full length in UTF-8 bytes.
58
58
  - `grantee` is `app:<id>` of the app whose agent wrote the first revision, or `null` when the person wrote it.
59
- - An absent or deleted name, a `friends` name, and a `private` name without `crtr:memory:read_private:user` reject with `NotFoundError` (`code: 'not_found'`); a malformed field rejects with `BadRequestError`.
59
+ - An absent or deleted name, and a `private` name without `crtr:memory:read_private:user` reject with `NotFoundError` (`code: 'not_found'`); a malformed field rejects with `BadRequestError`.
60
60
 
61
61
  ## Private memory
62
62
 
63
63
  `crtr:memory:read_private:user` is an [optional permission](/docs/guides/grant-changes#optional-permissions) that lets your app read the person's `private` documents. Declare it, then let the person switch it on from your app (sign-in request or `permissionUrl`).
64
64
 
65
- - **Read-only, and never `friends`.** With the scope `memory.list` and `memory.get` return `public` and `private` documents; a `friends` document still reads as absent, and the scope writes nothing. Each private document arrives with `privacy: 'private'`.
65
+ - **Read-only.** With the scope `memory.list` and `memory.get` return `public` and `private` documents, and the scope writes nothing. Each private document arrives with `privacy: 'private'`.
66
66
  - **Both server reads and runs.** Your server's `memory` calls see private documents while the grant holds the scope. A run sees them only if it was started with the scope: `runs.start` `scopes` must cover `crtr:memory:read_private:user` (name it, or name `crtr:memory:manage:user` if the grant holds that) (a run with no `scopes` list gets what the grant holds), and the start is refused `403 scope_missing` while the grant lacks it. Add the scope to the runs that need it only while `resolved_scopes` holds it.
67
67
  - **The person can turn it off at any time.** Reads then stop returning private documents at once, including from a run that is still live. That run keeps what it already read in its context, so restart the runs that used it when the permission turns off (`watchGrants` tells you).
68
68
  - **Never show a private detail to anyone but the owner**, unless the owner asked your app to. A visitor, a guest or another user must not see a fact, quote or summary taken from a private document.
@@ -46,7 +46,7 @@ A visitor chatting with B's clone starts an app run on **B's runtime and B's AI
46
46
 
47
47
  A run your app starts is **your app's agent**, not a continuation of another app's agent. It starts in `/apps/<app>/files`, uses the person's AI under `crtr:llm`, and reaches your app's own documents (owned by `app:<your app>`) without a `crtr:memory` scope. Other people's or apps' data is not shared merely because the app has many users. The grant's resolved permissions govern access to the person's files (`crtr:files:<access>:user:<dir>`), the person's documents (`crtr:memory:<access>:user`), another app's space (only where that app allows it), and another app's conversations (`crtr:conversations:read:app:<B>`).
48
48
 
49
- The exception is the person's **public** documents (owned by the person, read through `memory`; see [Files and documents](/docs/guides/files-and-documents)): an app with an active grant can read these even without a user-memory scope. A third-party app cannot see `friends` documents, and sees `private` ones only with the optional `crtr:memory:read_private:user` the person switched on; `crtr:memory:read:user` reveals neither. They look absent from lists, searches, reads and history. Only a holder of `crtr:memory:manage:user` (a first-party app), or the person, reads all three levels. A document without a privacy field reads as `private`. Public read access is not write access.
49
+ The exception is the person's **public** documents (owned by the person, read through `memory`; see [Files and documents](/docs/guides/files-and-documents)): an app with an active grant can read these even without a user-memory scope. A third-party app sees `private` documents only with the optional `crtr:memory:read_private:user` the person switched on; `crtr:memory:read:user` does not reveal them. They look absent from lists, searches, reads and history. `crtr:memory:read_private:user` and `crtr:memory:manage:user` (a first-party app) widen the app's ceiling to `private`, and the app's schema and relation facts decide visibility within it. The person reads both levels. A document without a privacy field reads as `private`. Public read access is not write access.
50
50
 
51
51
  Every run is sandboxed: its shell runs as the app's OS user and sees only the app's space and the folders its permissions name. Normal runs have network access. Start a run with `isolated: true` when the agent should have **no network** and **no `/apps/<app>/files` mount**: its cwd is its own node folder, and all children inherit the restriction. The shell, stored conversation and model calls still work, and the run's `scopes` can narrow its commands. An isolated run cannot turn isolation off in a child or schedule, or use an outside cwd or worktree.
52
52
 
@@ -117,7 +117,7 @@ In your callback handler, check `authorizationRefusalOf(url)` before reading `co
117
117
 
118
118
  ## Memory and providers
119
119
 
120
- `user.memory.put({name, body, privacy = 'public', kind = 'knowledge', ...})` and `remove(name)`. Without `crtr:memory:manage:user` in the grant, only `public` documents are listed and others read as 404, as on the runtime; `crtr:memory:read_private:user` adds `private` (never `friends`). FakeCloud applies the user's whole grant (`user.grant.set`), not the `scopes` a run was started with; test narrowed runs on the real runtime. List items carry the full `MemoryListItem` fields.
120
+ `user.memory.put({name, body, privacy = 'public', kind = 'knowledge', ...})` and `remove(name)`. Without `crtr:memory:manage:user` in the grant, only `public` documents are listed and others read as 404, as on the runtime; `crtr:memory:read_private:user` adds `private`. FakeCloud applies the user's whole grant (`user.grant.set`), not the `scopes` a run was started with; test narrowed runs on the real runtime. List items carry the full `MemoryListItem` fields.
121
121
 
122
122
  ```ts
123
123
  cloud.providers.define('sms', { tools: { send: { group: 'send', handler: ({ userId, arguments: args }) => ({ sent: true }) } } });
@@ -47,6 +47,6 @@ printf '%s\n' 'Production changes need an explicit approval.' | \
47
47
  crtr doc edit <name> --rationale "Updated the approval rule."
48
48
  ```
49
49
 
50
- `crtr doc edit` replaces the whole body you pipe; it does not append text. For a partial change, use `crtr doc edit <name> --rationale '…' --blocks <<'EOF'` with whole-line `<<<<<<< SEARCH`, `=======`, and `>>>>>>> REPLACE` markers around verbatim old and new text. An empty REPLACE deletes text. Scripts can still use `--replace '[{"old":"…","new":"…"}]'`. Read the document before you edit it; an edit made from an older revision is refused. Use `crtr doc history <name>` to read the revision history. If you want to create a document yourself, use `crtr doc write`; it takes a name, a preview sentence that tells agents when to read it, and the document body on stdin. `--kind knowledge|preference` (default `knowledge`) sets how agents use it, and `--owner node|user|profile|app|repo` chooses who owns it (default: the writing node; `profile:<name>` and `repo:<handle>` name a specific one). New documents are `privacy: public` unless `--privacy friends` or `--privacy private` is supplied; a repository owns only public documents. `crtr doc edit --privacy <level>` changes the level. An edit that changes only fields (privacy, preview, summary, rules, `--why-it-exists`) takes effect at once but makes no new revision: revisions are versions of the body, so the revision number does not move and `crtr doc history` shows nothing for it.
50
+ `crtr doc edit` replaces the whole body you pipe; it does not append text. For a partial change, use `crtr doc edit <name> --rationale '…' --blocks <<'EOF'` with whole-line `<<<<<<< SEARCH`, `=======`, and `>>>>>>> REPLACE` markers around verbatim old and new text. An empty REPLACE deletes text. Scripts can still use `--replace '[{"old":"…","new":"…"}]'`. Read the document before you edit it; an edit made from an older revision is refused. Use `crtr doc history <name>` to read the revision history. If you want to create a document yourself, use `crtr doc write`; it takes a name, a preview sentence that tells agents when to read it, and the document body on stdin. `--kind knowledge|preference` (default `knowledge`) sets how agents use it, and `--owner node|user|profile|app|repo` chooses who owns it (default: the writing node; `profile:<name>` and `repo:<handle>` name a specific one). New documents are `privacy: public` unless `--privacy private` is supplied; a repository owns only public documents. `crtr doc edit --privacy <level>` changes the level. An edit that changes only fields (privacy, preview, summary, rules, `--why-it-exists`) takes effect at once and records a new revision with the body unchanged, attributed to you with the rationale: the revision number advances and `crtr doc history` lists it. Another reader that read the document earlier must read it again before its next body edit.
51
51
 
52
52
  Documents are for reusable current truth and durable instructions, not a transcript of one conversation. When a fact changes, update the existing document rather than saving a second version.