@north-light/cli 0.3.486 → 0.3.488

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 (49) hide show
  1. package/dist/api/contract.d.ts +1 -1
  2. package/dist/api/contract.js +1 -1
  3. package/dist/api/index.d.ts +2 -1
  4. package/dist/build-root.js +1 -1
  5. package/dist/builtin-memory/crouter-sdk/release-notes.md +23 -0
  6. package/dist/builtin-memory/crouter-sdk/resources.md +2 -1
  7. package/dist/builtin-memory/northlight-apps/cli.md +20 -6
  8. package/dist/builtin-memory/northlight-apps/coding-agents.md +9 -7
  9. package/dist/builtin-memory/northlight-apps/guides/manage-your-app.md +1 -0
  10. package/dist/builtin-memory/northlight-apps/quickstart.md +5 -3
  11. package/dist/clients/attach/viewer.js +505 -505
  12. package/dist/core/canvas/recovery.d.ts +5 -0
  13. package/dist/core/canvas/recovery.js +2 -2
  14. package/dist/core/command-plugins/endpoint.js +1 -1
  15. package/dist/core/grants/cover.d.ts +14 -0
  16. package/dist/core/grants/cover.js +1 -0
  17. package/dist/core/grants/mirror.d.ts +3 -1
  18. package/dist/core/grants/mirror.js +2 -2
  19. package/dist/core/human/page-errors.d.ts +4 -0
  20. package/dist/core/human/page-errors.js +1 -1
  21. package/dist/core/human/page.d.ts +10 -3
  22. package/dist/core/human/page.js +1 -1
  23. package/dist/core/peer/ingest.js +1 -1
  24. package/dist/core/peer/stubs.d.ts +4 -0
  25. package/dist/core/peer/stubs.js +1 -1
  26. package/dist/core/peer/version.d.ts +2 -2
  27. package/dist/core/peer/version.js +1 -1
  28. package/dist/core/runtime/revive.js +2 -2
  29. package/dist/daemon/api/app-listener.js +13 -13
  30. package/dist/daemon/api/handlers/human-requests.js +1 -1
  31. package/dist/daemon/api/principal.d.ts +10 -18
  32. package/dist/daemon/api/principal.js +1 -1
  33. package/dist/daemon/peer/authority.d.ts +27 -0
  34. package/dist/daemon/peer/authority.js +1 -0
  35. package/dist/daemon/peer/ingress.d.ts +17 -15
  36. package/dist/daemon/peer/ingress.js +1 -1
  37. package/dist/daemon/peer/relay-service.js +1 -1
  38. package/docs/apps/cli.md +20 -6
  39. package/docs/apps/coding-agents.md +9 -7
  40. package/docs/apps/guides/manage-your-app.md +1 -0
  41. package/docs/apps/quickstart.md +5 -3
  42. package/docs/ci-runner.md +2 -1
  43. package/docs/sdk/release-notes.md +23 -0
  44. package/docs/sdk/resources.md +2 -1
  45. package/package.json +3 -3
  46. package/packages/crouter-identity/dist/index.d.ts +55 -0
  47. package/packages/crouter-identity/dist/index.js +117 -0
  48. package/packages/crouter-identity/package.json +1 -1
  49. package/runtime.lock.json +12 -12
@@ -47,6 +47,11 @@ export declare function readInterruptedTurn(nodeId: string): {
47
47
  interrupted: boolean;
48
48
  progressAt: string | null;
49
49
  } | null;
50
+ /** Whether any execution of this node ever admitted a turn (agent_start recorded
51
+ * by the daemon). This, not the transcript, is the durable fact that a node's
52
+ * birth task was delivered: a session file holding only the bearings message
53
+ * exists before the kickoff is admitted. */
54
+ export declare function hasAdmittedTurn(nodeId: string): boolean;
50
55
  export declare function recordFault(nodeId: string, input: FaultRecordInput): StoredFault | null;
51
56
  export declare function clearFault(nodeId: string, opts?: {
52
57
  link?: FaultLink;
@@ -1,4 +1,4 @@
1
- var re=Object.defineProperty;var o=(e,n)=>re(e,"name",{value:n,configurable:!0});import{prepared as s}from"../sqlite-statements.js";import{randomUUID as b}from"node:crypto";import{existsSync as p,readdirSync as ie,readFileSync as oe,realpathSync as se,statSync as de}from"node:fs";import{join as N,resolve as ae}from"node:path";import{openDb as T,prepared as ue,withCanvasWrite as l}from"./db.js";import{jobDir as ce,nodesRoot as C}from"./paths.js";import{errorClassFromFault as M}from"../fault-classifier.js";import{parseProviderRateLimit as _e}from"../provider-failure.js";import{emitEvent as X}from"../events/emit.js";import{operationIdContext as j,validateOperationId as $}from"../events/operation-id.js";const We=5*6e4,le=500,B=["pi\u2192provider","viewer\u2194broker","relay\u2194broker","viewer\u2194crtrd","daemon\u2192node","crtr\u2192pi"],pe=[...B,"broker\u2194crtrd"],Ee=["rate-limit","overloaded","connection","auth","protocol","context-overflow","other","wedged","model-not-found"],fe=["auto","manual","fatal"],ye=["sdk","daemon","client"],Te=["pending","admitted","invalidated"];function c(){return new Date().toISOString()}o(c,"now");function J(e,n){return new Set(e.prepare(`PRAGMA table_info(${n})`).all().map(({name:t})=>t))}o(J,"tableColumns");function Ne(e){const n=J(e,"executions"),t=[["turn_open_at","TEXT"],["turn_progress_at","TEXT"],["turn_closed_at","TEXT"],["turn_end_reason","TEXT CHECK (turn_end_reason IS NULL OR turn_end_reason IN ('settled', 'teardown-aborted'))"],["exit_diagnostic_json","TEXT"]];for(const[r,i]of t)n.has(r)||e.exec(`ALTER TABLE executions ADD COLUMN ${r} ${i}`)}o(Ne,"addExecutionColumns");function ge(e){e.exec(`
1
+ var re=Object.defineProperty;var o=(e,n)=>re(e,"name",{value:n,configurable:!0});import{prepared as s}from"../sqlite-statements.js";import{randomUUID as b}from"node:crypto";import{existsSync as p,readdirSync as ie,readFileSync as oe,realpathSync as se,statSync as de}from"node:fs";import{join as N,resolve as ae}from"node:path";import{openDb as E,prepared as ue,withCanvasWrite as l}from"./db.js";import{jobDir as ce,nodesRoot as C}from"./paths.js";import{errorClassFromFault as w}from"../fault-classifier.js";import{parseProviderRateLimit as _e}from"../provider-failure.js";import{emitEvent as X}from"../events/emit.js";import{operationIdContext as j,validateOperationId as $}from"../events/operation-id.js";const We=5*6e4,le=500,B=["pi\u2192provider","viewer\u2194broker","relay\u2194broker","viewer\u2194crtrd","daemon\u2192node","crtr\u2192pi"],pe=[...B,"broker\u2194crtrd"],Ee=["rate-limit","overloaded","connection","auth","protocol","context-overflow","other","wedged","model-not-found"],fe=["auto","manual","fatal"],ye=["sdk","daemon","client"],Te=["pending","admitted","invalidated"];function c(){return new Date().toISOString()}o(c,"now");function J(e,n){return new Set(e.prepare(`PRAGMA table_info(${n})`).all().map(({name:t})=>t))}o(J,"tableColumns");function Ne(e){const n=J(e,"executions"),t=[["turn_open_at","TEXT"],["turn_progress_at","TEXT"],["turn_closed_at","TEXT"],["turn_end_reason","TEXT CHECK (turn_end_reason IS NULL OR turn_end_reason IN ('settled', 'teardown-aborted'))"],["exit_diagnostic_json","TEXT"]];for(const[r,i]of t)n.has(r)||e.exec(`ALTER TABLE executions ADD COLUMN ${r} ${i}`)}o(Ne,"addExecutionColumns");function ge(e){e.exec(`
2
2
  CREATE TABLE IF NOT EXISTS node_faults (
3
3
  fault_id TEXT PRIMARY KEY,
4
4
  node_id TEXT NOT NULL REFERENCES nodes(node_id) ON DELETE CASCADE,
@@ -23,4 +23,4 @@ CREATE TABLE IF NOT EXISTS node_faults (
23
23
  );
24
24
  CREATE UNIQUE INDEX IF NOT EXISTS idx_node_faults_active ON node_faults(node_id) WHERE active = 1;
25
25
  CREATE UNIQUE INDEX IF NOT EXISTS idx_node_faults_episode ON node_faults(node_id) WHERE episode_state IS NOT NULL;
26
- `)}o(ge,"createFaultTable");function g(e,n){return typeof n=="string"&&e.includes(n)}o(g,"contains");function F(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(F,"isRecord");function K(e){if(!F(e)||typeof e.provider!="string"||e.provider===""||typeof e.model!="string"||e.model==="")return;const n=typeof e.status=="number"&&Number.isFinite(e.status)?e.status:void 0,t=typeof e.code=="string"||typeof e.code=="number"?e.code:void 0,r=typeof e.errno=="string"?e.errno:void 0,i=typeof e.body=="string"?e.body:void 0,d=_e(e.ratelimit),a=Array.isArray(e.causes)?e.causes.flatMap(u=>{if(!F(u))return[];const E={...typeof u.message=="string"?{message:u.message}:{},...typeof u.status=="number"&&Number.isFinite(u.status)?{status:u.status}:{},...typeof u.code=="string"||typeof u.code=="number"?{code:u.code}:{},...typeof u.errno=="string"?{errno:u.errno}:{},...typeof u.body=="string"?{body:u.body}:{}};return Object.keys(E).length===0?[]:[E]}):void 0;return{provider:e.provider,model:e.model,...n===void 0?{}:{status:n},...t===void 0?{}:{code:t},...r===void 0?{}:{errno:r},...i===void 0?{}:{body:i},...a===void 0||a.length===0?{}:{causes:a},...d===void 0?{}:{ratelimit:d}}}o(K,"parseProviderError");function Y(e){try{const n=JSON.parse(e);if(!g(pe,n.link)||typeof n.op!="string"||n.op===""||!g(Ee,n.kind)||typeof n.message!="string"||typeof n.since!="string")return null;const t=$(n.operation_id);if(!F(n.retry)||!g(fe,n.retry.disposition)||n.retry.by!==void 0&&!g(ye,n.retry.by)||n.retry.attempt!==void 0&&typeof n.retry.attempt!="number"||n.retry.max!==void 0&&typeof n.retry.max!="number"||n.retry.nextAt!==void 0&&typeof n.retry.nextAt!="string"||n.anchorEntryId!==void 0&&(typeof n.anchorEntryId!="string"||n.anchorEntryId===""))return null;const r=n.providerError===void 0?void 0:K(n.providerError);return n.providerError!==void 0&&r===void 0?null:{link:n.link,op:n.op,kind:n.kind,retry:{disposition:n.retry.disposition,...n.retry.by===void 0?{}:{by:n.retry.by},...n.retry.attempt===void 0?{}:{attempt:n.retry.attempt},...n.retry.max===void 0?{}:{max:n.retry.max},...n.retry.nextAt===void 0?{}:{nextAt:n.retry.nextAt}},message:n.message,since:n.since,operation_id:t,...n.anchorEntryId===void 0?{}:{anchorEntryId:n.anchorEntryId},...r===void 0?{}:{providerError:r}}}catch{return null}}o(Y,"parseLegacyFault");function Le(e){const n=ae(e);try{return se(n)}catch{return n}}o(Le,"canonicalPath");function me(e){try{const n=JSON.parse(e);if(!g(Te,n.state)||typeof n.sessionFile!="string"||n.sessionFile==="")return null;const t=JSON.stringify(n.fault),r=Y(t);if(r===null||r.link!=="pi\u2192provider"||r.retry.disposition!=="auto"||r.retry.by!=="daemon")return null;const i=n.anchorEntryId;return i!==null&&typeof i!="string"||(r.anchorEntryId??null)!==i?null:{state:n.state,sessionFile:Le(n.sessionFile),fault:r}}catch{return null}}o(me,"parseLegacyEpisode");function G(e){return e!==void 0?$(e):j.current()??j.fresh(t=>t)}o(G,"resolveOperationId");function Ae(e){return e.slice(0,le)}o(Ae,"clampMessage");function R(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}o(R,"faultPriority");function V(e){return{link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operationId:e.operation_id,anchorEntryId:e.anchorEntryId??null,retryDisposition:e.retry.disposition,retryBy:e.retry.by??null,retryAttempt:e.retry.attempt??null,retryMax:e.retry.max??null,retryNextAt:e.retry.nextAt??null,providerError:e.providerError===void 0?null:JSON.stringify(e.providerError)}}o(V,"encodeFault");function H(e){const n=e.provider_error_json,t=typeof n=="string"?K(JSON.parse(n)):void 0;if(typeof n=="string"&&t===void 0)throw new Error(`invalid provider error on stored fault ${e.fault_id}`);const r={disposition:e.retry_disposition,...e.retry_by===null?{}:{by:e.retry_by},...e.retry_attempt===null?{}:{attempt:e.retry_attempt},...e.retry_max===null?{}:{max:e.retry_max},...e.retry_next_at===null?{}:{nextAt:e.retry_next_at}};return{faultId:e.fault_id,link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operation_id:e.operation_id,retry:r,...e.anchor_entry_id===null?{}:{anchorEntryId:e.anchor_entry_id},...t===void 0?{}:{providerError:t}}}o(H,"hydrateFault");function L(e,n){const t=ue(e,"SELECT * FROM node_faults WHERE node_id = ? AND active = 1").get(n);return t===void 0?null:H(t)}o(L,"activeFault");function Q(e){if(!g(B,e.link))throw new Error(`fault link is not durable: ${e.link}`);return{link:e.link,op:e.op,kind:e.kind,retry:e.retry,message:Ae(e.message),since:e.since??c(),operation_id:G(e.operation_id),...typeof e.anchorEntryId=="string"&&e.anchorEntryId!==""?{anchorEntryId:e.anchorEntryId}:{},...e.providerError===void 0?{}:{providerError:e.providerError}}}o(Q,"storedFault");function q(e,n){X({level:n.retry.disposition==="fatal"?"error":"warn",event:"fault.recorded",operation_id:n.operation_id,node_id:e,error_class:M(n),fields:{link:n.link,op:n.op,kind:n.kind,retry:n.retry,message:n.message,...n.anchorEntryId===void 0?{}:{anchor_entry_id:n.anchorEntryId},...n.providerError===void 0?{}:{provider_error:n.providerError}}})}o(q,"emitRecordedFault");function W(e,n,t,r,i){const d=b(),a=V(t),u=c();return s(e,"INSERT INTO node_faults (fault_id, node_id, link, op, kind, message, since, operation_id, anchor_entry_id, retry_disposition, retry_by, retry_attempt, retry_max, retry_next_at, provider_error_json, active, episode_state, episode_binding_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(d,n,a.link,a.op,a.kind,a.message,a.since,a.operationId,a.anchorEntryId,a.retryDisposition,a.retryBy,a.retryAttempt,a.retryMax,a.retryNextAt,a.providerError,r?1:0,i?.state??null,i?.bindingId??null,u,u),{...t,faultId:d}}o(W,"insertFault");function z(e,n,t,r){const i=V(t);return s(e,"UPDATE node_faults SET link = ?, op = ?, kind = ?, message = ?, since = ?, operation_id = ?, anchor_entry_id = ?, retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, provider_error_json = ?, episode_state = COALESCE(?, episode_state), episode_binding_id = COALESCE(?, episode_binding_id), updated_at = ? WHERE fault_id = ?").run(i.link,i.op,i.kind,i.message,i.since,i.operationId,i.anchorEntryId,i.retryDisposition,i.retryBy,i.retryAttempt,i.retryMax,i.retryNextAt,i.providerError,r?.state??null,r?.bindingId??null,c(),n),{...t,faultId:n}}o(z,"updateFault");function D(e,n){s(e,"DELETE FROM node_faults WHERE fault_id = ? AND active = 0 AND episode_state IS NULL").run(n)}o(D,"deleteIfUnretained");function Z(e,n,t,r){const i=L(e,n);if(i===null){const d=s(e,"SELECT fault_id, link, kind, since, operation_id FROM node_faults WHERE node_id = ? AND active = 0 AND episode_state IS NOT NULL").get(n);return d!==void 0&&d.link===t.link&&d.kind===t.kind&&d.since===t.since&&d.operation_id===t.operation_id?(s(e,"UPDATE node_faults SET active = 1, updated_at = ? WHERE fault_id = ?").run(c(),d.fault_id),z(e,d.fault_id,t)):W(e,n,t,!0,r)}if(i.link===t.link&&i.kind===t.kind){const d={...i.retry,...t.retry};return t.retry.disposition==="fatal"&&!("nextAt"in t.retry)&&delete d.nextAt,z(e,i.faultId,{...t,since:i.since,anchorEntryId:i.anchorEntryId??t.anchorEntryId,retry:d},r)}return R(i)>R(t)?null:(s(e,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(e,i.faultId),W(e,n,t,!0,r))}o(Z,"replaceActiveFault");function m(e,n,t){return s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? AND unbound_at IS NULL").get(n,t)?.binding_id??null}o(m,"liveBinding");function Pe(e,n){return l(t=>{const r=c();return s(t,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,e).changes>0?!0:s(t,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ? AND state != 'exited'").run(r,r,e).changes>0})}o(Pe,"openTurn");function we(e){return l(n=>s(n,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(c(),e).changes>0)}o(we,"recordTurnProgress");function Me(e,n){return l(t=>s(t,"UPDATE executions SET turn_closed_at = ?, turn_end_reason = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(c(),n.endReason,e).changes>0)}o(Me,"closeTurn");function Xe(e,n){if(!Number.isInteger(n.consecutivePasses)||n.consecutivePasses<1||n.routes.length===0||!n.routes.every(t=>t!==""))throw new Error("invalid transport-poison verdict");return l(t=>s(t,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ? AND state != 'exited'").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:n.consecutivePasses,routes:n.routes}}),e).changes>0)}o(Xe,"recordTransportPoisonVerdict");function je(e){const n=s(T(),"SELECT exit_diagnostic_json FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);if(n===void 0||n.exit_diagnostic_json===null)return null;try{const t=JSON.parse(n.exit_diagnostic_json),r=t.transport_poison;return t.schema!=="crtr.execution-exit-diagnostic/v1"||r===void 0||!Number.isInteger(r.consecutive_passes)||r.consecutive_passes<1||!Array.isArray(r.routes)||r.routes.length===0||!r.routes.every(i=>typeof i=="string"&&i!=="")?null:{consecutivePasses:r.consecutive_passes,routes:r.routes}}catch{return null}}o(je,"readTransportPoisonVerdict");function $e(e){const n=s(T(),"SELECT turn_open_at, turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return n===void 0?null:{busy:n.turn_open_at!==null&&n.turn_closed_at===null,progressAt:n.turn_progress_at}}o($e,"readLiveTurn");function Be(e){const n=T(),t=s(n,"SELECT turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL ORDER BY rowid DESC LIMIT 1").get(e);if(t===void 0)return null;const r=s(n,"SELECT turn_end_reason FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);return{interrupted:t.turn_closed_at===null||r?.turn_end_reason==="teardown-aborted",progressAt:t.turn_progress_at}}o(Be,"readInterruptedTurn");function Je(e,n){const t=Q(n);return q(e,t),l(r=>Z(r,e,t))}o(Je,"recordFault");function Ke(e,n){const t=L(T(),e);return t===null||n?.link!==void 0&&t.link!==n.link?!1:l(r=>{const i=L(r,e);if(i===null||n?.link!==void 0&&i.link!==n.link)return!1;const d=s(r,"SELECT episode_state FROM node_faults WHERE fault_id = ?").get(i.faultId);s(r,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),d.episode_state==="pending"&&n?.preserveEpisode!==!0&&s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(r,i.faultId);const a=G();return X({level:"info",event:"fault.cleared",operation_id:a,node_id:e,error_class:M(i),fields:{cleared_fault_operation_id:i.operation_id,link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId}}}),!0})}o(Ke,"clearFault");function ee(e){return L(T(),e)}o(ee,"readFault");function Ye(e,n){const t=Q(n.input);if(t.link!=="pi\u2192provider"||t.retry.disposition!=="auto"||t.retry.by!=="daemon")throw new Error("provider retry episode requires an automatic daemon provider fault");return q(e,t),l(r=>{const i=m(r,e,n.sessionId);if(i===null)return null;const d=L(r,e);if(d!==null&&(d.link!==t.link||d.kind!==t.kind)&&R(d)>R(t))return null;const a=s(r,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_state IS NOT NULL").all(e);s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_state IS NOT NULL").run(c(),e);for(const E of a)D(r,E.fault_id);const u=Z(r,e,t,{state:"pending",bindingId:i});return u===null?null:(s(r,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run("pending",i,c(),u.faultId),u)})}o(Ye,"recordPendingEpisode");function Ge(e,n){return l(t=>{if(s(t,"SELECT 1 FROM nodes WHERE node_id = ? AND intent IS 'refresh'").get(e)!==void 0)return!1;const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'admitted', retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, updated_at = ? WHERE node_id = ? AND fault_id = ? AND episode_state = 'pending' AND episode_binding_id = ?").run(n.retry.disposition,n.retry.by??null,n.retry.attempt??null,n.retry.max??null,n.retry.nextAt??null,c(),e,n.faultId,r).changes>0})}o(Ge,"admitEpisode");function Ve(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'pending', updated_at = ? WHERE node_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(Ve,"reopenEpisode");function Qe(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'invalidated', updated_at = ? WHERE node_id = ? AND episode_state != 'invalidated' AND episode_state IS NOT NULL AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(Qe,"invalidateEpisode");function qe(e,n){return l(t=>{const r=m(t,e,n.sessionId);if(r===null)return!1;const i=s(t,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").all(e,r);if(i.length===0)return!1;s(t,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").run(c(),e,r);for(const d of i)D(t,d.fault_id);return!0})}o(qe,"clearEpisode");function ze(e){const n=s(T(),"SELECT f.*, s.session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.node_id = ? AND f.episode_state IS NOT NULL").get(e);return n===void 0?null:{state:n.episode_state,sessionId:n.session_id,fault:H(n)}}o(ze,"readEpisode");function Ze(){return s(T(),"SELECT f.*, s.session_id AS bound_session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.active = 1 AND f.episode_state = 'pending' AND s.unbound_at IS NULL AND s.session_id IS NOT NULL AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'auto' AND f.retry_by = 'daemon' AND f.kind IN ('connection', 'rate-limit', 'overloaded')").all().map(n=>({nodeId:n.node_id,sessionId:n.bound_session_id,fault:H(n),updatedAt:n.updated_at}))}o(Ze,"listPendingProviderRetries");function en(e){const n=ee(e)===null;return{explanation(){if(!n)return null;const t=ee(e);if(t===null||t.link!=="crtr\u2192pi"||t.retry.disposition!=="fatal")return null;const r=t.op.trim(),i=t.message.trim();return r===""||i===""?null:`${r}: ${i}`}}}o(en,"beginBootFaultAttempt");function ne(e,n){try{return de(e).mtime.toISOString()}catch{return n}}o(ne,"markerMtime");function P(e,n){if(!p(e))return null;try{return oe(e,"utf8")}catch(t){if(!n)return null;throw new Error(`cannot import recovery input ${e}: ${t.message}`)}}o(P,"legacyFile");function Se(e,n){return s(e,"SELECT execution_id, started_at FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(n)??null}o(Se,"latestExecution");function xe(e,n){const r=J(e,"nodes").has("launched_at")?s(e,"SELECT COALESCE(launched_at, created) AS started_at FROM nodes WHERE node_id = ?").get(n):s(e,"SELECT created AS started_at FROM nodes WHERE node_id = ?").get(n);if(r===void 0)throw new Error(`cannot import recovery witness for unknown node ${n}`);const i=b();return s(e,"INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, NULL, NULL, NULL, 'exited', ?, ?, 'pre-consolidation')").run(i,n,r.started_at,r.started_at),{execution_id:i,started_at:r.started_at}}o(xe,"syntheticExecution");function te(e,n,t,r,i){return W(e,n,t,r,i)}o(te,"insertMigratedFault");function Ie(e,n,t,r){const i=s(e,"SELECT binding_id, node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(t);if(i!==void 0){if(i.node_id!==n)throw new Error(`cannot import provider retry ${r}: transcript is live-owned by ${i.node_id}`);return i.binding_id}const d=s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND transcript_path = ? ORDER BY rowid DESC LIMIT 1").get(n,t);if(d!==void 0)return d.binding_id;const a=s(e,"SELECT created FROM nodes WHERE node_id = ?").get(n);if(a===void 0)throw new Error(`cannot import provider retry ${r}: unknown node ${n}`);const u=b();return s(e,"INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at) VALUES (?, NULL, ?, ?, NULL, NULL, ?, ?, ?)").run(u,n,t,a.created,a.created,c()),u}o(Ie,"migrationBinding");function nn(e){if(Ne(e),ge(e),!p(C()))return;const n=ie(C(),{withFileTypes:!0}).filter(r=>r.isDirectory()).sort((r,i)=>r.name.localeCompare(i.name)),t=s(e,"SELECT 1 FROM nodes WHERE node_id = ?");for(const r of n){const i=r.name,d=ce(i),a=N(d,"busy"),u=N(d,"clean-abort"),E=N(d,"transport-poison.json"),h=N(d,"fault"),A=N(d,"provider-retry"),O=p(a),U=p(u);if(!O&&!U&&!p(E)&&!p(h)&&!p(A)||!p(N(C(),i,"meta.json"))&&t.get(i)===void 0)continue;const k=P(E,!1),S=P(h,!0),x=P(A,!0);if(!O&&!U&&k===null&&S===null&&x===null)continue;let f=Se(e,i);if(f===null&&(f=xe(e,i)),O){const _=ne(a,f.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ?").run(_,_,f.execution_id)}else if(U){const _=ne(u,f.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = ?, turn_end_reason = 'teardown-aborted' WHERE execution_id = ?").run(_,_,_,f.execution_id)}if(k!==null)try{const _=JSON.parse(k);Number.isInteger(_.consecutivePasses)&&_.consecutivePasses>=1&&Array.isArray(_.routes)&&_.routes.length>0&&_.routes.every(w=>typeof w=="string"&&w!=="")&&s(e,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ?").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:_.consecutivePasses,routes:_.routes}}),f.execution_id)}catch{}const I=S===null?null:Y(S);if(S!==null&&I===null)throw new Error(`cannot import recovery fault ${h}`);const y=x===null?null:me(x);if(x!==null&&y===null)throw new Error(`cannot import provider retry ${A}`);let v=I===null||I.link==="broker\u2194crtrd"?null:te(e,i,I,!0);if(y!==null){const _=Ie(e,i,y.sessionFile,A);v!==null&&v.since===y.fault.since?s(e,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run(y.state,_,c(),v.faultId):te(e,i,y.fault,!1,{state:y.state,bindingId:_})}}}o(nn,"migrateRecoveryWitnesses");export{We as FAULT_QUIET_MS,Ge as admitEpisode,en as beginBootFaultAttempt,qe as clearEpisode,Ke as clearFault,Me as closeTurn,H as hydrateFault,Qe as invalidateEpisode,Ze as listPendingProviderRetries,nn as migrateRecoveryWitnesses,Pe as openTurn,K as parseProviderError,ze as readEpisode,ee as readFault,Be as readInterruptedTurn,$e as readLiveTurn,je as readTransportPoisonVerdict,Je as recordFault,Ye as recordPendingEpisode,Xe as recordTransportPoisonVerdict,we as recordTurnProgress,Ve as reopenEpisode};
26
+ `)}o(ge,"createFaultTable");function g(e,n){return typeof n=="string"&&e.includes(n)}o(g,"contains");function F(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(F,"isRecord");function K(e){if(!F(e)||typeof e.provider!="string"||e.provider===""||typeof e.model!="string"||e.model==="")return;const n=typeof e.status=="number"&&Number.isFinite(e.status)?e.status:void 0,t=typeof e.code=="string"||typeof e.code=="number"?e.code:void 0,r=typeof e.errno=="string"?e.errno:void 0,i=typeof e.body=="string"?e.body:void 0,d=_e(e.ratelimit),a=Array.isArray(e.causes)?e.causes.flatMap(u=>{if(!F(u))return[];const f={...typeof u.message=="string"?{message:u.message}:{},...typeof u.status=="number"&&Number.isFinite(u.status)?{status:u.status}:{},...typeof u.code=="string"||typeof u.code=="number"?{code:u.code}:{},...typeof u.errno=="string"?{errno:u.errno}:{},...typeof u.body=="string"?{body:u.body}:{}};return Object.keys(f).length===0?[]:[f]}):void 0;return{provider:e.provider,model:e.model,...n===void 0?{}:{status:n},...t===void 0?{}:{code:t},...r===void 0?{}:{errno:r},...i===void 0?{}:{body:i},...a===void 0||a.length===0?{}:{causes:a},...d===void 0?{}:{ratelimit:d}}}o(K,"parseProviderError");function Y(e){try{const n=JSON.parse(e);if(!g(pe,n.link)||typeof n.op!="string"||n.op===""||!g(Ee,n.kind)||typeof n.message!="string"||typeof n.since!="string")return null;const t=$(n.operation_id);if(!F(n.retry)||!g(fe,n.retry.disposition)||n.retry.by!==void 0&&!g(ye,n.retry.by)||n.retry.attempt!==void 0&&typeof n.retry.attempt!="number"||n.retry.max!==void 0&&typeof n.retry.max!="number"||n.retry.nextAt!==void 0&&typeof n.retry.nextAt!="string"||n.anchorEntryId!==void 0&&(typeof n.anchorEntryId!="string"||n.anchorEntryId===""))return null;const r=n.providerError===void 0?void 0:K(n.providerError);return n.providerError!==void 0&&r===void 0?null:{link:n.link,op:n.op,kind:n.kind,retry:{disposition:n.retry.disposition,...n.retry.by===void 0?{}:{by:n.retry.by},...n.retry.attempt===void 0?{}:{attempt:n.retry.attempt},...n.retry.max===void 0?{}:{max:n.retry.max},...n.retry.nextAt===void 0?{}:{nextAt:n.retry.nextAt}},message:n.message,since:n.since,operation_id:t,...n.anchorEntryId===void 0?{}:{anchorEntryId:n.anchorEntryId},...r===void 0?{}:{providerError:r}}}catch{return null}}o(Y,"parseLegacyFault");function Le(e){const n=ae(e);try{return se(n)}catch{return n}}o(Le,"canonicalPath");function me(e){try{const n=JSON.parse(e);if(!g(Te,n.state)||typeof n.sessionFile!="string"||n.sessionFile==="")return null;const t=JSON.stringify(n.fault),r=Y(t);if(r===null||r.link!=="pi\u2192provider"||r.retry.disposition!=="auto"||r.retry.by!=="daemon")return null;const i=n.anchorEntryId;return i!==null&&typeof i!="string"||(r.anchorEntryId??null)!==i?null:{state:n.state,sessionFile:Le(n.sessionFile),fault:r}}catch{return null}}o(me,"parseLegacyEpisode");function G(e){return e!==void 0?$(e):j.current()??j.fresh(t=>t)}o(G,"resolveOperationId");function Ae(e){return e.slice(0,le)}o(Ae,"clampMessage");function R(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}o(R,"faultPriority");function V(e){return{link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operationId:e.operation_id,anchorEntryId:e.anchorEntryId??null,retryDisposition:e.retry.disposition,retryBy:e.retry.by??null,retryAttempt:e.retry.attempt??null,retryMax:e.retry.max??null,retryNextAt:e.retry.nextAt??null,providerError:e.providerError===void 0?null:JSON.stringify(e.providerError)}}o(V,"encodeFault");function H(e){const n=e.provider_error_json,t=typeof n=="string"?K(JSON.parse(n)):void 0;if(typeof n=="string"&&t===void 0)throw new Error(`invalid provider error on stored fault ${e.fault_id}`);const r={disposition:e.retry_disposition,...e.retry_by===null?{}:{by:e.retry_by},...e.retry_attempt===null?{}:{attempt:e.retry_attempt},...e.retry_max===null?{}:{max:e.retry_max},...e.retry_next_at===null?{}:{nextAt:e.retry_next_at}};return{faultId:e.fault_id,link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operation_id:e.operation_id,retry:r,...e.anchor_entry_id===null?{}:{anchorEntryId:e.anchor_entry_id},...t===void 0?{}:{providerError:t}}}o(H,"hydrateFault");function L(e,n){const t=ue(e,"SELECT * FROM node_faults WHERE node_id = ? AND active = 1").get(n);return t===void 0?null:H(t)}o(L,"activeFault");function Q(e){if(!g(B,e.link))throw new Error(`fault link is not durable: ${e.link}`);return{link:e.link,op:e.op,kind:e.kind,retry:e.retry,message:Ae(e.message),since:e.since??c(),operation_id:G(e.operation_id),...typeof e.anchorEntryId=="string"&&e.anchorEntryId!==""?{anchorEntryId:e.anchorEntryId}:{},...e.providerError===void 0?{}:{providerError:e.providerError}}}o(Q,"storedFault");function q(e,n){X({level:n.retry.disposition==="fatal"?"error":"warn",event:"fault.recorded",operation_id:n.operation_id,node_id:e,error_class:w(n),fields:{link:n.link,op:n.op,kind:n.kind,retry:n.retry,message:n.message,...n.anchorEntryId===void 0?{}:{anchor_entry_id:n.anchorEntryId},...n.providerError===void 0?{}:{provider_error:n.providerError}}})}o(q,"emitRecordedFault");function W(e,n,t,r,i){const d=b(),a=V(t),u=c();return s(e,"INSERT INTO node_faults (fault_id, node_id, link, op, kind, message, since, operation_id, anchor_entry_id, retry_disposition, retry_by, retry_attempt, retry_max, retry_next_at, provider_error_json, active, episode_state, episode_binding_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(d,n,a.link,a.op,a.kind,a.message,a.since,a.operationId,a.anchorEntryId,a.retryDisposition,a.retryBy,a.retryAttempt,a.retryMax,a.retryNextAt,a.providerError,r?1:0,i?.state??null,i?.bindingId??null,u,u),{...t,faultId:d}}o(W,"insertFault");function z(e,n,t,r){const i=V(t);return s(e,"UPDATE node_faults SET link = ?, op = ?, kind = ?, message = ?, since = ?, operation_id = ?, anchor_entry_id = ?, retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, provider_error_json = ?, episode_state = COALESCE(?, episode_state), episode_binding_id = COALESCE(?, episode_binding_id), updated_at = ? WHERE fault_id = ?").run(i.link,i.op,i.kind,i.message,i.since,i.operationId,i.anchorEntryId,i.retryDisposition,i.retryBy,i.retryAttempt,i.retryMax,i.retryNextAt,i.providerError,r?.state??null,r?.bindingId??null,c(),n),{...t,faultId:n}}o(z,"updateFault");function D(e,n){s(e,"DELETE FROM node_faults WHERE fault_id = ? AND active = 0 AND episode_state IS NULL").run(n)}o(D,"deleteIfUnretained");function Z(e,n,t,r){const i=L(e,n);if(i===null){const d=s(e,"SELECT fault_id, link, kind, since, operation_id FROM node_faults WHERE node_id = ? AND active = 0 AND episode_state IS NOT NULL").get(n);return d!==void 0&&d.link===t.link&&d.kind===t.kind&&d.since===t.since&&d.operation_id===t.operation_id?(s(e,"UPDATE node_faults SET active = 1, updated_at = ? WHERE fault_id = ?").run(c(),d.fault_id),z(e,d.fault_id,t)):W(e,n,t,!0,r)}if(i.link===t.link&&i.kind===t.kind){const d={...i.retry,...t.retry};return t.retry.disposition==="fatal"&&!("nextAt"in t.retry)&&delete d.nextAt,z(e,i.faultId,{...t,since:i.since,anchorEntryId:i.anchorEntryId??t.anchorEntryId,retry:d},r)}return R(i)>R(t)?null:(s(e,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(e,i.faultId),W(e,n,t,!0,r))}o(Z,"replaceActiveFault");function m(e,n,t){return s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? AND unbound_at IS NULL").get(n,t)?.binding_id??null}o(m,"liveBinding");function Pe(e,n){return l(t=>{const r=c();return s(t,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,e).changes>0?!0:s(t,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ? AND state != 'exited'").run(r,r,e).changes>0})}o(Pe,"openTurn");function Me(e){return l(n=>s(n,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(c(),e).changes>0)}o(Me,"recordTurnProgress");function we(e,n){return l(t=>s(t,"UPDATE executions SET turn_closed_at = ?, turn_end_reason = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(c(),n.endReason,e).changes>0)}o(we,"closeTurn");function Xe(e,n){if(!Number.isInteger(n.consecutivePasses)||n.consecutivePasses<1||n.routes.length===0||!n.routes.every(t=>t!==""))throw new Error("invalid transport-poison verdict");return l(t=>s(t,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ? AND state != 'exited'").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:n.consecutivePasses,routes:n.routes}}),e).changes>0)}o(Xe,"recordTransportPoisonVerdict");function je(e){const n=s(E(),"SELECT exit_diagnostic_json FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);if(n===void 0||n.exit_diagnostic_json===null)return null;try{const t=JSON.parse(n.exit_diagnostic_json),r=t.transport_poison;return t.schema!=="crtr.execution-exit-diagnostic/v1"||r===void 0||!Number.isInteger(r.consecutive_passes)||r.consecutive_passes<1||!Array.isArray(r.routes)||r.routes.length===0||!r.routes.every(i=>typeof i=="string"&&i!=="")?null:{consecutivePasses:r.consecutive_passes,routes:r.routes}}catch{return null}}o(je,"readTransportPoisonVerdict");function $e(e){const n=s(E(),"SELECT turn_open_at, turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return n===void 0?null:{busy:n.turn_open_at!==null&&n.turn_closed_at===null,progressAt:n.turn_progress_at}}o($e,"readLiveTurn");function Be(e){const n=E(),t=s(n,"SELECT turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL ORDER BY rowid DESC LIMIT 1").get(e);if(t===void 0)return null;const r=s(n,"SELECT turn_end_reason FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);return{interrupted:t.turn_closed_at===null||r?.turn_end_reason==="teardown-aborted",progressAt:t.turn_progress_at}}o(Be,"readInterruptedTurn");function Je(e){return s(E(),"SELECT 1 FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL LIMIT 1").get(e)!==void 0}o(Je,"hasAdmittedTurn");function Ke(e,n){const t=Q(n);return q(e,t),l(r=>Z(r,e,t))}o(Ke,"recordFault");function Ye(e,n){const t=L(E(),e);return t===null||n?.link!==void 0&&t.link!==n.link?!1:l(r=>{const i=L(r,e);if(i===null||n?.link!==void 0&&i.link!==n.link)return!1;const d=s(r,"SELECT episode_state FROM node_faults WHERE fault_id = ?").get(i.faultId);s(r,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),d.episode_state==="pending"&&n?.preserveEpisode!==!0&&s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(r,i.faultId);const a=G();return X({level:"info",event:"fault.cleared",operation_id:a,node_id:e,error_class:w(i),fields:{cleared_fault_operation_id:i.operation_id,link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId}}}),!0})}o(Ye,"clearFault");function ee(e){return L(E(),e)}o(ee,"readFault");function Ge(e,n){const t=Q(n.input);if(t.link!=="pi\u2192provider"||t.retry.disposition!=="auto"||t.retry.by!=="daemon")throw new Error("provider retry episode requires an automatic daemon provider fault");return q(e,t),l(r=>{const i=m(r,e,n.sessionId);if(i===null)return null;const d=L(r,e);if(d!==null&&(d.link!==t.link||d.kind!==t.kind)&&R(d)>R(t))return null;const a=s(r,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_state IS NOT NULL").all(e);s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_state IS NOT NULL").run(c(),e);for(const f of a)D(r,f.fault_id);const u=Z(r,e,t,{state:"pending",bindingId:i});return u===null?null:(s(r,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run("pending",i,c(),u.faultId),u)})}o(Ge,"recordPendingEpisode");function Ve(e,n){return l(t=>{if(s(t,"SELECT 1 FROM nodes WHERE node_id = ? AND intent IS 'refresh'").get(e)!==void 0)return!1;const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'admitted', retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, updated_at = ? WHERE node_id = ? AND fault_id = ? AND episode_state = 'pending' AND episode_binding_id = ?").run(n.retry.disposition,n.retry.by??null,n.retry.attempt??null,n.retry.max??null,n.retry.nextAt??null,c(),e,n.faultId,r).changes>0})}o(Ve,"admitEpisode");function Qe(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'pending', updated_at = ? WHERE node_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(Qe,"reopenEpisode");function qe(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'invalidated', updated_at = ? WHERE node_id = ? AND episode_state != 'invalidated' AND episode_state IS NOT NULL AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(qe,"invalidateEpisode");function ze(e,n){return l(t=>{const r=m(t,e,n.sessionId);if(r===null)return!1;const i=s(t,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").all(e,r);if(i.length===0)return!1;s(t,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").run(c(),e,r);for(const d of i)D(t,d.fault_id);return!0})}o(ze,"clearEpisode");function Ze(e){const n=s(E(),"SELECT f.*, s.session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.node_id = ? AND f.episode_state IS NOT NULL").get(e);return n===void 0?null:{state:n.episode_state,sessionId:n.session_id,fault:H(n)}}o(Ze,"readEpisode");function en(){return s(E(),"SELECT f.*, s.session_id AS bound_session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.active = 1 AND f.episode_state = 'pending' AND s.unbound_at IS NULL AND s.session_id IS NOT NULL AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'auto' AND f.retry_by = 'daemon' AND f.kind IN ('connection', 'rate-limit', 'overloaded')").all().map(n=>({nodeId:n.node_id,sessionId:n.bound_session_id,fault:H(n),updatedAt:n.updated_at}))}o(en,"listPendingProviderRetries");function nn(e){const n=ee(e)===null;return{explanation(){if(!n)return null;const t=ee(e);if(t===null||t.link!=="crtr\u2192pi"||t.retry.disposition!=="fatal")return null;const r=t.op.trim(),i=t.message.trim();return r===""||i===""?null:`${r}: ${i}`}}}o(nn,"beginBootFaultAttempt");function ne(e,n){try{return de(e).mtime.toISOString()}catch{return n}}o(ne,"markerMtime");function P(e,n){if(!p(e))return null;try{return oe(e,"utf8")}catch(t){if(!n)return null;throw new Error(`cannot import recovery input ${e}: ${t.message}`)}}o(P,"legacyFile");function Se(e,n){return s(e,"SELECT execution_id, started_at FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(n)??null}o(Se,"latestExecution");function xe(e,n){const r=J(e,"nodes").has("launched_at")?s(e,"SELECT COALESCE(launched_at, created) AS started_at FROM nodes WHERE node_id = ?").get(n):s(e,"SELECT created AS started_at FROM nodes WHERE node_id = ?").get(n);if(r===void 0)throw new Error(`cannot import recovery witness for unknown node ${n}`);const i=b();return s(e,"INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, NULL, NULL, NULL, 'exited', ?, ?, 'pre-consolidation')").run(i,n,r.started_at,r.started_at),{execution_id:i,started_at:r.started_at}}o(xe,"syntheticExecution");function te(e,n,t,r,i){return W(e,n,t,r,i)}o(te,"insertMigratedFault");function Ie(e,n,t,r){const i=s(e,"SELECT binding_id, node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(t);if(i!==void 0){if(i.node_id!==n)throw new Error(`cannot import provider retry ${r}: transcript is live-owned by ${i.node_id}`);return i.binding_id}const d=s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND transcript_path = ? ORDER BY rowid DESC LIMIT 1").get(n,t);if(d!==void 0)return d.binding_id;const a=s(e,"SELECT created FROM nodes WHERE node_id = ?").get(n);if(a===void 0)throw new Error(`cannot import provider retry ${r}: unknown node ${n}`);const u=b();return s(e,"INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at) VALUES (?, NULL, ?, ?, NULL, NULL, ?, ?, ?)").run(u,n,t,a.created,a.created,c()),u}o(Ie,"migrationBinding");function tn(e){if(Ne(e),ge(e),!p(C()))return;const n=ie(C(),{withFileTypes:!0}).filter(r=>r.isDirectory()).sort((r,i)=>r.name.localeCompare(i.name)),t=s(e,"SELECT 1 FROM nodes WHERE node_id = ?");for(const r of n){const i=r.name,d=ce(i),a=N(d,"busy"),u=N(d,"clean-abort"),f=N(d,"transport-poison.json"),h=N(d,"fault"),A=N(d,"provider-retry"),O=p(a),U=p(u);if(!O&&!U&&!p(f)&&!p(h)&&!p(A)||!p(N(C(),i,"meta.json"))&&t.get(i)===void 0)continue;const k=P(f,!1),S=P(h,!0),x=P(A,!0);if(!O&&!U&&k===null&&S===null&&x===null)continue;let y=Se(e,i);if(y===null&&(y=xe(e,i)),O){const _=ne(a,y.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ?").run(_,_,y.execution_id)}else if(U){const _=ne(u,y.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = ?, turn_end_reason = 'teardown-aborted' WHERE execution_id = ?").run(_,_,_,y.execution_id)}if(k!==null)try{const _=JSON.parse(k);Number.isInteger(_.consecutivePasses)&&_.consecutivePasses>=1&&Array.isArray(_.routes)&&_.routes.length>0&&_.routes.every(M=>typeof M=="string"&&M!=="")&&s(e,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ?").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:_.consecutivePasses,routes:_.routes}}),y.execution_id)}catch{}const I=S===null?null:Y(S);if(S!==null&&I===null)throw new Error(`cannot import recovery fault ${h}`);const T=x===null?null:me(x);if(x!==null&&T===null)throw new Error(`cannot import provider retry ${A}`);let v=I===null||I.link==="broker\u2194crtrd"?null:te(e,i,I,!0);if(T!==null){const _=Ie(e,i,T.sessionFile,A);v!==null&&v.since===T.fault.since?s(e,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run(T.state,_,c(),v.faultId):te(e,i,T.fault,!1,{state:T.state,bindingId:_})}}}o(tn,"migrateRecoveryWitnesses");export{We as FAULT_QUIET_MS,Ve as admitEpisode,nn as beginBootFaultAttempt,ze as clearEpisode,Ye as clearFault,we as closeTurn,Je as hasAdmittedTurn,H as hydrateFault,qe as invalidateEpisode,en as listPendingProviderRetries,tn as migrateRecoveryWitnesses,Pe as openTurn,K as parseProviderError,Ze as readEpisode,ee as readFault,Be as readInterruptedTurn,$e as readLiveTurn,je as readTransportPoisonVerdict,Ke as recordFault,Ge as recordPendingEpisode,Xe as recordTransportPoisonVerdict,Me as recordTurnProgress,Qe as reopenEpisode};
@@ -1 +1 @@
1
- var p=Object.defineProperty;var e=(n,t)=>p(n,"name",{value:t,configurable:!0});import{validateEnvVarName as i}from"../env-name.js";function h(n){return n==="localhost"||n.endsWith(".localhost")||n==="127.0.0.1"||n==="[::1]"||n==="::1"||n==="host.docker.internal"}e(h,"isLoopbackHostname");function l(n){const t=[];if(typeof n!="string")t.push("endpoint must be a string");else try{const o=new URL(n);(o.protocol!=="https:"&&!(o.protocol==="http:"&&h(o.hostname))||o.username||o.password||o.hash)&&t.push("endpoint must be an absolute https:// URL (http:// permitted for loopback and *.localhost hosts only; no credentials or fragment)")}catch{t.push("endpoint must be an absolute https:// URL (http:// permitted for loopback and *.localhost hosts only; no credentials or fragment)")}return{isValid:t.length===0,errors:t}}e(l,"validateEndpoint");function u(n){try{const t=new URL(n),o=t.pathname.length>1&&t.pathname.endsWith("/")?t.pathname.slice(0,-1):t.pathname;return`${t.protocol}//${t.host}${o}${t.search}`}catch{return n}}e(u,"normalizeEndpoint");function c(n){const t=[];if(typeof n!="object"||n===null||Array.isArray(n))return{errors:["transport must be an object"]};const o=n,r=Object.keys(o).filter(a=>!["kind","endpoint","authEnv"].includes(a));r.length&&t.push(`transport has unknown keys: ${r.join(", ")}`),o.kind!=="http"&&t.push('transport.kind must be "http"');const s=l(o.endpoint);return t.push(...s.errors),o.authEnv!==void 0&&t.push(...i(o.authEnv).errors),t.length?{errors:t}:{transport:{kind:"http",endpoint:u(o.endpoint),...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},errors:t}}e(c,"validateHttpPluginTransport");function m(n){if(typeof n=="object"&&n!==null&&!Array.isArray(n)&&n.kind==="machine"){const t=Object.keys(n).filter(o=>o!=="kind");return t.length?{errors:[`transport has unknown keys: ${t.join(", ")}`]}:{transport:{kind:"machine"},errors:[]}}return c(n)}e(m,"validateBundleTransport");export{h as isLoopbackHostname,u as normalizeEndpoint,m as validateBundleTransport,l as validateEndpoint,c as validateHttpPluginTransport};
1
+ var i=Object.defineProperty;var e=(t,n)=>i(t,"name",{value:n,configurable:!0});import{validateEnvVarName as p}from"../env-name.js";function h(t){return t==="localhost"||t.endsWith(".localhost")||t==="127.0.0.1"||t==="[::1]"||t==="::1"||t==="host.docker.internal"}e(h,"isLoopbackHostname");function l(t){const n=[];if(typeof t!="string")n.push("endpoint must be a string");else try{const o=new URL(t);(o.protocol!=="https:"&&!(o.protocol==="http:"&&h(o.hostname))||o.username||o.password||o.hash)&&n.push("endpoint must be an absolute https:// URL (http:// permitted for loopback and *.localhost hosts only; no credentials or fragment)")}catch{n.push("endpoint must be an absolute https:// URL (http:// permitted for loopback and *.localhost hosts only; no credentials or fragment)")}return{isValid:n.length===0,errors:n}}e(l,"validateEndpoint");function u(t){try{const n=new URL(t),o=n.pathname.endsWith("/")?n.pathname.slice(0,-1):n.pathname;return`${n.protocol}//${n.host}${o}${n.search}`}catch{return t}}e(u,"normalizeEndpoint");function c(t){const n=[];if(typeof t!="object"||t===null||Array.isArray(t))return{errors:["transport must be an object"]};const o=t,r=Object.keys(o).filter(a=>!["kind","endpoint","authEnv"].includes(a));r.length&&n.push(`transport has unknown keys: ${r.join(", ")}`),o.kind!=="http"&&n.push('transport.kind must be "http"');const s=l(o.endpoint);return n.push(...s.errors),o.authEnv!==void 0&&n.push(...p(o.authEnv).errors),n.length?{errors:n}:{transport:{kind:"http",endpoint:u(o.endpoint),...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},errors:n}}e(c,"validateHttpPluginTransport");function k(t){if(typeof t=="object"&&t!==null&&!Array.isArray(t)&&t.kind==="machine"){const n=Object.keys(t).filter(o=>o!=="kind");return n.length?{errors:[`transport has unknown keys: ${n.join(", ")}`]}:{transport:{kind:"machine"},errors:[]}}return c(t)}e(k,"validateBundleTransport");export{h as isLoopbackHostname,u as normalizeEndpoint,k as validateBundleTransport,l as validateEndpoint,c as validateHttpPluginTransport};
@@ -0,0 +1,14 @@
1
+ import { type ActiveGrant } from './mirror.js';
2
+ /** Pulls the directory's grants into the mirror; `fresh` demands a pull that starts after the call. */
3
+ export type GrantSync = (options?: {
4
+ fresh?: boolean;
5
+ }) => Promise<void>;
6
+ /** Make the mirror cover grant `grantId` at `rev`, pulling once when it is behind. Throws `RunError` 503
7
+ * `service_unavailable` (failed pull, or a pull that stayed behind) or 401 `grant_revoked` (absent after a pull). */
8
+ export declare function ensureCovers(grantId: string, rev: number, syncGrants: GrantSync): Promise<void>;
9
+ /** The mirrored grant a caller names, read now, when it is still the caller's: active, the same `sub` and
10
+ * `grantee`, and not past `expires_at`. Otherwise 401 `grant_revoked`. */
11
+ export declare function callerGrantOf(grantId: string, sub: string, grantee: string): ActiveGrant;
12
+ /** The grant a token's app link names: the mirror made to cover `rev`, then the grant itself checked against
13
+ * `sub` and `grantee`. Errors are `ensureCovers`' and `callerGrantOf`'s `RunError`s. */
14
+ export declare function coverGrant(grantId: string, rev: number, sub: string, grantee: string, syncGrants: GrantSync): Promise<ActiveGrant>;
@@ -0,0 +1 @@
1
+ var l=Object.defineProperty;var r=(e,n)=>l(e,"name",{value:n,configurable:!0});import{emitEvent as w}from"../events/emit.js";import{RunError as a}from"../runs/operations.js";import{activeGrant as h,grantExpired as m,grantSyncState as s,grantsGeneration as g}from"./mirror.js";let c=new Map,f=-1;function u(e){const n=g();return n!==f&&(c=new Map,f=n),c.get(e)}r(u,"behindRev");const v=r((e,n)=>e!==null&&e.rev>=n,"covered");async function p(e,n,o){if(v(s(e),n))return;const t=u(e);if(t===void 0||n>t){try{await o({fresh:!0})}catch{throw new a(503,"service_unavailable","grant sync failed")}const i=s(e);if(v(i,n))return;u(e),c.set(e,Math.max(n,c.get(e)??0)),w({level:"error",event:"daemon.grants.behind_token",fields:{grant:e,token_rev:n,mirror_rev:i?.rev??0}})}throw s(e)?new a(503,"service_unavailable","the directory answered grant sync below the access token's grant revision"):new a(401,"grant_revoked","grant is not active")}r(p,"ensureCovers");function b(e,n,o){const t=h(e);if(!t||t.sub!==n||t.grantee!==o||m(t))throw new a(401,"grant_revoked","grant is not active");return t}r(b,"callerGrantOf");async function x(e,n,o,t,i){return await p(e,n,i),b(e,o,t)}r(x,"coverGrant");export{b as callerGrantOf,x as coverGrant,p as ensureCovers};
@@ -44,7 +44,9 @@ export declare function mirrorOnly(grant: Pick<GrantRecord, 'grantee'>): boolean
44
44
  export declare function localGrants(): GrantRecord[];
45
45
  /** Every mirrored grant, whatever its status. */
46
46
  export declare function allGrants(): GrantRecord[];
47
- /** The active form of a grant record read earlier, or null when it is not active or unparsable. */
47
+ /** Whether a grant's `expires_at` has passed. An unparsable time reads as expired (fail closed). */
48
+ export declare function grantExpired(grant: Pick<GrantRecord, 'expires_at'>): boolean;
49
+ /** The active form of a grant record read earlier, or null when it is not active, is past `expires_at`, or is unparsable. */
48
50
  export declare function activeRecord(grant: GrantRecord): ActiveGrant | null;
49
51
  /** `grant.get`'s `version`: an opaque string that changes exactly when what an app
50
52
  * reads from its grant changes — `rev`, `resolved_scopes` (order kept), `spend_cap`,
@@ -1,4 +1,4 @@
1
- var y=Object.defineProperty;var t=(e,r)=>y(e,"name",{value:r,configurable:!0});import{createHash as _}from"node:crypto";import{prepared as s}from"../sqlite-statements.js";import{parseScope as S}from"@north-light/identity";import{openDb as i,withCanvasWrite as v}from"../canvas/db.js";import{isUnsandboxedMachine as T}from"../runtime/unsandboxed.js";const m=["not_started","pending","ready","failed","unavailable"];function c(e){if(!Array.isArray(e))throw new TypeError("grant scopes must be a list");return e.map(r=>{if(!r||typeof r!="object"||typeof r.scope!="string"||!["always","ask"].includes(r.mode))throw new TypeError("invalid grant scope entry");return{scope:r.scope,mode:r.mode}})}t(c,"entries");function O(e){if(!e||typeof e!="object"||Array.isArray(e))return null;const{state:r,message:a,next:u,step:n}=e;return typeof r!="string"||!m.includes(r)||a!==void 0&&typeof a!="string"||n!==void 0&&typeof n!="string"||typeof u!="string"||!u?null:{state:r,...a===void 0?{}:{message:a},next:u,...n===void 0?{}:{step:n}}}t(O,"dependencyOf");function E(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const r={};for(const[a,u]of Object.entries(e)){const n=O(u);n&&(r[a]=n)}return r}t(E,"dependenciesOf");function l(e){return{id:e.id,runtime:e.runtime,sub:e.sub,grantee:e.grantee,rev:e.rev,scopes:c(JSON.parse(e.scopes_json)),resolved_scopes:c(JSON.parse(e.resolved_scopes_json)),spend_cap:e.spend_cap,expires_at:e.expires_at,status:e.status,revoked_at:e.revoked_at,approved_at:e.approved_at,payer:e.payer,dependencies:E(JSON.parse(e.dependencies_json)),run_notice_url:e.run_notice_url??null,synced_at:e.synced_at}}t(l,"record");function p(e){if(!e||e.status!=="active")return null;try{return x(l(e))}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(p,"active");function d(e){return e.grantee!=="app:terminal"&&T()}t(d,"mirrorOnly");function M(){return R().filter(e=>!d(e))}t(M,"localGrants");function R(){return s(i(),"SELECT * FROM grants").all().flatMap(e=>{try{return[l(e)]}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return[];throw r}})}t(R,"allGrants");function x(e){if(e.status!=="active")return null;try{const r=e.resolved_scopes.map(({scope:a})=>S(a));return{...e,resolved:e.resolved_scopes.flatMap(({mode:a},u)=>a==="always"?[r[u]]:[])}}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(x,"activeRecord");function f(e){return Array.isArray(e)?`[${e.map(f).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().filter(r=>e[r]!==void 0).map(r=>`${JSON.stringify(r)}:${f(e[r])}`).join(",")}}`:JSON.stringify(e)??"null"}t(f,"canonicalJson");function b(e){const r={rev:e.rev,resolved_scopes:e.resolved_scopes,spend_cap:e.spend_cap,payer:e.payer,dependencies:e.dependencies??{}};return _("sha256").update(f(r)).digest("base64url").slice(0,22)}t(b,"grantVersion");function k(e){return!!s(i(),"SELECT 1 FROM grants WHERE id = ?").get(e)}t(k,"hasGrant");function H(e){return s(i(),"SELECT rev, status FROM grants WHERE id = ?").get(e)??null}t(H,"grantSyncState");function W(e,r){return s(i(),"SELECT rev, status FROM grants WHERE grantee = ? AND sub = ?").get(e,r)??null}t(W,"grantSyncStateFor");function j(e){const r=s(i(),"SELECT * FROM grants WHERE id = ?").get(e);if(!r)return null;try{return l(r)}catch(a){if(a instanceof TypeError||a instanceof SyntaxError)return null;throw a}}t(j,"grantRecord");function D(e){return p(s(i(),"SELECT * FROM grants WHERE id = ?").get(e))}t(D,"activeGrant");function G(e,r){return p(s(i(),"SELECT * FROM grants WHERE grantee = ? AND sub = ?").get(e,r))}t(G,"grantFor");function I(e){if(d({grantee:e}))return null;const r=s(i(),"SELECT * FROM grants WHERE grantee = ? AND status = 'active'").all(e);if(r.length>1)throw new Error(`multiple active grants for ${e}`);return p(r[0])}t(I,"activeGrantForApp");function J(e){const r=s(i(),"SELECT run_notice_url AS url, sub, grantee FROM grants WHERE id = ? AND status = 'active'").get(e);return r&&r.url&&!d(r)?{url:r.url,sub:r.sub,grantee:r.grantee}:null}t(J,"runNoticeTarget");function U(){const e=s(i(),"SELECT * FROM grants WHERE grantee = 'app:terminal' AND status = 'active'").all();if(e.length>1)throw new Error("multiple active terminal grants");return p(e[0])}t(U,"terminalGrant");function w(){return s(i(),"SELECT value FROM runtime_state WHERE key = 'grants_source'").get()?.value??null}t(w,"grantsSource");function $(e){return s(i(),"SELECT value FROM runtime_state WHERE key = 'grants_source'").get()?.value===e}t($,"hasSyncedGrants");function V(e){return s(e,"SELECT value FROM runtime_state WHERE key = 'grants_source'").get()?.value!=="local"?0:(s(e,"DELETE FROM runtime_state WHERE key = 'grants_source'").run(),Number(s(e,"DELETE FROM grants").run().changes))}t(V,"dropLocalGrantMirror");function P(e,r,a){const u=new Set;for(const n of e){if(u.has(n.id)||!n.id||!n.runtime||!n.sub||!n.grantee||!Number.isInteger(n.rev)||!["active","revoked","removed"].includes(n.status))throw new TypeError("invalid grant sync response");u.add(n.id),c(n.scopes),c(n.resolved_scopes)}v(n=>{n.exec("DELETE FROM grants");const g=s(n,`INSERT INTO grants
1
+ var _=Object.defineProperty;var t=(e,r)=>_(e,"name",{value:r,configurable:!0});import{createHash as y}from"node:crypto";import{prepared as s}from"../sqlite-statements.js";import{parseScope as S}from"@north-light/identity";import{openDb as i,withCanvasWrite as v}from"../canvas/db.js";import{isUnsandboxedMachine as T}from"../runtime/unsandboxed.js";const m=["not_started","pending","ready","failed","unavailable"];function c(e){if(!Array.isArray(e))throw new TypeError("grant scopes must be a list");return e.map(r=>{if(!r||typeof r!="object"||typeof r.scope!="string"||!["always","ask"].includes(r.mode))throw new TypeError("invalid grant scope entry");return{scope:r.scope,mode:r.mode}})}t(c,"entries");function O(e){if(!e||typeof e!="object"||Array.isArray(e))return null;const{state:r,message:a,next:u,step:n}=e;return typeof r!="string"||!m.includes(r)||a!==void 0&&typeof a!="string"||n!==void 0&&typeof n!="string"||typeof u!="string"||!u?null:{state:r,...a===void 0?{}:{message:a},next:u,...n===void 0?{}:{step:n}}}t(O,"dependencyOf");function E(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const r={};for(const[a,u]of Object.entries(e)){const n=O(u);n&&(r[a]=n)}return r}t(E,"dependenciesOf");function l(e){return{id:e.id,runtime:e.runtime,sub:e.sub,grantee:e.grantee,rev:e.rev,scopes:c(JSON.parse(e.scopes_json)),resolved_scopes:c(JSON.parse(e.resolved_scopes_json)),spend_cap:e.spend_cap,expires_at:e.expires_at,status:e.status,revoked_at:e.revoked_at,approved_at:e.approved_at,payer:e.payer,dependencies:E(JSON.parse(e.dependencies_json)),run_notice_url:e.run_notice_url??null,synced_at:e.synced_at}}t(l,"record");function p(e){if(!e||e.status!=="active")return null;try{return N(l(e))}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(p,"active");function d(e){return e.grantee!=="app:terminal"&&T()}t(d,"mirrorOnly");function b(){return R().filter(e=>!d(e))}t(b,"localGrants");function R(){return s(i(),"SELECT * FROM grants").all().flatMap(e=>{try{return[l(e)]}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return[];throw r}})}t(R,"allGrants");function x(e){return e.expires_at!==null&&!(Date.parse(e.expires_at)>Date.now())}t(x,"grantExpired");function N(e){if(e.status!=="active"||x(e))return null;try{const r=e.resolved_scopes.map(({scope:a})=>S(a));return{...e,resolved:e.resolved_scopes.flatMap(({mode:a},u)=>a==="always"?[r[u]]:[])}}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(N,"activeRecord");function f(e){return Array.isArray(e)?`[${e.map(f).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().filter(r=>e[r]!==void 0).map(r=>`${JSON.stringify(r)}:${f(e[r])}`).join(",")}}`:JSON.stringify(e)??"null"}t(f,"canonicalJson");function k(e){const r={rev:e.rev,resolved_scopes:e.resolved_scopes,spend_cap:e.spend_cap,payer:e.payer,dependencies:e.dependencies??{}};return y("sha256").update(f(r)).digest("base64url").slice(0,22)}t(k,"grantVersion");function D(e){return!!s(i(),"SELECT 1 FROM grants WHERE id = ?").get(e)}t(D,"hasGrant");function H(e){return s(i(),"SELECT rev, status FROM grants WHERE id = ?").get(e)??null}t(H,"grantSyncState");function W(e,r){return s(i(),"SELECT rev, status FROM grants WHERE grantee = ? AND sub = ?").get(e,r)??null}t(W,"grantSyncStateFor");function j(e){const r=s(i(),"SELECT * FROM grants WHERE id = ?").get(e);if(!r)return null;try{return l(r)}catch(a){if(a instanceof TypeError||a instanceof SyntaxError)return null;throw a}}t(j,"grantRecord");function G(e){return p(s(i(),"SELECT * FROM grants WHERE id = ?").get(e))}t(G,"activeGrant");function I(e,r){return p(s(i(),"SELECT * FROM grants WHERE grantee = ? AND sub = ?").get(e,r))}t(I,"grantFor");function J(e){if(d({grantee:e}))return null;const r=s(i(),"SELECT * FROM grants WHERE grantee = ? AND status = 'active'").all(e);if(r.length>1)throw new Error(`multiple active grants for ${e}`);return p(r[0])}t(J,"activeGrantForApp");function U(e){const r=s(i(),"SELECT run_notice_url AS url, sub, grantee FROM grants WHERE id = ? AND status = 'active'").get(e);return r&&r.url&&!d(r)?{url:r.url,sub:r.sub,grantee:r.grantee}:null}t(U,"runNoticeTarget");function w(){const e=s(i(),"SELECT * FROM grants WHERE grantee = 'app:terminal' AND status = 'active'").all();if(e.length>1)throw new Error("multiple active terminal grants");return p(e[0])}t(w,"terminalGrant");function $(){return s(i(),"SELECT value FROM runtime_state WHERE key = 'grants_source'").get()?.value??null}t($,"grantsSource");function V(e){return s(i(),"SELECT value FROM runtime_state WHERE key = 'grants_source'").get()?.value===e}t(V,"hasSyncedGrants");function P(e){return s(e,"SELECT value FROM runtime_state WHERE key = 'grants_source'").get()?.value!=="local"?0:(s(e,"DELETE FROM runtime_state WHERE key = 'grants_source'").run(),Number(s(e,"DELETE FROM grants").run().changes))}t(P,"dropLocalGrantMirror");function X(e,r,a){const u=new Set;for(const n of e){if(u.has(n.id)||!n.id||!n.runtime||!n.sub||!n.grantee||!Number.isInteger(n.rev)||!["active","revoked","removed"].includes(n.status))throw new TypeError("invalid grant sync response");u.add(n.id),c(n.scopes),c(n.resolved_scopes)}v(n=>{n.exec("DELETE FROM grants");const g=s(n,`INSERT INTO grants
2
2
  (id, runtime, sub, grantee, rev, scopes_json, resolved_scopes_json, spend_cap, expires_at,
3
3
  status, revoked_at, approved_at, payer, dependencies_json, run_notice_url, synced_at)
4
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);for(const o of e)g.run(o.id,o.runtime,o.sub,o.grantee,o.rev,JSON.stringify(o.scopes),JSON.stringify(o.resolved_scopes),o.spend_cap,o.expires_at,o.status,o.revoked_at,o.approved_at,o.payer,JSON.stringify(E(o.dependencies)),o.run_notice_url??null,o.synced_at);s(n,"INSERT INTO runtime_state (key, value) VALUES ('grants_source', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(a),s(n,"INSERT INTO runtime_state (key, value) VALUES ('grants_generation', '1') ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT)").run()})}t(P,"replaceGrants");function X(){const e=s(i(),"SELECT value FROM runtime_state WHERE key = 'grants_generation'").get();return e?Number(e.value):0}t(X,"grantsGeneration");export{D as activeGrant,I as activeGrantForApp,x as activeRecord,R as allGrants,E as dependenciesOf,V as dropLocalGrantMirror,G as grantFor,j as grantRecord,H as grantSyncState,W as grantSyncStateFor,b as grantVersion,X as grantsGeneration,w as grantsSource,k as hasGrant,$ as hasSyncedGrants,M as localGrants,d as mirrorOnly,P as replaceGrants,J as runNoticeTarget,U as terminalGrant};
4
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);for(const o of e)g.run(o.id,o.runtime,o.sub,o.grantee,o.rev,JSON.stringify(o.scopes),JSON.stringify(o.resolved_scopes),o.spend_cap,o.expires_at,o.status,o.revoked_at,o.approved_at,o.payer,JSON.stringify(E(o.dependencies)),o.run_notice_url??null,o.synced_at);s(n,"INSERT INTO runtime_state (key, value) VALUES ('grants_source', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(a),s(n,"INSERT INTO runtime_state (key, value) VALUES ('grants_generation', '1') ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT)").run()})}t(X,"replaceGrants");function q(){const e=s(i(),"SELECT value FROM runtime_state WHERE key = 'grants_generation'").get();return e?Number(e.value):0}t(q,"grantsGeneration");export{G as activeGrant,J as activeGrantForApp,N as activeRecord,R as allGrants,E as dependenciesOf,P as dropLocalGrantMirror,x as grantExpired,I as grantFor,j as grantRecord,H as grantSyncState,W as grantSyncStateFor,k as grantVersion,q as grantsGeneration,$ as grantsSource,D as hasGrant,V as hasSyncedGrants,b as localGrants,d as mirrorOnly,X as replaceGrants,U as runNoticeTarget,w as terminalGrant};
@@ -2,3 +2,7 @@
2
2
  export declare class PageAuthoringError extends Error {
3
3
  constructor(message: string);
4
4
  }
5
+ /** The page compiler itself failed; the page is not at fault, so callers must not report it as bad page input. */
6
+ export declare class PageCompilerError extends Error {
7
+ constructor(message: string);
8
+ }
@@ -1 +1 @@
1
- var t=Object.defineProperty;var e=(o,r)=>t(o,"name",{value:r,configurable:!0});class n extends Error{static{e(this,"PageAuthoringError")}constructor(r){super(r),this.name="PageAuthoringError"}}export{n as PageAuthoringError};
1
+ var s=Object.defineProperty;var o=(e,r)=>s(e,"name",{value:r,configurable:!0});class a extends Error{static{o(this,"PageAuthoringError")}constructor(r){super(r),this.name="PageAuthoringError"}}class n extends Error{static{o(this,"PageCompilerError")}constructor(r){super(r),this.name="PageCompilerError"}}export{a as PageAuthoringError,n as PageCompilerError};
@@ -1,9 +1,16 @@
1
1
  import type { ProductPageComponents } from '../../types.js';
2
2
  import { type PageDelivery, type PageManifest, type PageSource } from './page-schema.js';
3
- import { PageAuthoringError } from './page-errors.js';
4
- export { PageAuthoringError };
3
+ import { PageAuthoringError, PageCompilerError } from './page-errors.js';
4
+ export { PageAuthoringError, PageCompilerError };
5
5
  /** Compile one authored TSX page to the CommonJS module the Gateway evaluates.
6
- * Registry names stay free identifiers; the Gateway supplies them at eval. */
6
+ * Registry names stay free identifiers; the Gateway supplies them at eval.
7
+ *
8
+ * esbuild's sync API keeps one service child process for the life of the host, and the
9
+ * long-lived daemon outlives it: once that child dies every later transform throws "The
10
+ * service is no longer running". A page's own compile failure always carries a located
11
+ * `errors` list; an error without one is the service failing, so stop the handle (the next
12
+ * call starts a fresh service) and retry once. A failure that survives the retry is a
13
+ * PageCompilerError, never a PageAuthoringError, so it is not blamed on the page. */
7
14
  export declare function compilePage(document: string): string;
8
15
  /** Derive the transport manifest from one authored TSX page document. */
9
16
  export declare function derivePageManifestFromDocument(document: string, productComponents?: ProductPageComponents, source?: PageSource, delivery?: PageDelivery): PageManifest;
@@ -1 +1 @@
1
- var q=Object.defineProperty;var i=(t,e)=>q(t,"name",{value:e,configurable:!0});import{readFileSync as v}from"node:fs";import{createRequire as C}from"node:module";import{join as D}from"node:path";import{BUILTIN_KIND_BY_TAG as O,BUILTIN_PAGE_COMPONENT_TAGS as M,DISPLAY_PAGE_COMPONENT_TAGS as L,pageComponentTag as E}from"./page-catalog.js";import{isResponseBearingSlot as R,pageDeliverySchema as F,validateAuthoredPageManifest as B,validatePageManifest as G}from"./page-schema.js";import{evaluatePageTree as J,jsonProps as K}from"./page-eval.js";import{PageAuthoringError as o}from"./page-errors.js";const T=C(import.meta.url);let U,X;function H(){return U??=T("esbuild")}i(H,"esbuild");function $(){return X??=T("typescript")}i($,"typescript");function k(t){return t instanceof o?t:new o(t instanceof Error?t.message:String(t))}i(k,"asPageAuthoringError");function A(t,e){try{const n=B(t,e),r=n.slots.filter(R);if(r.length>=2)for(const s of r){const c=s.config.label;if(typeof c!="string"||c==="")throw new o(`response-bearing slot "${s.id}" requires a nonempty config.label when the page has multiple response-bearing slots`)}return n}catch(n){throw k(n)}}i(A,"validateAuthoredManifest");const Y="a page is evaluated with React and every registry component already in scope, so it takes no imports \u2014 write `<Page>`, `<UserQuestion>`, `<Card>` and friends directly.";function z(t){try{return H().transformSync(t,{loader:"tsx",format:"cjs",jsx:"transform",jsxFactory:"React.createElement",jsxFragment:"React.Fragment",target:"es2020",sourcefile:"page.tsx"}).code}catch(e){const r=e.errors?.[0];if(r===void 0)throw k(e);const s=r.location==null?"":` (page.tsx:${r.location.line}:${r.location.column})`;throw new o(`page does not compile: ${r.text??"unknown error"}${s}`)}}i(z,"compilePage");function Q(t){const e=$();return e.createSourceFile("page.tsx",t,e.ScriptTarget.ES2022,!0,e.ScriptKind.TSX)}i(Q,"parseTsx");function j(t,e){e(t),t.forEachChild(n=>j(n,e))}i(j,"eachNode");function V(t){const e=$();let n;if(j(t,r=>{n===void 0&&(e.isImportDeclaration(r)||e.isImportEqualsDeclaration(r)?n="import":e.isExportDeclaration(r)&&r.moduleSpecifier!==void 0?n="export \u2026 from":e.isCallExpression(r)&&(r.expression.kind===e.SyntaxKind.ImportKeyword?n="dynamic import()":e.isIdentifier(r.expression)&&r.expression.text==="require"&&(n="require()")))}),n!==void 0)throw new o(`page source uses ${n}: ${Y}`)}i(V,"rejectModulePlumbing");function I(t,e){const n=t[e];if(n!==void 0){if(typeof n!="string")throw new o(`<Page> prop ${e} must be a string; it is part of the page manifest`);return n}}i(I,"stringProp");function W(t,e,n){V(Q(t));const r=[...M,...L,...n.map(l=>E(l.kind))],s=J(e,r),c=[],h=i(l=>{for(const a of l)a.kind!=="text"&&(a.tag==="Page"&&c.push(a),h(a.children))},"collectPages");if(h(s),c.length===0)throw new o('page default export must render exactly one <Page title="\u2026"> root; it rendered none');if(c.length>1)throw new o(`page default export renders ${c.length} <Page> elements; exactly one is allowed`);const d=c[0],w=(I(d.props,"title")??"").trim();if(w==="")throw new o("<Page> requires a nonempty title prop");const g=I(d.props,"subtitle")?.trim();if(d.props.placement!==void 0)throw new o("<Page> placement is not authored; choose --placement inline or --placement panel when sending the page.");const f=new Map;for(const l of n){const a=E(l.kind);if(M.has(a))throw new o(`product page component kind "${l.kind}" derives JSX tag "${a}", which collides with a built-in page component`);if(f.has(a))throw new o(`product page component kind "${l.kind}" derives JSX tag "${a}", which duplicates product page component kind "${f.get(a)}"`);f.set(a,l.kind)}const x=[];let y=0;const P=i((l,a)=>{for(const p of l){if(p.kind==="text")continue;const S=p.tag==="Step"?y++:a,m=O[p.tag],b=f.get(p.tag);if(m!==void 0||b!==void 0){const{id:u,..._}=K(p.props);if(u!==void 0&&typeof u!="string")throw new o(`<${p.tag}> id prop must be a string`);x.push({...u===void 0?{}:{id:u},kind:m??b,step:S,config:_,...m===void 0?{unvalidated:!0}:{}})}P(p.children,S)}},"collectSlots");return P(d.children,0),{title:w,...g===void 0||g===""?{}:{subtitle:g},steps:Math.max(y,1),slots:x}}i(W,"scanPage");function Z(t,e=[],n,r={placement:"inline",inbox:!1,reply:!1}){const s=W(t,z(t),e);return A({schema:"crtr.page/v2",dialect:"jsx",title:s.title,...s.subtitle===void 0?{}:{subtitle:s.subtitle},delivery:r,document:"page.tsx",steps:s.steps,slots:s.slots,...n===void 0?{}:{source:n}},e)}i(Z,"derivePageManifestFromDocument");function ee(t){const e=/<title\b[^>]*>([\s\S]*?)<\/title\s*>/i.exec(t)?.[1]?.replace(/<[^>]+>/g,"").trim();if(e===void 0||e==="")throw new o("HTML page requires a nonempty <title>.");const n=[...t.matchAll(/<meta\b[^>]*>/gi)].map(r=>r[0]).map(r=>{const s=new Map([...r.matchAll(/\b([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/g)].map(c=>[c[1].toLowerCase(),c[3]]));return s.get("name")?.toLowerCase()==="description"?s.get("content")?.trim():void 0}).find(r=>r!==void 0);return{title:e,...n===void 0||n===""?{}:{subtitle:n}}}i(ee,"htmlMetadata");function le(t,e,n={placement:"inline",inbox:!1,reply:!1}){const r=ee(t);return A({schema:"crtr.page/v2",dialect:"html",...r,delivery:n,document:"page.html",steps:1,slots:[],...e===void 0?{}:{source:e}},[])}i(le,"deriveHtmlPageManifest");function pe(t,e=[],n,r){return Z(v(t,"utf8"),e,n,r)}i(pe,"derivePageManifest");function N(t){try{return JSON.parse(v(D(t,"page.json"),"utf8"))}catch{throw new o("page.json is not valid JSON")}}i(N,"readPageJson");function de(t){return G(N(t))}i(de,"parsePage");function fe(t){const e=N(t),n=F.safeParse(typeof e=="object"&&e!==null&&!Array.isArray(e)?e.delivery:void 0);if(!n.success)throw new o("page.json has an invalid delivery envelope");return n.data}i(fe,"parsePageDelivery");export{o as PageAuthoringError,z as compilePage,le as deriveHtmlPageManifest,pe as derivePageManifest,Z as derivePageManifestFromDocument,de as parsePage,fe as parsePageDelivery};
1
+ var q=Object.defineProperty;var i=(t,e)=>q(t,"name",{value:e,configurable:!0});import{readFileSync as v}from"node:fs";import{createRequire as D}from"node:module";import{join as O}from"node:path";import{BUILTIN_KIND_BY_TAG as L,BUILTIN_PAGE_COMPONENT_TAGS as E,DISPLAY_PAGE_COMPONENT_TAGS as R,pageComponentTag as M}from"./page-catalog.js";import{isResponseBearingSlot as F,pageDeliverySchema as B,validateAuthoredPageManifest as G,validatePageManifest as J}from"./page-schema.js";import{evaluatePageTree as K,jsonProps as U}from"./page-eval.js";import{PageAuthoringError as s,PageCompilerError as $}from"./page-errors.js";const T=D(import.meta.url);let X,H;function k(){return X??=T("esbuild")}i(k,"esbuild");function A(){return H??=T("typescript")}i(A,"typescript");function Y(t){return t instanceof s?t:new s(t instanceof Error?t.message:String(t))}i(Y,"asPageAuthoringError");function j(t,e){try{const n=G(t,e),r=n.slots.filter(F);if(r.length>=2)for(const o of r){const a=o.config.label;if(typeof a!="string"||a==="")throw new s(`response-bearing slot "${o.id}" requires a nonempty config.label when the page has multiple response-bearing slots`)}return n}catch(n){throw Y(n)}}i(j,"validateAuthoredManifest");const z="a page is evaluated with React and every registry component already in scope, so it takes no imports \u2014 write `<Page>`, `<UserQuestion>`, `<Card>` and friends directly.";function Q(t){return k().transformSync(t,{loader:"tsx",format:"cjs",jsx:"transform",jsxFactory:"React.createElement",jsxFragment:"React.Fragment",target:"es2020",sourcefile:"page.tsx"}).code}i(Q,"transformPage");function V(t){let e;for(let n=0;n<2;n++)try{return Q(t)}catch(r){const o=r.errors?.[0];if(o!==void 0){const a=o.location==null?"":` (page.tsx:${o.location.line}:${o.location.column})`;throw new s(`page does not compile: ${o.text??"unknown error"}${a}`)}e=r,k().stop()}throw new $(`page compiler (esbuild) service failed and did not recover after a restart: ${e instanceof Error?e.message:String(e)}`)}i(V,"compilePage");function W(t){const e=A();return e.createSourceFile("page.tsx",t,e.ScriptTarget.ES2022,!0,e.ScriptKind.TSX)}i(W,"parseTsx");function I(t,e){e(t),t.forEachChild(n=>I(n,e))}i(I,"eachNode");function Z(t){const e=A();let n;if(I(t,r=>{n===void 0&&(e.isImportDeclaration(r)||e.isImportEqualsDeclaration(r)?n="import":e.isExportDeclaration(r)&&r.moduleSpecifier!==void 0?n="export \u2026 from":e.isCallExpression(r)&&(r.expression.kind===e.SyntaxKind.ImportKeyword?n="dynamic import()":e.isIdentifier(r.expression)&&r.expression.text==="require"&&(n="require()")))}),n!==void 0)throw new s(`page source uses ${n}: ${z}`)}i(Z,"rejectModulePlumbing");function N(t,e){const n=t[e];if(n!==void 0){if(typeof n!="string")throw new s(`<Page> prop ${e} must be a string; it is part of the page manifest`);return n}}i(N,"stringProp");function ee(t,e,n){Z(W(t));const r=[...E,...R,...n.map(l=>M(l.kind))],o=K(e,r),a=[],h=i(l=>{for(const c of l)c.kind!=="text"&&(c.tag==="Page"&&a.push(c),h(c.children))},"collectPages");if(h(o),a.length===0)throw new s('page default export must render exactly one <Page title="\u2026"> root; it rendered none');if(a.length>1)throw new s(`page default export renders ${a.length} <Page> elements; exactly one is allowed`);const f=a[0],w=(N(f.props,"title")??"").trim();if(w==="")throw new s("<Page> requires a nonempty title prop");const g=N(f.props,"subtitle")?.trim();if(f.props.placement!==void 0)throw new s("<Page> placement is not authored; choose --placement inline or --placement panel when sending the page.");const d=new Map;for(const l of n){const c=M(l.kind);if(E.has(c))throw new s(`product page component kind "${l.kind}" derives JSX tag "${c}", which collides with a built-in page component`);if(d.has(c))throw new s(`product page component kind "${l.kind}" derives JSX tag "${c}", which duplicates product page component kind "${d.get(c)}"`);d.set(c,l.kind)}const x=[];let y=0;const P=i((l,c)=>{for(const p of l){if(p.kind==="text")continue;const S=p.tag==="Step"?y++:c,m=L[p.tag],b=d.get(p.tag);if(m!==void 0||b!==void 0){const{id:u,...C}=U(p.props);if(u!==void 0&&typeof u!="string")throw new s(`<${p.tag}> id prop must be a string`);x.push({...u===void 0?{}:{id:u},kind:m??b,step:S,config:C,...m===void 0?{unvalidated:!0}:{}})}P(p.children,S)}},"collectSlots");return P(f.children,0),{title:w,...g===void 0||g===""?{}:{subtitle:g},steps:Math.max(y,1),slots:x}}i(ee,"scanPage");function te(t,e=[],n,r={placement:"inline",inbox:!1,reply:!1}){const o=ee(t,V(t),e);return j({schema:"crtr.page/v2",dialect:"jsx",title:o.title,...o.subtitle===void 0?{}:{subtitle:o.subtitle},delivery:r,document:"page.tsx",steps:o.steps,slots:o.slots,...n===void 0?{}:{source:n}},e)}i(te,"derivePageManifestFromDocument");function ne(t){const e=/<title\b[^>]*>([\s\S]*?)<\/title\s*>/i.exec(t)?.[1]?.replace(/<[^>]+>/g,"").trim();if(e===void 0||e==="")throw new s("HTML page requires a nonempty <title>.");const n=[...t.matchAll(/<meta\b[^>]*>/gi)].map(r=>r[0]).map(r=>{const o=new Map([...r.matchAll(/\b([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/g)].map(a=>[a[1].toLowerCase(),a[3]]));return o.get("name")?.toLowerCase()==="description"?o.get("content")?.trim():void 0}).find(r=>r!==void 0);return{title:e,...n===void 0||n===""?{}:{subtitle:n}}}i(ne,"htmlMetadata");function fe(t,e,n={placement:"inline",inbox:!1,reply:!1}){const r=ne(t);return j({schema:"crtr.page/v2",dialect:"html",...r,delivery:n,document:"page.html",steps:1,slots:[],...e===void 0?{}:{source:e}},[])}i(fe,"deriveHtmlPageManifest");function de(t,e=[],n,r){return te(v(t,"utf8"),e,n,r)}i(de,"derivePageManifest");function _(t){try{return JSON.parse(v(O(t,"page.json"),"utf8"))}catch{throw new s("page.json is not valid JSON")}}i(_,"readPageJson");function ue(t){return J(_(t))}i(ue,"parsePage");function ge(t){const e=_(t),n=B.safeParse(typeof e=="object"&&e!==null&&!Array.isArray(e)?e.delivery:void 0);if(!n.success)throw new s("page.json has an invalid delivery envelope");return n.data}i(ge,"parsePageDelivery");export{s as PageAuthoringError,$ as PageCompilerError,V as compilePage,fe as deriveHtmlPageManifest,de as derivePageManifest,te as derivePageManifestFromDocument,ue as parsePage,ge as parsePageDelivery};
@@ -1 +1 @@
1
- var g=Object.defineProperty;var c=(e,t)=>g(e,"name",{value:t,configurable:!0});import{prepared as d}from"../sqlite-statements.js";import{CrtrError as k}from"../errors.js";import{getById as S,getByRowid as L}from"../graph/objects.js";import{publish as O}from"../graph/events.js";import{markLinkWatch as h,recordWatch as x}from"../graph/watches.js";import{ackRows as A,claimRows as T}from"./outbox-store.js";import{ensureStub as E,stubOf as f}from"./stubs.js";const V=100,y=c((e,t)=>`peer:${e}:${t}`,"ingestKey");function $(e,t){return d(e,"SELECT 1 FROM peer_ingested WHERE key = ?").get(t)!==void 0?!0:d(e,"SELECT 1 FROM deliveries WHERE idempotency_key >= ? AND idempotency_key < ? LIMIT 1").get(`${t}:`,`${t};`)!==void 0}c($,"applied");const m=c((e,t,n)=>{d(e,"INSERT OR IGNORE INTO peer_ingested_destinations (key, ingested_at) VALUES (?, ?)").run(`${t}:${n}`,Date.now())},"markDestination");function w(e,t,n){return d(e,"SELECT 1 FROM peer_ingested_destinations WHERE key = ?").get(`${t}:${n}`)!==void 0||d(e,"SELECT 1 FROM deliveries WHERE idempotency_key = ?").get(`${t}:${n}`)!==void 0}c(w,"destinationDone");function N(e,t,n){return E(e,t.id,t.type,n,void 0,t)}c(N,"actorFor");function _(e,t,n,r,i){const s=n.actor===null?null:N(e,n.actor,t),u=n.body_text,o=n.body===void 0&&u===void 0?void 0:{...n.body??{},...u===void 0?{}:{body:u}};O(e,{event:n.event,object:r,actor:s,level:n.level,attrs:n.attrs,...o===void 0?{}:{messageBody:o},idempotencyKey:y(t,n.message_id),...i===void 0?{}:{onlyWatchers:i}})}c(_,"apply");function I(e,t){const n=`ev:${t.message_id}:`;if(!t.key.startsWith(n)||t.key.length===n.length)return null;const r=S(e,t.key.slice(n.length));return r!==null&&r.type==="node"&&r.deleted_at===null&&f(e,r)===null?r:null}c(I,"localDestination");function K(e,t,n){const r={accepted:[],rejected:[]};for(const i of n){const s=y(t,i.message_id),u=$(e,s);e.exec("SAVEPOINT peer_event");try{const o=I(e,i);if(u&&o===null){e.exec("RELEASE peer_event"),r.accepted.push(i.key);continue}const l=E(e,i.object.id,i.object.type,t,void 0,i.object),a=i.linked===!0&&o!==null&&l.owner!==null?L(e,l.owner):null,p=a!==null&&a.type==="app"?a:null;if(o!==null&&d(e,"SELECT 1 FROM watches WHERE watcher = ? AND object = ?").get(o.rowid,l.rowid)===void 0?x(e,o,l,"act",{patterns:[">"],...p===null?{}:{linkApp:p}}):o!==null&&p!==null&&h(e,o,l,p),u)w(e,s,o.id)||_(e,t,i,l,[o.id]);else{_(e,t,i,l),d(e,"INSERT OR IGNORE INTO peer_ingested (key, ingested_at) VALUES (?, ?)").run(s,Date.now());for(const R of d(e,"SELECT destination_id FROM deliveries WHERE idempotency_key >= ? AND idempotency_key < ?").all(`${s}:`,`${s};`))m(e,s,R.destination_id)}o!==null&&m(e,s,o.id),e.exec("RELEASE peer_event"),r.accepted.push(i.key)}catch(o){e.exec("ROLLBACK TO peer_event"),e.exec("RELEASE peer_event");const l=o instanceof k?o.code:"invalid_event";r.rejected.push({key:i.key,code:l,message:o instanceof Error?o.message:String(o)})}}return r}c(K,"ingestPeerEvents");const P=c((e,t,n)=>f(e,t)?.home_machine===n,"isStubOf"),v=c((e,t,n)=>T(e,t,n),"claimFor"),G=c((e,t,n)=>A(e,t,n),"ackFor");export{V as MAX_EVENTS_PER_CALL,G as ackFor,v as claimFor,y as ingestKey,K as ingestPeerEvents,P as isStubOf};
1
+ var g=Object.defineProperty;var c=(e,t)=>g(e,"name",{value:t,configurable:!0});import{prepared as d}from"../sqlite-statements.js";import{CrtrError as k}from"../errors.js";import{getById as S,getByRowid as O}from"../graph/objects.js";import{publish as L}from"../graph/events.js";import{markLinkWatch as h,recordWatch as A}from"../graph/watches.js";import{ackRows as x,claimRows as T}from"./outbox-store.js";import{ensureStub as E,localOwnerActor as w,stubOf as f}from"./stubs.js";const K=100,y=c((e,t)=>`peer:${e}:${t}`,"ingestKey");function $(e,t){return d(e,"SELECT 1 FROM peer_ingested WHERE key = ?").get(t)!==void 0?!0:d(e,"SELECT 1 FROM deliveries WHERE idempotency_key >= ? AND idempotency_key < ? LIMIT 1").get(`${t}:`,`${t};`)!==void 0}c($,"applied");const m=c((e,t,n)=>{d(e,"INSERT OR IGNORE INTO peer_ingested_destinations (key, ingested_at) VALUES (?, ?)").run(`${t}:${n}`,Date.now())},"markDestination");function N(e,t,n){return d(e,"SELECT 1 FROM peer_ingested_destinations WHERE key = ?").get(`${t}:${n}`)!==void 0||d(e,"SELECT 1 FROM deliveries WHERE idempotency_key = ?").get(`${t}:${n}`)!==void 0}c(N,"destinationDone");function I(e,t,n){return w(e,t)??E(e,t.id,t.type,n,void 0,t)}c(I,"actorFor");function _(e,t,n,r,i){const s=n.actor===null?null:I(e,n.actor,t),u=n.body_text,o=n.body===void 0&&u===void 0?void 0:{...n.body??{},...u===void 0?{}:{body:u}};L(e,{event:n.event,object:r,actor:s,level:n.level,attrs:n.attrs,...o===void 0?{}:{messageBody:o},idempotencyKey:y(t,n.message_id),...i===void 0?{}:{onlyWatchers:i}})}c(_,"apply");function C(e,t){const n=`ev:${t.message_id}:`;if(!t.key.startsWith(n)||t.key.length===n.length)return null;const r=S(e,t.key.slice(n.length));return r!==null&&r.type==="node"&&r.deleted_at===null&&f(e,r)===null?r:null}c(C,"localDestination");function P(e,t,n){const r={accepted:[],rejected:[]};for(const i of n){const s=y(t,i.message_id),u=$(e,s);e.exec("SAVEPOINT peer_event");try{const o=C(e,i);if(u&&o===null){e.exec("RELEASE peer_event"),r.accepted.push(i.key);continue}const l=E(e,i.object.id,i.object.type,t,void 0,i.object),a=i.linked===!0&&o!==null&&l.owner!==null?O(e,l.owner):null,p=a!==null&&a.type==="app"?a:null;if(o!==null&&d(e,"SELECT 1 FROM watches WHERE watcher = ? AND object = ?").get(o.rowid,l.rowid)===void 0?A(e,o,l,"act",{patterns:[">"],...p===null?{}:{linkApp:p}}):o!==null&&p!==null&&h(e,o,l,p),u)N(e,s,o.id)||_(e,t,i,l,[o.id]);else{_(e,t,i,l),d(e,"INSERT OR IGNORE INTO peer_ingested (key, ingested_at) VALUES (?, ?)").run(s,Date.now());for(const R of d(e,"SELECT destination_id FROM deliveries WHERE idempotency_key >= ? AND idempotency_key < ?").all(`${s}:`,`${s};`))m(e,s,R.destination_id)}o!==null&&m(e,s,o.id),e.exec("RELEASE peer_event"),r.accepted.push(i.key)}catch(o){e.exec("ROLLBACK TO peer_event"),e.exec("RELEASE peer_event");const l=o instanceof k?o.code:"invalid_event";r.rejected.push({key:i.key,code:l,message:o instanceof Error?o.message:String(o)})}}return r}c(P,"ingestPeerEvents");const v=c((e,t,n)=>f(e,t)?.home_machine===n,"isStubOf"),G=c((e,t,n)=>T(e,t,n),"claimFor"),U=c((e,t,n)=>x(e,t,n),"ackFor");export{K as MAX_EVENTS_PER_CALL,U as ackFor,G as claimFor,y as ingestKey,P as ingestPeerEvents,v as isStubOf};
@@ -52,6 +52,10 @@ export interface StubRecord {
52
52
  export declare const identityOfEnvelope: (envelope: Envelope) => StubIdentity;
53
53
  export declare function stubOf(db: DatabaseSync, object: ObjectRow | string): StubRecord | null;
54
54
  export declare const isStub: (db: DatabaseSync, object: ObjectRow) => boolean;
55
+ /** The local object for an app or person the other machine names as an event's actor, or null for any other type. An app or person is an
56
+ * owner, not a thing that lives on one machine: it is the same object here as there, so it is never given a stub (a stub would collide
57
+ * with the local owner object of the same handle, as with an installed plugin's app). */
58
+ export declare function localOwnerActor(db: DatabaseSync, ref: ObjectRef): ObjectRow | null;
55
59
  /**
56
60
  * The stub of the object `id` that lives on `machine`, created on first sight. Idempotent: a second
57
61
  * call returns the same row and, given an `envelope`, replaces the identity it stores. Refuses
@@ -1 +1 @@
1
- var x=Object.defineProperty;var o=(n,e)=>x(n,"name",{value:e,configurable:!0});import{prepared as i}from"../sqlite-statements.js";import{createObject as A,ensureOwner as _,getById as h,getByRowid as p}from"../graph/objects.js";import{upsertKind as b}from"../graph/custom.js";import{CrtrError as E}from"../errors.js";import{ExitCode as f}from"../../types.js";import{normalizeMachineId as H}from"./names.js";const W=["public","friends","private"],D=o(n=>{const e=n.act.act;return e===void 0?{sub:n.sub,app:null,node:null,node_scopes:null,place:null}:{sub:n.sub,app:e.sub,node:e.node,node_scopes:e.node_scopes,place:e.place}},"identityOfEnvelope");function y(n,e){const r=typeof e=="string"?h(n,e):e;if(r===null)return null;const t=i(n,"SELECT home_machine, envelope_json FROM peer_stubs WHERE object = ?").get(r.rowid);return t?{object:r,home_machine:t.home_machine,identity:t.envelope_json===null?null:JSON.parse(t.envelope_json)}:null}o(y,"stubOf");const I=o((n,e)=>i(n,"SELECT 1 FROM peer_stubs WHERE object = ?").get(e.rowid)!==void 0,"isStub");function m(n){return _(n,"person","local-user","user:local","user")}o(m,"localPerson");function S(n,e){return e==="user:local"?m(n):_(n,"app","app",e,e.replace(/^app:/,""))}o(S,"localApp");function v(n,e,r){if(e!==null)return e.app===null?m(n):S(n,e.app);const t=r?.owner;return t?.type==="app"?S(n,t.external_id??`app:${t.handle}`):m(n)}o(v,"ownerFor");function N(n,e,r,t,w,u){const l=w===void 0?null:D(w),s=u?.privacy??"public";if(!W.includes(s))throw new E("invalid_event",`invalid privacy ${JSON.stringify(s)}`,f.GENERAL,{id:e});const c=h(n,e);if(c!==null){const d=y(n,c);if(d===null)throw new E("conflict",`${e} is a local ${c.type}, not a stub of ${t}`,f.GENERAL,{id:e});if(d.home_machine!==t)throw new E("conflict",`${e} is already a stub of ${d.home_machine}, not ${t}`,f.GENERAL,{id:e,home_machine:d.home_machine});return l!==null&&(i(n,"UPDATE peer_stubs SET envelope_json = ? WHERE object = ?").run(JSON.stringify(l),c.rowid),i(n,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(c.rowid)),u!==void 0&&(R(n,r,u),u.privacy!==void 0&&c.privacy!==s)?(i(n,"UPDATE objects SET privacy = ? WHERE rowid = ?").run(s,c.rowid),p(n,c.rowid)):c}const O=v(n,l,u);R(n,r,u);const a=A(n,{id:e,type:r,kind:u?.kind??null,owner:O.rowid,privacy:s,name:u?.name??e,preview:u?.preview??""});return i(n,"UPDATE objects SET home_machine = ? WHERE rowid = ?").run(t,a.rowid),i(n,"INSERT INTO peer_stubs (object, home_machine, envelope_json, created_at) VALUES (?, ?, ?, ?)").run(a.rowid,t,l===null?null:JSON.stringify(l),new Date().toISOString()),l!==null&&i(n,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(a.rowid),p(n,a.rowid)}o(N,"ensureStub");function R(n,e,r){const t=r?.kind_decl;t===void 0||t.name!==e||b(n,{name:t.name,owner:v(n,null,{...r,owner:t.owner}),description:t.description,events:t.events,read:null,source:"peer"})}o(R,"holdKind");function F(n,e,r){const t=N(n,e,"node",H(r));return i(n,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(t.rowid),p(n,t.rowid)}o(F,"ensureNodeStub");function J(n,e,r){const t=y(n,e);t===null||t.home_machine===r||(i(n,"UPDATE peer_stubs SET home_machine = ? WHERE object = ?").run(r,t.object.rowid),i(n,"UPDATE objects SET home_machine = ? WHERE rowid = ?").run(r,t.object.rowid))}o(J,"rehomeStub");function M(n,e){const r=j(n,e.owner===null?null:p(n,e.owner)),t=T(n,e.type);return{id:e.id,type:e.type,kind:e.kind,name:e.name,preview:e.preview,owner:r,privacy:e.privacy,...t===null?{}:{kind_decl:t}}}o(M,"describeObject");function j(n,e){if(e===null||e.type!=="person"&&e.type!=="app"&&e.type!=="repo"&&e.type!=="profile")return null;const r=i(n,"SELECT scheme, external_id FROM identities WHERE object = ?").get(e.rowid);return{id:e.id,type:e.type,scheme:r?.scheme??null,external_id:r?.external_id??null,handle:e.name}}o(j,"ownerRefOf");function T(n,e){const r=i(n,"SELECT owner, description, events_json FROM object_kinds WHERE name = ?").get(e),t=r===void 0?null:j(n,p(n,r.owner));return r===void 0||t===null?null:{name:e,description:r.description,events:JSON.parse(r.events_json),owner:t}}o(T,"kindDeclarationOf");function G(n,e,r){const t=T(n,e.type);return t===null?r:{...r,kind_decl:t}}o(G,"withKindDecl");export{M as describeObject,F as ensureNodeStub,N as ensureStub,D as identityOfEnvelope,I as isStub,T as kindDeclarationOf,J as rehomeStub,y as stubOf,G as withKindDecl};
1
+ var x=Object.defineProperty;var o=(n,e)=>x(n,"name",{value:e,configurable:!0});import{prepared as i}from"../sqlite-statements.js";import{createObject as A,ensureOwner as h,getById as y,getByRowid as p}from"../graph/objects.js";import{upsertKind as b}from"../graph/custom.js";import{CrtrError as f}from"../errors.js";import{ExitCode as m}from"../../types.js";import{normalizeMachineId as H}from"./names.js";const W=["public","friends","private"],D=o(n=>{const e=n.act.act;return e===void 0?{sub:n.sub,app:null,node:null,node_scopes:null,place:null}:{sub:n.sub,app:e.sub,node:e.node,node_scopes:e.node_scopes,place:e.place}},"identityOfEnvelope");function S(n,e){const r=typeof e=="string"?y(n,e):e;if(r===null)return null;const t=i(n,"SELECT home_machine, envelope_json FROM peer_stubs WHERE object = ?").get(r.rowid);return t?{object:r,home_machine:t.home_machine,identity:t.envelope_json===null?null:JSON.parse(t.envelope_json)}:null}o(S,"stubOf");const I=o((n,e)=>i(n,"SELECT 1 FROM peer_stubs WHERE object = ?").get(e.rowid)!==void 0,"isStub");function E(n){return h(n,"person","local-user","user:local","user")}o(E,"localPerson");function w(n,e){return e==="user:local"?E(n):h(n,"app","app",e,e.replace(/^app:/,""))}o(w,"localApp");function F(n,e){return e.type==="app"?w(n,`app:${e.name}`):e.type==="person"?E(n):null}o(F,"localOwnerActor");function v(n,e,r){if(e!==null)return e.app===null?E(n):w(n,e.app);const t=r?.owner;return t?.type==="app"?w(n,t.external_id??`app:${t.handle}`):E(n)}o(v,"ownerFor");function N(n,e,r,t,_,u){const l=_===void 0?null:D(_),s=u?.privacy??"public";if(!W.includes(s))throw new f("invalid_event",`invalid privacy ${JSON.stringify(s)}`,m.GENERAL,{id:e});const c=y(n,e);if(c!==null){const d=S(n,c);if(d===null)throw new f("conflict",`${e} is a local ${c.type}, not a stub of ${t}`,m.GENERAL,{id:e});if(d.home_machine!==t)throw new f("conflict",`${e} is already a stub of ${d.home_machine}, not ${t}`,m.GENERAL,{id:e,home_machine:d.home_machine});return l!==null&&(i(n,"UPDATE peer_stubs SET envelope_json = ? WHERE object = ?").run(JSON.stringify(l),c.rowid),i(n,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(c.rowid)),u!==void 0&&(R(n,r,u),u.privacy!==void 0&&c.privacy!==s)?(i(n,"UPDATE objects SET privacy = ? WHERE rowid = ?").run(s,c.rowid),p(n,c.rowid)):c}const O=v(n,l,u);R(n,r,u);const a=A(n,{id:e,type:r,kind:u?.kind??null,owner:O.rowid,privacy:s,name:u?.name??e,preview:u?.preview??""});return i(n,"UPDATE objects SET home_machine = ? WHERE rowid = ?").run(t,a.rowid),i(n,"INSERT INTO peer_stubs (object, home_machine, envelope_json, created_at) VALUES (?, ?, ?, ?)").run(a.rowid,t,l===null?null:JSON.stringify(l),new Date().toISOString()),l!==null&&i(n,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(a.rowid),p(n,a.rowid)}o(N,"ensureStub");function R(n,e,r){const t=r?.kind_decl;t===void 0||t.name!==e||b(n,{name:t.name,owner:v(n,null,{...r,owner:t.owner}),description:t.description,events:t.events,read:null,source:"peer"})}o(R,"holdKind");function J(n,e,r){const t=N(n,e,"node",H(r));return i(n,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(t.rowid),p(n,t.rowid)}o(J,"ensureNodeStub");function M(n,e,r){const t=S(n,e);t===null||t.home_machine===r||(i(n,"UPDATE peer_stubs SET home_machine = ? WHERE object = ?").run(r,t.object.rowid),i(n,"UPDATE objects SET home_machine = ? WHERE rowid = ?").run(r,t.object.rowid))}o(M,"rehomeStub");function G(n,e){const r=j(n,e.owner===null?null:p(n,e.owner)),t=T(n,e.type);return{id:e.id,type:e.type,kind:e.kind,name:e.name,preview:e.preview,owner:r,privacy:e.privacy,...t===null?{}:{kind_decl:t}}}o(G,"describeObject");function j(n,e){if(e===null||e.type!=="person"&&e.type!=="app"&&e.type!=="repo"&&e.type!=="profile")return null;const r=i(n,"SELECT scheme, external_id FROM identities WHERE object = ?").get(e.rowid);return{id:e.id,type:e.type,scheme:r?.scheme??null,external_id:r?.external_id??null,handle:e.name}}o(j,"ownerRefOf");function T(n,e){const r=i(n,"SELECT owner, description, events_json FROM object_kinds WHERE name = ?").get(e),t=r===void 0?null:j(n,p(n,r.owner));return r===void 0||t===null?null:{name:e,description:r.description,events:JSON.parse(r.events_json),owner:t}}o(T,"kindDeclarationOf");function K(n,e,r){const t=T(n,e.type);return t===null?r:{...r,kind_decl:t}}o(K,"withKindDecl");export{G as describeObject,J as ensureNodeStub,N as ensureStub,D as identityOfEnvelope,I as isStub,T as kindDeclarationOf,F as localOwnerActor,M as rehomeStub,S as stubOf,K as withKindDecl};
@@ -1,7 +1,7 @@
1
1
  /** Request header naming the sending machine's crtr release. */
2
2
  export declare const PEER_VERSION_HEADER = "Crtr-Version";
3
- /** The oldest crtr release that speaks the peer protocol. The release that first ships C1–C6 with the peer relay switched on. */
4
- export declare const PEER_VERSION_FLOOR = "0.3.448";
3
+ /** The oldest crtr release that speaks the peer protocol. 0.3.487 is the first release whose app listener verifies peer tokens with `verifyCallToken` (peer authority), so it can take tokens without `machine_id`/`grantee`. */
4
+ export declare const PEER_VERSION_FLOOR = "0.3.487";
5
5
  export interface PeerVersionRefusal {
6
6
  status: 426;
7
7
  code: 'peer_version_too_old';
@@ -1 +1 @@
1
- var n=Object.defineProperty;var i=(r,e)=>n(r,"name",{value:e,configurable:!0});import{compareReleaseVersions as a}from"../../api/runtime-version.js";import{crtrVersion as o}from"../../shared/crtr-version.js";const l="Crtr-Version",c="0.3.448";function d(r,e=c,s=o()){const t=r?.trim()?r.trim():null;return t!==null&&a(t,e)>=0?null:{status:426,code:"peer_version_too_old",message:t===null?`The peer did not name its crtr version; machines below ${e} cannot take part (this machine is ${s}). Update it with \`crtr sys update\`.`:`The peer runs crtr ${t}; machines below ${e} cannot take part (this machine is ${s}). Update it with \`crtr sys update\`.`,details:{peer_version:t,floor:e,receiver_version:s}}}i(d,"peerVersionRefusal");export{c as PEER_VERSION_FLOOR,l as PEER_VERSION_HEADER,d as peerVersionRefusal};
1
+ var n=Object.defineProperty;var i=(r,e)=>n(r,"name",{value:e,configurable:!0});import{compareReleaseVersions as a}from"../../api/runtime-version.js";import{crtrVersion as o}from"../../shared/crtr-version.js";const l="Crtr-Version",c="0.3.487";function d(r,e=c,s=o()){const t=r?.trim()?r.trim():null;return t!==null&&a(t,e)>=0?null:{status:426,code:"peer_version_too_old",message:t===null?`The peer did not name its crtr version; machines below ${e} cannot take part (this machine is ${s}). Update it with \`crtr sys update\`.`:`The peer runs crtr ${t}; machines below ${e} cannot take part (this machine is ${s}). Update it with \`crtr sys update\`.`,details:{peer_version:t,floor:e,receiver_version:s}}}i(d,"peerVersionRefusal");export{c as PEER_VERSION_FLOOR,l as PEER_VERSION_HEADER,d as peerVersionRefusal};
@@ -1,3 +1,3 @@
1
- var V=Object.defineProperty;var s=(e,r)=>V(e,"name",{value:r,configurable:!0});import{assertGranteeRunsHere as X}from"./unsandboxed.js";import{existsSync as P}from"node:fs";import{conversationIdFromPath as _,conversationStore as h,ConversationNotFoundError as A}from"../conversation-store/index.js";import{isAbsolute as Y}from"node:path";import{findNodeBySessionFile as q,getNode as g,updateNode as y,beginExecution as Q,recordExecutionPid as Z,abortExecution as b,endLiveExecution as I,unbindSession as O,recordLaunch as ee,setFrozen as re,clearFrozen as ie,fullName as D}from"../canvas/index.js";import{emitEvent as ne}from"../events/emit.js";import{cancelCronsOnWake as oe}from"../canvas/crons.js";import{isParked as te,transition as R}from"./lifecycle.js";import{publishNotice as se}from"./close.js";import{InputError as E}from"../io.js";import{buildPiArgv as m}from"./launch.js";import{buildReviveKickoff as le,drainBearings as ce,hasRetainedReports as ae,readGoal as S,readYieldMessage as ue,RUNTIME_RESTART_CONTINUATION as fe}from"./kickoff.js";import{readRoadmap as T}from"./roadmap.js";import{encodeKickoffOrigin as he,KICKOFF_ORIGIN_ENV as de}from"./stamp/protocol.js";import{headlessBrokerHost as B}from"./host.js";import{boundFleet as z,brokerCapReached as pe,brokerThresholdsForDaemon as U}from"./fleet.js";import{beginBootFaultAttempt as ve,clearFault as we}from"../canvas/recovery.js";import{clearNodeLedger as H,forkNodeLedger as _e,noticeChangedWhileDone as me}from"./ledger.js";import{forkSourceNode as ke,rootOfSpine as ge}from"./nodes.js";import{isReviewCompanionBound as ye}from"../review/companion.js";import{assertProfileActive as be}from"../profiles/manifest.js";import{isPidAlive as Re}from"../canvas/pid.js";import{crtrHome as Ee,jobDir as Se}from"../canvas/paths.js";import{contextDir as xe,ensureNodeDirs as $e,nodeAgentDir as Ne}from"../canvas/node-agent-paths.js";import{discoverLifecycleHookRegistry as Ce}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Fe}from"../command-hooks/transport/exec-lifecycle.js";function Pe(e,r){const i=e.pi_session_file,n=i?_(i):null;if(n===null)return{};try{const t=h().header(n);return r?{resumeSessionPath:t.path}:{resumeSessionPath:t.path,newCycle:!0}}catch(t){if(t instanceof A)return{};throw t}}s(Pe,"resumeArgs");function K(e){const r=_(e);if(r===null)return!1;try{return h().header(r),!0}catch(i){if(i instanceof A)return!1;throw i}}s(K,"conversationExists");function Ae(e){const r=_(e);if(r===null)return!0;const i=h().header(r).header.cwd;return typeof i!="string"||P(i)}s(Ae,"sessionCwdExists");function Oe(e,r,i){const n=r.pi_session_file;if(!n||!K(n))return{};const t=q(n);return t!==null&&t.node_id!==e&&Re(t.pi_pid)?{}:Ae(n)?Pe(r,i):{}}s(Oe,"resumableSessionArgs");function De(e){return T(e)===null&&ue(e)===null&&!ae(e)}s(De,"isUnstartedBirth");function ar(e){const r=S(e);if(r!==null&&r.trim()!=="")return!0;const i=T(e);return i!==null&&i.trim()!==""}s(ar,"hasFreshGroundState");async function ur(e,r){const i=await L(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}s(ur,"reviveNode");async function fr(e,r,i){return L(e,{...r,viewerAttach:!0},i)}s(fr,"decideAttachRevive");async function L(e,r,i){let n=g(e);if(n===null)throw new Error(`reviveNode: unknown node ${e}`);if(n=g(e)??n,n.run_id&&g(n.run_id)?.deleting_at)throw new Error("run is deleting");if(n.final_report!==null)throw new Error(`reviveNode: refusing to revive ${e} \u2014 its finalization latch is set (final_report=${n.final_report}). A final landed between the caller's reopen-gate check and this revive; re-run with --reopen if this retask is still wanted.`);be(n.profile_id),X(n.grantee);const t=z();if(t.has(e))return R(e,n.intent==="refresh"?"refresh-launch":"revive"),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(t.isClaimed(e))return{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(!i&&n.lifecycle==="resident"&&te(n))return{parked:!0};if(!t.reserveSlot(e)){if(r.capacity==="refuse")throw pe(U().automaticReviveCap,t.size());return n.frozen_at==null&&(re(e,new Date().toISOString()),I(e,{reason:"frozen"}),ne({level:"info",event:"broker.frozen",node_id:e,fields:{live_count:t.size(),hard_cap:U().automaticReviveCap}})),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await Te(e,n,r)}}finally{t.releaseReservation(e)}}s(L,"decideRevive");async function Te(e,r,i){if(!P(r.cwd)){const d=r.fork_from!=null?`Restore ${r.cwd}, then revive the fork normally with \`crtr node lifecycle revive ${e}\`.`:r.managed_worktree?.state==="open"?"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon recovery.":`Recreate ${r.cwd}, or repair it with \`crtr node config --cwd <path> --node ${e}\`; durable node work resumes in a fresh conversation. Then retry \`crtr node lifecycle revive ${e}\`.`;throw new E({error:"cwd_missing",message:`${e} cannot be revived \u2014 its recorded cwd no longer exists: ${r.cwd}`,next:d})}r.host_kind!=="broker"&&(y(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!ye(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(O(e),r.pi_session_id=null,r.pi_session_file=null);const t=r.fork_from!=null&&r.pi_session_id==null,c=r.fork_source_file;if(t&&(typeof c!="string"||!Y(c)))throw new E({error:"fork_source_invalid",message:`${e} cannot be revived \u2014 its resolved fork source file is missing or invalid.`,next:`Restore the node's fork source metadata, then retry \`crtr node lifecycle revive ${e}\`.`});const f=t&&typeof c=="string";if(f&&!K(c))throw new E({error:"fork_from_missing",message:`${e} cannot be revived \u2014 its fork source no longer exists: ${c}`,next:`Restore ${c}, or update the node's fork source, then retry \`crtr node lifecycle revive ${e}\`.`});const a=Q(e,{daemonEpoch:z().epoch()});try{r.cycles=(r.cycles??0)+1,y(e,{cycles:r.cycles});const G=r.intent==="refresh"||r.cycle_pending===!0?!1:i.resume,p=f?{}:Oe(e,r,G),v=p.resumeSessionPath!==void 0,x=v&&p.newCycle===!0,k=v&&!x,$=!v&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&De(e),M=f||$,N=r.cycle_pending===!0||x;y(e,{cycle_pending:N}),r.cycle_pending=N,!f&&!v&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(O(e),r.pi_session_id=null,r.pi_session_file=null);let l,u=null;const C=s(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(f){const o=S(e),F=_(c);if(F===null)throw new Error(`invalid fork source ${c}`);const J=h().header(h().fork(F,e)).path;l=m(r,{resumeSessionPath:J,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(u=C()),_e(e,ke(c)?.node_id??null)}else if(k)l=m(r,{...p,...i.wakeReason==="runtime-restart-abort"?{prompt:fe}:{}}),i.wakeReason==="runtime-restart-abort"&&(u={type:"runtime",kind:"restart-continuation"});else if($){const o=S(e)?.trim();l=m(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(u=C()),H(e)}else{const o=ce(r,a);l=m(r,{...p,prompt:le(r,o,i.wakeReason==="runtime-restart-abort"?void 0:i.wakeReason)}),r.run_id&&o.unreadMessageIds?.length&&(l.env.CRTR_KICKOFF_MESSAGE_IDS=JSON.stringify(o.unreadMessageIds)),u=i.wakeReason!==void 0&&i.wakeReason!=="runtime-restart-abort"?{type:"runtime",kind:"wake",wake:i.wakeReason}:{type:"runtime",kind:"revive",cycle:r.cycles??0},H(e)}l.env={...l.env,CRTR_SUBTREE:ge(e)},u!==null&&(l.env[de]=he(u)),r.status==="done"&&r.last_settled_at!=null&&me(e,r.last_settled_at),R(e,r.intent==="refresh"?"refresh-launch":"revive"),we(e,{preserveEpisode:!0});const j=ve(e);i.recovery!==!0&&i.viewerAttach!==!0&&oe(e),$e(e,r.grantee);const W=Ce(r.cwd,r.profile_id).plans.get("node:start")??[];await Fe(W,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:Ne(e),contextDir:xe(e),jobDir:Se(e)},runtime:{isBirth:M,canvasHome:Ee(),profile:r.profile_id??null}}),l.env={...l.env,CRTR_EXECUTION_ID:a};let w;try{if(w=await B.launch(e,l,{cwd:r.cwd,name:D(r),resuming:k}),w.pid===null)throw new Error(`broker host returned no pid for ${e}`)}catch(o){try{R(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:o instanceof Error?o.message:String(o)}}}),se(e,"notice.crash",`Child crashed \u2014 ${D(r)} (${e}) failed to relaunch and is now dead: ${o.message}
1
+ var Y=Object.defineProperty;var s=(e,r)=>Y(e,"name",{value:r,configurable:!0});import{assertGranteeRunsHere as q}from"./unsandboxed.js";import{existsSync as O}from"node:fs";import{conversationIdFromPath as p,conversationStore as h,ConversationNotFoundError as B}from"../conversation-store/index.js";import{isAbsolute as Q}from"node:path";import{findNodeBySessionFile as Z,getNode as R,updateNode as E,beginExecution as I,recordExecutionPid as ee,abortExecution as S,endLiveExecution as re,unbindSession as D,recordLaunch as ie,setFrozen as ne,clearFrozen as oe,fullName as T}from"../canvas/index.js";import{emitEvent as te}from"../events/emit.js";import{cancelCronsOnWake as se}from"../canvas/crons.js";import{isParked as le,transition as x}from"./lifecycle.js";import{publishNotice as ce}from"./close.js";import{InputError as $}from"../io.js";import{buildPiArgv as v}from"./launch.js";import{buildReviveKickoff as ae,drainBearings as ue,hasRetainedReports as fe,readGoal as g,readYieldMessage as he,RUNTIME_RESTART_CONTINUATION as de}from"./kickoff.js";import{readRoadmap as z}from"./roadmap.js";import{encodeKickoffOrigin as pe,KICKOFF_ORIGIN_ENV as ve}from"./stamp/protocol.js";import{headlessBrokerHost as H}from"./host.js";import{boundFleet as U,brokerCapReached as we,brokerThresholdsForDaemon as K}from"./fleet.js";import{beginBootFaultAttempt as me,clearFault as _e,hasAdmittedTurn as ke}from"../canvas/recovery.js";import{clearNodeLedger as G,forkNodeLedger as ge,noticeChangedWhileDone as ye}from"./ledger.js";import{forkSourceNode as be,rootOfSpine as Re}from"./nodes.js";import{isReviewCompanionBound as Ee}from"../review/companion.js";import{assertProfileActive as Se}from"../profiles/manifest.js";import{isPidAlive as xe}from"../canvas/pid.js";import{crtrHome as $e,jobDir as Ce}from"../canvas/paths.js";import{contextDir as Ne,ensureNodeDirs as Pe,nodeAgentDir as Ae}from"../canvas/node-agent-paths.js";import{discoverLifecycleHookRegistry as Fe}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Oe}from"../command-hooks/transport/exec-lifecycle.js";function Be(e,r){const i=e.pi_session_file,n=i?p(i):null;if(n===null)return{};try{const t=h().header(n);return r?{resumeSessionPath:t.path}:{resumeSessionPath:t.path,newCycle:!0}}catch(t){if(t instanceof B)return{};throw t}}s(Be,"resumeArgs");function L(e){const r=p(e);if(r===null)return!1;try{return h().header(r),!0}catch(i){if(i instanceof B)return!1;throw i}}s(L,"conversationExists");function De(e){const r=p(e);return r===null?!0:h().read(r).entries.some(i=>i.type==="message")}s(De,"sessionHasConversation");function Te(e){const r=p(e);if(r===null)return!0;const i=h().header(r).header.cwd;return typeof i!="string"||O(i)}s(Te,"sessionCwdExists");function ze(e,r,i){const n=r.pi_session_file;if(!n||!L(n))return{};const t=Z(n);return t!==null&&t.node_id!==e&&xe(t.pi_pid)?{}:Te(n)?Be(r,i):{}}s(ze,"resumableSessionArgs");function He(e){return z(e)===null&&he(e)===null&&!fe(e)}s(He,"isUnstartedBirth");function pr(e){const r=g(e);if(r!==null&&r.trim()!=="")return!0;const i=z(e);return i!==null&&i.trim()!==""}s(pr,"hasFreshGroundState");async function vr(e,r){const i=await M(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}s(vr,"reviveNode");async function wr(e,r,i){return M(e,{...r,viewerAttach:!0},i)}s(wr,"decideAttachRevive");async function M(e,r,i){let n=R(e);if(n===null)throw new Error(`reviveNode: unknown node ${e}`);if(n=R(e)??n,n.run_id&&R(n.run_id)?.deleting_at)throw new Error("run is deleting");if(n.final_report!==null)throw new Error(`reviveNode: refusing to revive ${e} \u2014 its finalization latch is set (final_report=${n.final_report}). A final landed between the caller's reopen-gate check and this revive; re-run with --reopen if this retask is still wanted.`);Se(n.profile_id),q(n.grantee);const t=U();if(t.has(e))return x(e,n.intent==="refresh"?"refresh-launch":"revive"),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(t.isClaimed(e))return{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(!i&&n.lifecycle==="resident"&&le(n))return{parked:!0};if(!t.reserveSlot(e)){if(r.capacity==="refuse")throw we(K().automaticReviveCap,t.size());return n.frozen_at==null&&(ne(e,new Date().toISOString()),re(e,{reason:"frozen"}),te({level:"info",event:"broker.frozen",node_id:e,fields:{live_count:t.size(),hard_cap:K().automaticReviveCap}})),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await Ue(e,n,r)}}finally{t.releaseReservation(e)}}s(M,"decideRevive");async function Ue(e,r,i){if(!O(r.cwd)){const w=r.fork_from!=null?`Restore ${r.cwd}, then revive the fork normally with \`crtr node lifecycle revive ${e}\`.`:r.managed_worktree?.state==="open"?"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon recovery.":`Recreate ${r.cwd}, or repair it with \`crtr node config --cwd <path> --node ${e}\`; durable node work resumes in a fresh conversation. Then retry \`crtr node lifecycle revive ${e}\`.`;throw new $({error:"cwd_missing",message:`${e} cannot be revived \u2014 its recorded cwd no longer exists: ${r.cwd}`,next:w})}r.host_kind!=="broker"&&(E(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!Ee(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(D(e),r.pi_session_id=null,r.pi_session_file=null);const t=r.fork_from!=null&&r.pi_session_id==null,c=r.fork_source_file;if(t&&(typeof c!="string"||!Q(c)))throw new $({error:"fork_source_invalid",message:`${e} cannot be revived \u2014 its resolved fork source file is missing or invalid.`,next:`Restore the node's fork source metadata, then retry \`crtr node lifecycle revive ${e}\`.`});const d=t&&typeof c=="string";if(d&&!L(c))throw new $({error:"fork_from_missing",message:`${e} cannot be revived \u2014 its fork source no longer exists: ${c}`,next:`Restore ${c}, or update the node's fork source, then retry \`crtr node lifecycle revive ${e}\`.`});const u=I(e,{daemonEpoch:U().epoch()});try{r.cycles=(r.cycles??0)+1,E(e,{cycles:r.cycles});const j=r.intent==="refresh"||r.cycle_pending===!0?!1:i.resume,f=d?{}:ze(e,r,j),m=f.resumeSessionPath!==void 0,C=m&&f.newCycle===!0,_=m&&!C,N=!m&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&He(e),y=_&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&!ke(e)&&!De(f.resumeSessionPath)?g(e)?.trim():void 0,P=y!==void 0&&y!=="",W=d||N||P,A=r.cycle_pending===!0||C;E(e,{cycle_pending:A}),r.cycle_pending=A,!d&&!m&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(D(e),r.pi_session_id=null,r.pi_session_file=null);let l,a=null;const b=s(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(d){const o=g(e),F=p(c);if(F===null)throw new Error(`invalid fork source ${c}`);const X=h().header(h().fork(F,e)).path;l=v(r,{resumeSessionPath:X,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(a=b()),ge(e,be(c)?.node_id??null)}else if(P)l=v(r,{...f,prompt:y}),a=b();else if(_)l=v(r,{...f,...i.wakeReason==="runtime-restart-abort"?{prompt:de}:{}}),i.wakeReason==="runtime-restart-abort"&&(a={type:"runtime",kind:"restart-continuation"});else if(N){const o=g(e)?.trim();l=v(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(a=b()),G(e)}else{const o=ue(r,u);l=v(r,{...f,prompt:ae(r,o,i.wakeReason==="runtime-restart-abort"?void 0:i.wakeReason)}),r.run_id&&o.unreadMessageIds?.length&&(l.env.CRTR_KICKOFF_MESSAGE_IDS=JSON.stringify(o.unreadMessageIds)),a=i.wakeReason!==void 0&&i.wakeReason!=="runtime-restart-abort"?{type:"runtime",kind:"wake",wake:i.wakeReason}:{type:"runtime",kind:"revive",cycle:r.cycles??0},G(e)}l.env={...l.env,CRTR_SUBTREE:Re(e)},a!==null&&(l.env[ve]=pe(a)),r.status==="done"&&r.last_settled_at!=null&&ye(e,r.last_settled_at),x(e,r.intent==="refresh"?"refresh-launch":"revive"),_e(e,{preserveEpisode:!0});const J=me(e);i.recovery!==!0&&i.viewerAttach!==!0&&se(e),Pe(e,r.grantee);const V=Fe(r.cwd,r.profile_id).plans.get("node:start")??[];await Oe(V,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:Ae(e),contextDir:Ne(e),jobDir:Ce(e)},runtime:{isBirth:W,canvasHome:$e(),profile:r.profile_id??null}}),l.env={...l.env,CRTR_EXECUTION_ID:u};let k;try{if(k=await H.launch(e,l,{cwd:r.cwd,name:T(r),resuming:_}),k.pid===null)throw new Error(`broker host returned no pid for ${e}`)}catch(o){try{x(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:o instanceof Error?o.message:String(o)}}}),ce(e,"notice.crash",`Child crashed \u2014 ${T(r)} (${e}) failed to relaunch and is now dead: ${o.message}
2
2
 
3
- It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw b(a,{reason:"launch_failed"}),new Error(`[broker] refusing to revive ${e}: ${o.message}`)}if(ee(e,new Date().toISOString()),Z(a,e,w.pid)==="shutdown")throw b(a,{reason:"superseded"}),B.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return ie(e),{window:null,session:r.tmux_session??null,resumed:k,launch:w,faultExplanation:j.explanation,outcome:"launched"}}catch(d){throw b(a,{reason:"launch_failed"}),d}}s(Te,"launchRevive");export{fr as decideAttachRevive,ar as hasFreshGroundState,Pe as resumeArgs,ur as reviveNode};
3
+ It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw S(u,{reason:"launch_failed"}),new Error(`[broker] refusing to revive ${e}: ${o.message}`)}if(ie(e,new Date().toISOString()),ee(u,e,k.pid)==="shutdown")throw S(u,{reason:"superseded"}),H.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return oe(e),{window:null,session:r.tmux_session??null,resumed:_,launch:k,faultExplanation:J.explanation,outcome:"launched"}}catch(w){throw S(u,{reason:"launch_failed"}),w}}s(Ue,"launchRevive");export{wr as decideAttachRevive,pr as hasFreshGroundState,Be as resumeArgs,vr as reviveNode};
@@ -1,24 +1,24 @@
1
- var $=Object.defineProperty;var s=(e,n)=>$(e,"name",{value:n,configurable:!0});import{randomUUID as F}from"node:crypto";import{createServer as G}from"node:http";import{Router as J}from"./router.js";import{toErrorBody as Y}from"./map.js";import{objectRoutes as q}from"./handlers/objects.js";import{customObjectRoutes as z}from"./handlers/custom-objects.js";import{docRoutes as Q}from"./handlers/docs.js";import{OPERATIONS as W}from"./operations.js";import{errorCodes as L}from"../../api/error-codes.js";import{MINIMUM_RUNTIME_VERSION_HEADER as K,RUNTIME_VERSION_HEADER as Z,minimumRuntimeRefusal as ee}from"../../api/runtime-version.js";import{CONTRACT_HEADER as te,CONTRACT_LEVEL as U,REQUIRED_CONTRACT_HEADER as re,contractRefusal as ne}from"../../api/contract.js";import{crtrVersion as H}from"../../shared/crtr-version.js";import{decodeJwt as ae}from"jose";import{AppPrincipalResolver as oe}from"./principal.js";import{runtimeOwner as se,servePeer as ie}from"../peer/ingress.js";import{applySyncNotice as ue}from"./sync-notice.js";import{ownMachineId as ce}from"../../core/peer/directory.js";import{handleRunOperation as de,integer as le}from"./handlers/runs.js";import{parseLlmRequest as fe,runLlm as me}from"../../core/llm/run.js";import{parseUsageMonth as pe,usageFor as he}from"../../core/usage/ledger.js";import{capFields as we}from"./handlers/llm.js";import{CONTROL_BODY_MAX_BYTES as ye,MODEL_CONTEXT_BODY_MAX_BYTES as _e}from"../../core/llm/body-limits.js";import{RunError as f,runIsRunning as ge}from"../../core/runs/operations.js";import{requireRun as k}from"./router.js";import{deferHead as ve}from"./deferred-head.js";import{readRunEvents as V,registerGrantStream as Re,subscribeRunEvents as Oe}from"../../core/runs/events.js";import{activeGrant as Ee}from"../../core/grants/mirror.js";import{releaseGrantWaiters as be}from"../../core/grants/watch.js";import{runNotices as Se}from"../run-notices.js";import{handleVendorSignIn as Ae,isVendorSignInPath as Te}from"./vendor-signin.js";import{listAppProfiles as Ne}from"./handlers/app-profiles.js";import{handleTransferDownload as Ce,handleTransferOperation as Pe,TRANSFER_OPERATIONS as Ie}from"./handlers/transfer.js";import{handleQuestionOperation as Me,QUESTION_OPERATIONS as He}from"./handlers/questions.js";import{vendorStatus as ke}from"./handlers/vendor-status.js";import{handleMemoryOperation as De,MEMORY_OPERATIONS as xe}from"./handlers/memory.js";import{abortOnClose as Be,callerFromApp as je,handleProviderOperation as Je,PROVIDER_OPERATIONS as Le,providerFailure as Ue}from"./handlers/providers.js";function Ve(e){return Object.prototype.hasOwnProperty.call(L,e)?L[e]:void 0}s(Ve,"fixedRow");function Xe(e){const n=Ve(e);return n?n.type:e==="stream_gap"||e==="provider_error"||e==="runtime_version_unsupported"?"invalid_request_error":"server_error"}s(Xe,"errorType");function $e(e){if(!e||typeof e!="object"||Array.isArray(e)||!("rate_limit"in e))return e;const{rate_limit:n,...o}=e;return o}s($e,"appDetails");function M(e,n,o){const l=$e(e.details);return{error:{code:e.code,message:e.message,...l===void 0?{}:{details:l},type:Xe(e.code),...e.param?{param:e.param}:{},origin:"runtime",retryable:e.retryable||e.code==="stream_dropped",request_id:n,...o?{run_id:o}:{},...e.scope?{scope:e.scope}:{},...e.code==="unauthorized"?{user_action:"reconnect"}:{},...we(e),...e.code==="all_routes_exhausted"?{retry_after_s:e.details.retry_after_s}:{}}}}s(M,"envelope");function Fe(e,n,o,l){const i=n instanceof f?n:new f(500,"server_failure","runtime request failed");if(n instanceof f||console.error("[app-listener]",n),e.headersSent&&!String(e.getHeader("Content-Type")??"").startsWith("text/event-stream")){e.destroy();return}if(e.headersSent){e.end(`event: error
2
- data: ${JSON.stringify(M(i,o,l))}
1
+ var z=Object.defineProperty;var s=(e,r)=>z(e,"name",{value:r,configurable:!0});import{randomUUID as F}from"node:crypto";import{createServer as G}from"node:http";import{Router as J}from"./router.js";import{toErrorBody as Y}from"./map.js";import{objectRoutes as q}from"./handlers/objects.js";import{customObjectRoutes as Q}from"./handlers/custom-objects.js";import{docRoutes as W}from"./handlers/docs.js";import{OPERATIONS as K}from"./operations.js";import{errorCodes as L}from"../../api/error-codes.js";import{MINIMUM_RUNTIME_VERSION_HEADER as Z,RUNTIME_VERSION_HEADER as ee,minimumRuntimeRefusal as te}from"../../api/runtime-version.js";import{CONTRACT_HEADER as ne,CONTRACT_LEVEL as U,REQUIRED_CONTRACT_HEADER as re,contractRefusal as ae}from"../../api/contract.js";import{crtrVersion as x}from"../../shared/crtr-version.js";import{AppPrincipalResolver as oe}from"./principal.js";import{isDaemonRoute as se,runtimeOwner as ie,servePeer as V}from"../peer/ingress.js";import{applySyncNotice as ue}from"./sync-notice.js";import{ownMachineId as de}from"../../core/peer/directory.js";import{handleRunOperation as ce,integer as le}from"./handlers/runs.js";import{parseLlmRequest as fe,runLlm as me}from"../../core/llm/run.js";import{parseUsageMonth as pe,usageFor as he}from"../../core/usage/ledger.js";import{capFields as we}from"./handlers/llm.js";import{CONTROL_BODY_MAX_BYTES as ye,MODEL_CONTEXT_BODY_MAX_BYTES as _e}from"../../core/llm/body-limits.js";import{RunError as m,runIsRunning as ve}from"../../core/runs/operations.js";import{requireRun as j}from"./router.js";import{deferHead as ge}from"./deferred-head.js";import{readRunEvents as X,registerGrantStream as Re,subscribeRunEvents as Oe}from"../../core/runs/events.js";import{activeGrant as Ee}from"../../core/grants/mirror.js";import{releaseGrantWaiters as be}from"../../core/grants/watch.js";import{runNotices as Se}from"../run-notices.js";import{handleVendorSignIn as Te,isVendorSignInPath as Ae}from"./vendor-signin.js";import{listAppProfiles as Ne}from"./handlers/app-profiles.js";import{handleTransferDownload as Ce,handleTransferOperation as Ie,TRANSFER_OPERATIONS as Pe}from"./handlers/transfer.js";import{handleQuestionOperation as ke,QUESTION_OPERATIONS as He}from"./handlers/questions.js";import{vendorStatus as Me}from"./handlers/vendor-status.js";import{handleMemoryOperation as De,MEMORY_OPERATIONS as xe}from"./handlers/memory.js";import{abortOnClose as je,callerFromApp as Be,handleProviderOperation as Je,PROVIDER_OPERATIONS as Le,providerFailure as Ue}from"./handlers/providers.js";function Ve(e){return Object.prototype.hasOwnProperty.call(L,e)?L[e]:void 0}s(Ve,"fixedRow");function Xe(e){const r=Ve(e);return r?r.type:e==="stream_gap"||e==="provider_error"||e==="runtime_version_unsupported"?"invalid_request_error":"server_error"}s(Xe,"errorType");function $e(e){if(!e||typeof e!="object"||Array.isArray(e)||!("rate_limit"in e))return e;const{rate_limit:r,...o}=e;return o}s($e,"appDetails");function D(e,r,o){const c=$e(e.details);return{error:{code:e.code,message:e.message,...c===void 0?{}:{details:c},type:Xe(e.code),...e.param?{param:e.param}:{},origin:"runtime",retryable:e.retryable||e.code==="stream_dropped",request_id:r,...o?{run_id:o}:{},...e.scope?{scope:e.scope}:{},...e.code==="unauthorized"?{user_action:"reconnect"}:{},...we(e),...e.code==="all_routes_exhausted"?{retry_after_s:e.details.retry_after_s}:{}}}}s(D,"envelope");function ze(e,r,o,c){const u=r instanceof m?r:new m(500,"server_failure","runtime request failed");if(r instanceof m||console.error("[app-listener]",r),e.headersSent&&!String(e.getHeader("Content-Type")??"").startsWith("text/event-stream")){e.destroy();return}if(e.headersSent){e.end(`event: error
2
+ data: ${JSON.stringify(D(u,o,c))}
3
3
 
4
- `);return}e.writeHead(i.status,{"Content-Type":"application/json; charset=utf-8","Request-Id":o,"X-Content-Type-Options":"nosniff",...i.code==="all_routes_exhausted"?{"Retry-After":String(i.details.retry_after_s)}:{}}),e.end(JSON.stringify(M(i,o,l)))}s(Fe,"fail");function X(e){return Array.isArray(e)?e[0]:e}s(X,"headerValue");function Ge(e){if(!e?.startsWith("Bearer ")||e.length<=7)return!1;try{return typeof ae(e.slice(7)).machine_id=="string"}catch{return!1}}s(Ge,"isMachineBearer");function O(e,n,o){e.writeHead(n,{"Content-Type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}s(O,"json");async function P(e,n=ye){const o=[];let l=0;for await(const i of e){if(l+=i.length,l>n)throw new f(400,"invalid_request","request body too large");o.push(i)}if(l)try{return JSON.parse(Buffer.concat(o).toString("utf8"))}catch{throw new f(400,"invalid_request","invalid JSON body")}}s(P,"bodyOf");function Ye(e,n){const o=e.headers["last-event-id"]??n.get("after");if(Array.isArray(o))throw new f(400,"invalid_request","invalid cursor","after");return le(o??null,"after",0,Number.MAX_SAFE_INTEGER,0)}s(Ye,"cursor");function qe(e){return`id: ${e.sequence_number}
4
+ `);return}e.writeHead(u.status,{"Content-Type":"application/json; charset=utf-8","Request-Id":o,"X-Content-Type-Options":"nosniff",...u.code==="all_routes_exhausted"?{"Retry-After":String(u.details.retry_after_s)}:{}}),e.end(JSON.stringify(D(u,o,c)))}s(ze,"fail");function $(e){return Array.isArray(e)?e[0]:e}s($,"headerValue");function O(e,r,o){e.writeHead(r,{"Content-Type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}s(O,"json");async function I(e,r=ye){const o=[];let c=0;for await(const u of e){if(c+=u.length,c>r)throw new m(400,"invalid_request","request body too large");o.push(u)}if(c)try{return JSON.parse(Buffer.concat(o).toString("utf8"))}catch{throw new m(400,"invalid_request","invalid JSON body")}}s(I,"bodyOf");function Fe(e,r){const o=e.headers["last-event-id"]??r.get("after");if(Array.isArray(o))throw new m(400,"invalid_request","invalid cursor","after");return le(o??null,"after",0,Number.MAX_SAFE_INTEGER,0)}s(Fe,"cursor");function Ge(e){return`id: ${e.sequence_number}
5
5
  event: ${e.type}
6
6
  data: ${JSON.stringify(e)}
7
7
 
8
- `}s(qe,"frame");const ze=6e4;function Qe(e,n,o,l,i,g,E,A={}){k(l,o);let _=V(o,i);if(i>_.latest_sequence)throw new f(400,"invalid_request","cursor is beyond the run","after");if(i<_.latest_sequence&&(_.earliest_sequence===null||i<_.earliest_sequence-1))throw new f(409,"stream_gap","events have expired",void 0,{earliest_sequence:_.earliest_sequence,latest_sequence:_.latest_sequence});if(n.destroyed||e.destroyed)return n.destroy(),Promise.resolve();n.writeHead(200,{"Content-Type":E==="sse"?"text/event-stream":"application/x-ndjson","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),E==="sse"?n.write(`: connected
8
+ `}s(Ge,"frame");const Ye=6e4;function qe(e,r,o,c,u,_,E,A={}){j(c,o);let v=X(o,u);if(u>v.latest_sequence)throw new m(400,"invalid_request","cursor is beyond the run","after");if(u<v.latest_sequence&&(v.earliest_sequence===null||u<v.earliest_sequence-1))throw new m(409,"stream_gap","events have expired",void 0,{earliest_sequence:v.earliest_sequence,latest_sequence:v.latest_sequence});if(r.destroyed||e.destroyed)return r.destroy(),Promise.resolve();r.writeHead(200,{"Content-Type":E==="sse"?"text/event-stream":"application/x-ndjson","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),E==="sse"?r.write(`: connected
9
9
 
10
- `):n.flushHeaders();let w=i;const D=Se().streamOpened(o);let r=!1,t=!1,p=!1,b;const T=new Promise(h=>{b=h}),y=s(()=>{r||(r=!0,D(w),clearInterval(d),clearInterval(B),u(),S(),n.off("close",y),n.off("drain",m),n.end(),b())},"end"),m=s(()=>{p=!1,a()},"onDrain"),v=s(h=>{r||n.write(E==="sse"?`event: error
11
- data: ${JSON.stringify(M(h,g,o))}
10
+ `):r.flushHeaders();let w=u;const B=Se().streamOpened(o);let n=!1,t=!1,h=!1,b;const N=new Promise(f=>{b=f}),y=s(()=>{n||(n=!0,B(w),clearInterval(l),clearInterval(R),P(),H(),r.off("close",y),r.off("drain",p),r.end(),b())},"end"),p=s(()=>{h=!1,a()},"onDrain"),g=s(f=>{n||r.write(E==="sse"?`event: error
11
+ data: ${JSON.stringify(D(f,_,o))}
12
12
 
13
- `:`${JSON.stringify({type:"error",...M(h,g,o)})}
14
- `),y()},"error"),a=s(()=>{if(!(r||t)){t=!0;try{if(!I()){c();return}if(k(l,o),_=V(o,w),_.backlog_count>1e3||_.backlog_bytes>32*1024*1024){v(new f(503,"stream_dropped","stream reader fell behind",void 0,{last_sequence:w}));return}for(const h of _.events){if(p)break;p=!n.write(E==="sse"?qe(h):`${JSON.stringify(h)}
15
- `),w=h.sequence_number}}catch(h){v(h instanceof f?h:new f(500,"server_failure","stream failed"))}finally{t=!1}}},"flush"),c=s(()=>v(new f(401,"grant_revoked","grant is not active")),"revoked"),I=s(()=>"class"in l||Ee(l.grant)!==null,"grantActive"),u=Oe(o,a),S="class"in l?()=>{}:Re(l.grant,c),d=setInterval(()=>{!r&&!p&&E==="sse"&&n.write(`: keepalive
13
+ `:`${JSON.stringify({type:"error",...D(f,_,o)})}
14
+ `),y()},"error"),a=s(()=>{if(!(n||t)){t=!0;try{if(!T()){k();return}if(j(c,o),v=X(o,w),v.backlog_count>1e3||v.backlog_bytes>32*1024*1024){g(new m(503,"stream_dropped","stream reader fell behind",void 0,{last_sequence:w}));return}for(const f of v.events){if(h)break;h=!r.write(E==="sse"?Ge(f):`${JSON.stringify(f)}
15
+ `),w=f.sequence_number}}catch(f){g(f instanceof m?f:new m(500,"server_failure","stream failed"))}finally{t=!1}}},"flush"),k=s(()=>g(new m(401,"grant_revoked","grant is not active")),"revoked"),T=s(()=>"class"in c||Ee(c.grant)!==null,"grantActive"),P=Oe(o,a),H="class"in c?()=>{}:Re(c.grant,k),l=setInterval(()=>{!n&&!h&&E==="sse"&&r.write(`: keepalive
16
16
 
17
- `)},15e3),R=A.idleMs??ze,N=A.isRunning??ge;let C=Date.now(),x=w;const B=setInterval(()=>{if(r||E!=="sse")return;const h=Date.now();let j=!0;try{j=N(o)}catch{}if(j||w!==x){C=h,x=w;return}h-C<R||p||(n.write(`event: idle
17
+ `)},15e3),M=A.idleMs??Ye,i=A.isRunning??ve;let S=Date.now(),d=w;const R=setInterval(()=>{if(n||E!=="sse")return;const f=Date.now();let C=!0;try{C=i(o)}catch{}if(C||w!==d){S=f,d=w;return}f-S<M||h||(r.write(`event: idle
18
18
  data: {}
19
19
 
20
- `),y())},A.idleCheckMs??1e3);return B.unref(),n.on("drain",m),n.on("close",y),a(),T}s(Qe,"streamRunEvents");function kt(e,n,o,l={}){const i=e.listener;if(!e.issuer||!e.audience||!i?.address||!Number.isInteger(i.port)||i.port<1||i.port>65535)throw new Error("runtime issuer, audience and listener address/port are required");if(["0.0.0.0","::","[::]"].includes(i.address))throw new Error("runtime listener must bind a specific address");const g=new oe(e.issuer,e.audience,o,e.jwksUrl),E=new J,A=new Map;for(const r of W.filter(t=>t.stage!==void 0)){const t=s(()=>({status:500}),"handler");E.register({method:r.method,pattern:r.path,handler:t}),A.set(t,r)}const _=new J().registerAll(q).registerAll(z).registerAll(Q),w=G((r,t)=>{(async()=>{ve(r,t,l.deferHead);const p=F();t.setHeader("Request-Id",p),t.setHeader(Z,H()),t.setHeader(te,U);let b;try{const T=X(r.headers[K.toLowerCase()]),y=ee(T,H())??ne(X(r.headers[re.toLowerCase()]),U,{legacyMinimum:T,runtimeVersion:H()});if(y!==null)throw y.status===400?new f(400,y.code,y.message,y.param):new f(426,y.code,y.message,void 0,y.details);const m=new URL(r.url??"/","http://runtime.local");if(Te(m.pathname)){await Ae(r,t,m,g);return}if(Ge(r.headers.authorization)){await ie(r,t,{issuer:e.issuer,jwks:g.jwks,audience:s(()=>e.audience,"audience"),owner:se,self:ce,ready:s(()=>g.isReady()&&n(),"ready")});return}if((r.method!=="GET"||m.pathname!=="/v1/health")&&(!g.isReady()||!n()))throw new f(503,"runtime_starting","runtime_starting");const v=E.match(r.method??"GET",m.pathname);if(!v)throw new f(404,"not_found","unknown operation");const a=A.get(v.handler);if(!a)throw new f(404,"not_found","unknown operation");if(b=v.params.run_id,a.name==="health"){O(t,200,{status:"ok",api_version:"2026-09-23"});return}if(a.name==="runtime.sync-notice"){await ue(await g.verifySyncNotice(r.headers.authorization),o,p),t.writeHead(204),t.end();return}if(a.name==="runtime.vendor-status"){await g.verifyDirectoryRead(r.headers.authorization,"vendor_status"),O(t,200,ke());return}const c=await g.resolve(r.headers.authorization,a.scope);if(t.setHeader("Request-Id",p),b&&k(c,b,["run.message","run.interrupt","run.cancel","run.rename","run.delete"].includes(a.name),a.name==="run.delete"),a.stage==="objects"){const u=_.match(a.method,m.pathname);if(!u)throw new f(404,"not_found","unknown operation");const S={method:a.method,path:m.pathname,params:u.params,query:m.searchParams,body:await P(r,u.maxBodyBytes),ceiling:c.resolved,principal:{class:"app",app:c.grantee,scopes:c.resolved},req:r,res:t};let d;try{d=await u.handler(S)}catch(R){const{status:N,body:C}=Y(R);throw N>=500&&console.error("[app-listener]",R),new f(N,C.error.code,C.error.message,void 0,C.error.details)}if(t.headersSent)return;if(d.rawBody!==void 0||d.status===204||d.body===void 0){t.writeHead(d.status,d.headers??{}),t.end(d.rawBody);return}t.writeHead(d.status,{"Content-Type":"application/json; charset=utf-8",...d.headers??{}}),t.end(JSON.stringify(d.body));return}if(a.stream==="bytes"){await Ce(r,t,c,m.searchParams);return}if(a.stream){Qe(r,t,b,c,Ye(r,m.searchParams),p,"sse",l.stream);return}if(a.name==="llm"){const u=fe(await P(r,_e)),S=new AbortController,d=s(()=>S.abort(),"abort");t.on("close",d);try{const R=await me(u,S.signal,u.stream?N=>{t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.write(`data: ${JSON.stringify(N)}
20
+ `),y())},A.idleCheckMs??1e3);return R.unref(),r.on("drain",p),r.on("close",y),a(),N}s(qe,"streamRunEvents");function kt(e,r,o,c={}){const u=e.listener;if(!e.issuer||!e.audience||!u?.address||!Number.isInteger(u.port)||u.port<1||u.port>65535)throw new Error("runtime issuer, audience and listener address/port are required");if(["0.0.0.0","::","[::]"].includes(u.address))throw new Error("runtime listener must bind a specific address");const _=new oe(e.issuer,e.audience,o,e.jwksUrl),E=new J,A=new Map;for(const n of K.filter(t=>t.stage!==void 0)){const t=s(()=>({status:500}),"handler");E.register({method:n.method,pattern:n.path,handler:t}),A.set(t,n)}const v=new J().registerAll(q).registerAll(Q).registerAll(W),w=G((n,t)=>{(async()=>{ge(n,t,c.deferHead);const h=F();t.setHeader("Request-Id",h),t.setHeader(ee,x()),t.setHeader(ne,U);let b;try{const N=$(n.headers[Z.toLowerCase()]),y=te(N,x())??ae($(n.headers[re.toLowerCase()]),U,{legacyMinimum:N,runtimeVersion:x()});if(y!==null)throw y.status===400?new m(400,y.code,y.message,y.param):new m(426,y.code,y.message,void 0,y.details);const p=new URL(n.url??"/","http://runtime.local");if(Ae(p.pathname)){await Te(n,t,p,_);return}const g=E.match(n.method??"GET",p.pathname),a=g?A.get(g.handler):void 0,k=a?.name==="runtime.sync-notice"||a?.name==="runtime.vendor-status";let T,P;if(!k&&n.headers.authorization!==void 0)try{T=await _.verifyCall(n.headers.authorization)}catch(i){P=i}const H={issuer:e.issuer,jwks:_.jwks,audience:s(()=>e.audience,"audience"),owner:ie,self:de,syncGrants:o,ready:s(()=>_.isReady()&&r(),"ready")};if(T?.chain[0]?.sub.startsWith("runtime:")){await V(n,t,H,T);return}if(T===void 0&&a===void 0&&await se(n.method??"GET",p.pathname)){await V(n,t,H,{status:401,code:"unauthorized",message:P===void 0?"a machine token is required":"invalid machine token"});return}if((n.method!=="GET"||p.pathname!=="/v1/health")&&(!_.isReady()||!r()))throw new m(503,"runtime_starting","runtime_starting");if(!g||!a)throw new m(404,"not_found","unknown operation");if(b=g.params.run_id,a.name==="health"){O(t,200,{status:"ok",api_version:"2026-09-23"});return}if(a.name==="runtime.sync-notice"){await ue(await _.verifySyncNotice(n.headers.authorization),o,h),t.writeHead(204),t.end();return}if(a.name==="runtime.vendor-status"){await _.verifyDirectoryRead(n.headers.authorization,"vendor_status"),O(t,200,Me());return}if(T===void 0)throw P??new m(401,"unauthorized","a directory access token is required");const l=await _.resolveVerified(T,a.scope);if(t.setHeader("Request-Id",h),b&&j(l,b,["run.message","run.interrupt","run.cancel","run.rename","run.delete"].includes(a.name),a.name==="run.delete"),a.stage==="objects"){const i=v.match(a.method,p.pathname);if(!i)throw new m(404,"not_found","unknown operation");const S={method:a.method,path:p.pathname,params:i.params,query:p.searchParams,body:await I(n,i.maxBodyBytes),ceiling:l.resolved,principal:{class:"app",app:l.grantee,scopes:l.resolved},req:n,res:t};let d;try{d=await i.handler(S)}catch(R){const{status:f,body:C}=Y(R);throw f>=500&&console.error("[app-listener]",R),new m(f,C.error.code,C.error.message,void 0,C.error.details)}if(t.headersSent)return;if(d.rawBody!==void 0||d.status===204||d.body===void 0){t.writeHead(d.status,d.headers??{}),t.end(d.rawBody);return}t.writeHead(d.status,{"Content-Type":"application/json; charset=utf-8",...d.headers??{}}),t.end(JSON.stringify(d.body));return}if(a.stream==="bytes"){await Ce(n,t,l,p.searchParams);return}if(a.stream){qe(n,t,b,l,Fe(n,p.searchParams),h,"sse",c.stream);return}if(a.name==="llm"){const i=fe(await I(n,_e)),S=new AbortController,d=s(()=>S.abort(),"abort");t.on("close",d);try{const R=await me(i,S.signal,i.stream?f=>{t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.write(`data: ${JSON.stringify(f)}
21
21
 
22
- `)}:void 0,void 0,{grantee:c.grantee,spend_cap:c.spend_cap});u.stream?(t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.end(`data: [DONE]
22
+ `)}:void 0,void 0,{grantee:l.grantee,spend_cap:l.spend_cap});i.stream?(t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.end(`data: [DONE]
23
23
 
24
- `)):O(t,200,R.completion)}finally{t.off("close",d)}return}if(a.name==="usage.get"){O(t,200,he(c.grantee,c.spend_cap,pe(m.searchParams.get("month"))));return}if(a.name==="profile.list"){O(t,200,Ne(c));return}if(He.has(a.name)){const u=await Me(a.name,c,v.params.question_id,a.method==="POST"?await P(r):void 0);O(t,u.status,u.body);return}if(Le.has(a.name)){const{signal:u,release:S}=Be(t);try{const d=await Je(a.name,je(c),{params:v.params,body:a.method==="POST"?await P(r):void 0,query:m.searchParams},{requestId:p,signal:u});O(t,d.status,d.body)}catch(d){const R=Ue(d,p,!0);t.writeHead(R.status,{"Content-Type":"application/json; charset=utf-8","X-Content-Type-Options":"nosniff",...R.headers}),t.end(JSON.stringify(R.body))}finally{S()}return}if(xe.has(a.name)){const u=De(a.name,{class:"app",app:c.grantee,scopes:c.resolved},m.searchParams);O(t,u.status,u.body);return}if(Ie.has(a.name)){const u=await Pe(a,c,v.params,m.searchParams,await P(r));O(t,u.status,u.body);return}const I=await de(a,c,b,m.searchParams,await P(r),r.headers["idempotency-key"]);O(t,I.status,I.body)}catch(T){Fe(t,T,p,b)}})()});return{ready:new Promise((r,t)=>{w.once("error",t),w.listen(i.port,i.address,()=>{w.off("error",t),r()})}),close:s(async()=>{g.close(),be(),w.closeAllConnections(),await new Promise((r,t)=>w.close(p=>p?t(p):r()))},"close")}}s(kt,"createAppListener");export{ze as RUN_STREAM_IDLE_MS,kt as createAppListener,Ye as cursor,Qe as streamRunEvents};
24
+ `)):O(t,200,R.completion)}finally{t.off("close",d)}return}if(a.name==="usage.get"){O(t,200,he(l.grantee,l.spend_cap,pe(p.searchParams.get("month"))));return}if(a.name==="profile.list"){O(t,200,Ne(l));return}if(He.has(a.name)){const i=await ke(a.name,l,g.params.question_id,a.method==="POST"?await I(n):void 0);O(t,i.status,i.body);return}if(Le.has(a.name)){const{signal:i,release:S}=je(t);try{const d=await Je(a.name,Be(l),{params:g.params,body:a.method==="POST"?await I(n):void 0,query:p.searchParams},{requestId:h,signal:i});O(t,d.status,d.body)}catch(d){const R=Ue(d,h,!0);t.writeHead(R.status,{"Content-Type":"application/json; charset=utf-8","X-Content-Type-Options":"nosniff",...R.headers}),t.end(JSON.stringify(R.body))}finally{S()}return}if(xe.has(a.name)){const i=De(a.name,{class:"app",app:l.grantee,scopes:l.resolved},p.searchParams);O(t,i.status,i.body);return}if(Pe.has(a.name)){const i=await Ie(a,l,g.params,p.searchParams,await I(n));O(t,i.status,i.body);return}const M=await ce(a,l,b,p.searchParams,await I(n),n.headers["idempotency-key"]);O(t,M.status,M.body)}catch(N){ze(t,N,h,b)}})()});return{ready:new Promise((n,t)=>{w.once("error",t),w.listen(u.port,u.address,()=>{w.off("error",t),n()})}),close:s(async()=>{_.close(),be(),w.closeAllConnections(),await new Promise((n,t)=>w.close(h=>h?t(h):n()))},"close")}}s(kt,"createAppListener");export{Ye as RUN_STREAM_IDLE_MS,kt as createAppListener,Fe as cursor,qe as streamRunEvents};