@north-light/cli 0.3.546 → 0.3.547

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.
@@ -1,8 +1,8 @@
1
- var ee=Object.defineProperty;var a=(e,n)=>ee(e,"name",{value:n,configurable:!0});import{envNodeId as U}from"../../shared/env.js";import{rmdirSync as ne,rmSync as te,statSync as ae}from"node:fs";import{dirname as ie,join as I,resolve as oe}from"node:path";import{removeTreeBeneath as j}from"../spaces/open-beneath.js";import{emitEvent as re}from"../events/emit.js";import{withCanvasWrite as p,openDb as r}from"./db.js";import{conversationStore as se,ConversationNotFoundError as de}from"../conversation-store/index.js";import{hasUnseenWakeMail as ue,UNSEEN_WAKE_MAIL_SQL as le}from"./deliveries.js";import{isAppRun as W}from"./app-run.js";import{registerOutcomeAction as F}from"./outcome-actions.js";import{publish as ce}from"../graph/events.js";import{nodeObject as _e}from"../graph/objects.js";import{findNodeBySessionFileSql as pe}from"./sessions.js";import{hydrateFault as fe}from"./recovery.js";import{hasUnreconciledWorktree as Ee,openWorktree as we,readWorktree as ye,worktreeFromRow as me}from"./worktrees.js";import{isPidAlive as Ne,isPidPresent as b,recordedPidLiveness as Re}from"./pid.js";import{ensureHome as Se,jobDir as he,nodeDir as Oe,nodeRunDir as C}from"./paths.js";import{appForNode as Te,ensureNodeDirs as Le,nodeAgentDir as De}from"./node-agent-paths.js";import{appSpace as H}from"../layout.js";import{createObject as ve,getById as M,ownerForGrantee as ge,setObjectKind as Ae,setObjectName as ke}from"../graph/objects.js";import{deleteNodeWithOwned as xe}from"../graph/deletion.js";import{SUBTREE_ALL_IDS_SQL as Ue,SUBTREE_IDS_SQL as Ie}from"./tree.js";import{filterAsync as y,mapAsync as h}from"../async-array.js";function E(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}a(E,"jsonValue");async function pn(e,n){if((await e.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(n))?.deleting_at)throw new Error("run is deleting")}a(pn,"assertRunNotDeleting");async function je(e,n){const t=await ge(n,e.grantee??"app:terminal");await ve(n,{id:e.node_id,type:"node",kind:e.kind,owner:t.id,privacy:"public",name:e.name,preview:""}),await n.prepare(`INSERT INTO nodes (node_id, description, title, icon, cycles, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, isolated, status, intent, final_report, finalized_at, deadline_at, "window", tmux_session, pane, sub, grant_id, client_id, metadata_json, run_id, event_cursor, usage_json, deleting_at) VALUES (${Array(40).fill("?").join(", ")})`).run(e.node_id,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,E(e.persona_ack,"persona_ack"),E(e.review_binding,"review_binding"),E(e.launch,"launch"),E(e.scopes,"scopes"),e.isolated===!0?1:0,e.status??"active",e.intent??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null,e.sub??null,e.grant_id??null,e.client_id??null,e.metadata_json??null,e.run_id??null,e.event_cursor??null,e.usage_json??null,e.deleting_at??null)}a(je,"seedRow");function P(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,i])=>[t==="fault_id"?t:t.slice(6),i]);return fe(Object.fromEntries(n))}a(P,"faultFrom");function f(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),isolated:e.isolated===1,grantee:e.grantee,sub:e.sub??null,grant_id:e.grant_id??null,client_id:e.client_id??null,metadata_json:e.metadata_json??null,run_id:e.run_id??null,event_cursor:e.event_cursor??null,last_activity_at:e.last_activity_at??null,usage_json:e.usage_json??null,last_turn_error_json:e.last_turn_error_json??null,deleting_at:e.deleting_at??null,parent:e.parent??null,created:e.created,intent:e.intent??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=b(n.pi_pid),i=P(e);return n.fault=i?.link==="pi\u2192provider"&&i.retry.by==="daemon"&&i.retry.disposition==="auto"&&!t?null:i,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}a(f,"rowFrom");async function $(e,n){return n??=await ye(e.node_id),{...f(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}a($,"metaFrom");async function fn(e,n={}){return Se(),await p(async t=>{await je(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&await we(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&await F(t,e.node_id,n.outcomeDelivery),await n.withinCreate?.(t,e)}),await Le(e.node_id),await N(e.node_id)}a(fn,"createNode");async function N(e){const n=await(await r()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:await $(n)}a(N,"getNode");const We=1440*60*1e3;function q(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}a(q,"createRequestRecord");async function En(e){const n=await(await r()).prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return n===void 0?null:q(n)}a(En,"findCreateRequest");async function wn(e){return await p(async n=>{const t=Date.now();await n.prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(t);const i=await n.prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return i!==void 0?q(i):(await n.prepareUncached("INSERT INTO create_requests (request_key, node_id, expires_at, state) VALUES (?, NULL, ?, 'reserved')").run(e,t+We),{requestKey:e,nodeId:null,state:"reserved"})})}a(wn,"reserveCreateRequest");async function yn(e=Date.now()){return Number((await(await r()).prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(e)).changes)}a(yn,"pruneExpiredCreateRequests");async function mn(e,n){await(await r()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)}a(mn,"recordCreateRequestNode");async function Nn(e,n){await(await r()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ?").run(n,e)}a(Nn,"reserveCreateRequestNode");async function Rn(e,n){await(await r()).prepareUncached("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)}a(Rn,"completeCreateRequest");async function Sn(e,n){await p(async t=>{if(n===null){await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id IS NULL").run(e);return}await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id = ?").run(e,n)})}a(Sn,"abandonCreateRequest");function hn(e){return oe(e)}a(hn,"canonicalSessionFile");async function On(e){const n=await pe(e);return n===null?null:await N(n)}a(On,"findNodeBySessionFile");async function Tn(e){const n=await(await r()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}a(Tn,"getRow");async function Ln(e){const n=await(await r()).prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}a(Ln,"getRowByPane");async function Dn(e){return(await(await r()).prepare(`SELECT * FROM node_rows
1
+ var te=Object.defineProperty;var i=(e,n)=>te(e,"name",{value:n,configurable:!0});import{envNodeId as j}from"../../shared/env.js";import{lstatSync as ae,realpathSync as W,rmdirSync as ie,rmSync as oe,statSync as re}from"node:fs";import{basename as se,dirname as F,isAbsolute as de,join as N,relative as ue,resolve as le,sep as ce}from"node:path";import{removeTreeBeneath as b}from"../spaces/open-beneath.js";import{emitEvent as _e}from"../events/emit.js";import{withCanvasWrite as p,openDb as r}from"./db.js";import{conversationStore as pe,ConversationNotFoundError as fe}from"../conversation-store/index.js";import{hasUnseenWakeMail as Ee,UNSEEN_WAKE_MAIL_SQL as we}from"./deliveries.js";import{isAppRun as C}from"./app-run.js";import{registerOutcomeAction as H}from"./outcome-actions.js";import{publish as ye}from"../graph/events.js";import{nodeObject as me}from"../graph/objects.js";import{findNodeBySessionFileSql as Ne}from"./sessions.js";import{hydrateFault as Re}from"./recovery.js";import{hasUnreconciledWorktree as Se,openWorktree as he,readWorktree as Oe,worktreeFromRow as Le}from"./worktrees.js";import{isPidAlive as Te,isPidPresent as M,recordedPidLiveness as De}from"./pid.js";import{ensureHome as ve,jobDir as ge,nodeDir as Ae,nodeRunDir as P}from"./paths.js";import{appForNode as ke,ensureNodeDirs as xe,nodeAgentDir as Ue}from"./node-agent-paths.js";import{appSpace as O}from"../layout.js";import{createObject as Ie,getById as $,ownerForGrantee as je,setObjectKind as We,setObjectName as Fe}from"../graph/objects.js";import{deleteNodeWithOwned as be}from"../graph/deletion.js";import{SUBTREE_ALL_IDS_SQL as Ce,SUBTREE_IDS_SQL as He}from"./tree.js";import{filterAsync as y,mapAsync as L}from"../async-array.js";function E(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}i(E,"jsonValue");async function Rn(e,n){if((await e.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(n))?.deleting_at)throw new Error("run is deleting")}i(Rn,"assertRunNotDeleting");async function Me(e,n){const t=await je(n,e.grantee??"app:terminal");await Ie(n,{id:e.node_id,type:"node",kind:e.kind,owner:t.id,privacy:"public",name:e.name,preview:""}),await n.prepare(`INSERT INTO nodes (node_id, description, title, icon, cycles, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, isolated, status, intent, final_report, finalized_at, deadline_at, "window", tmux_session, pane, sub, grant_id, client_id, metadata_json, run_id, event_cursor, usage_json, deleting_at) VALUES (${Array(40).fill("?").join(", ")})`).run(e.node_id,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,E(e.persona_ack,"persona_ack"),E(e.review_binding,"review_binding"),E(e.launch,"launch"),E(e.scopes,"scopes"),e.isolated===!0?1:0,e.status??"active",e.intent??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null,e.sub??null,e.grant_id??null,e.client_id??null,e.metadata_json??null,e.run_id??null,e.event_cursor??null,e.usage_json??null,e.deleting_at??null)}i(Me,"seedRow");function q(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,a])=>[t==="fault_id"?t:t.slice(6),a]);return Re(Object.fromEntries(n))}i(q,"faultFrom");function f(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),isolated:e.isolated===1,grantee:e.grantee,sub:e.sub??null,grant_id:e.grant_id??null,client_id:e.client_id??null,metadata_json:e.metadata_json??null,run_id:e.run_id??null,event_cursor:e.event_cursor??null,last_activity_at:e.last_activity_at??null,usage_json:e.usage_json??null,last_turn_error_json:e.last_turn_error_json??null,deleting_at:e.deleting_at??null,parent:e.parent??null,created:e.created,intent:e.intent??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=M(n.pi_pid),a=q(e);return n.fault=a?.link==="pi\u2192provider"&&a.retry.by==="daemon"&&a.retry.disposition==="auto"&&!t?null:a,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}i(f,"rowFrom");async function B(e,n){return n??=await Oe(e.node_id),{...f(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}i(B,"metaFrom");async function Sn(e,n={}){return ve(),await p(async t=>{await Me(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&await he(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&await H(t,e.node_id,n.outcomeDelivery),await n.withinCreate?.(t,e)}),await xe(e.node_id),await R(e.node_id)}i(Sn,"createNode");async function R(e){const n=await(await r()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:await B(n)}i(R,"getNode");const Pe=1440*60*1e3;function z(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}i(z,"createRequestRecord");async function hn(e){const n=await(await r()).prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return n===void 0?null:z(n)}i(hn,"findCreateRequest");async function On(e){return await p(async n=>{const t=Date.now();await n.prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(t);const a=await n.prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return a!==void 0?z(a):(await n.prepareUncached("INSERT INTO create_requests (request_key, node_id, expires_at, state) VALUES (?, NULL, ?, 'reserved')").run(e,t+Pe),{requestKey:e,nodeId:null,state:"reserved"})})}i(On,"reserveCreateRequest");async function Ln(e=Date.now()){return Number((await(await r()).prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(e)).changes)}i(Ln,"pruneExpiredCreateRequests");async function Tn(e,n){await(await r()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)}i(Tn,"recordCreateRequestNode");async function Dn(e,n){await(await r()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ?").run(n,e)}i(Dn,"reserveCreateRequestNode");async function vn(e,n){await(await r()).prepareUncached("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)}i(vn,"completeCreateRequest");async function gn(e,n){await p(async t=>{if(n===null){await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id IS NULL").run(e);return}await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id = ?").run(e,n)})}i(gn,"abandonCreateRequest");function An(e){return le(e)}i(An,"canonicalSessionFile");async function kn(e){const n=await Ne(e);return n===null?null:await R(n)}i(kn,"findNodeBySessionFile");async function xn(e){const n=await(await r()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}i(xn,"getRow");async function Un(e){const n=await(await r()).prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}i(Un,"getRowByPane");async function In(e){return(await(await r()).prepare(`SELECT * FROM node_rows
2
2
  WHERE deadline_at IS NOT NULL AND outcome_at IS NULL
3
3
  AND deadline_at <= ? AND status IN ('active','idle') AND kind != 'human'
4
- ORDER BY deadline_at, created, node_id`).all(e)).map(f)}a(Dn,"dueNodeDeadlines");async function vn(e,n){return Number((await(await r()).prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e)).changes)===1}a(vn,"setNodeDeadline");async function gn(e,n){return!Number.isFinite(n)||n<=0?0:await p(async t=>{const i=await t.prepare(`SELECT node_id, deadline_at FROM nodes
5
- WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),o=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let s=0;for(const d of i){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(s+=Number((await o.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at)).changes))}return s})}a(gn,"shiftProfileNodeDeadlines");function O(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}a(O,"sqlInput");async function An(e,n){const t=[],i=a((s,d=s)=>{Object.prototype.hasOwnProperty.call(n,s)&&t.push([d,O(n[s],s)])},"add");if(i("description"),i("title"),i("icon"),i("cycles"),i("mode"),i("lifecycle"),i("cwd"),i("host_kind"),i("profile_id"),i("parent"),i("spawned_by"),i("creator"),i("fork_from"),i("fork_source_file"),i("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"isolated"))throw new TypeError("isolated cannot change after node creation");Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",E(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]);const o=a(s=>Object.prototype.hasOwnProperty.call(n,s),"has");return await p(async s=>{const d=await M(s,e);if(d===null||d.type!=="node")throw new Error(`unknown node: ${e}`);if(o("name")&&await ke(s,d,O(n.name,"name")),o("kind")&&await Ae(s,d,O(n.kind,"kind")),t.length===0)return;if((await s.prepareUncached(`UPDATE nodes SET ${t.map(([u])=>`${u} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,u])=>u),e)).changes!==1)throw new Error(`unknown node: ${e}`)}),await N(e)}a(An,"updateNode");async function kn(e,n){await(await r()).prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}a(kn,"setStatus");async function xn(e,n){await(await r()).prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}a(xn,"setIntent");async function Un(e,n,t={}){if(t.outcome===void 0){const o=[],s=[];Object.prototype.hasOwnProperty.call(n,"status")&&(o.push("status = ?"),s.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(o.push("intent = ?"),s.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(o.push("terminal_reason = ?"),s.push(n.terminal_reason??null));const d=["node_id = ?"];s.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),s.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const l=await(await r()).prepareUncached(`UPDATE nodes SET ${o.join(", ")} WHERE ${d.join(" AND ")}`).run(...s);return Number(l.changes)}const i=t.outcome;return await p(async o=>{const s=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(s.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(s.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(s.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const l=a((x,w)=>i.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${w} END`,"outcomeValue");s.push(`outcome_kind = ${l(i.kind,"outcome_kind")}`,`outcome_reason = ${l(i.reason,"outcome_reason")}`,`outcome_detail_json = ${l(i.detailJson,"outcome_detail_json")}`,`outcome_revision = ${i.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${l(i.at,"outcome_at")}`),d.push(i.kind,i.reason,i.detailJson,i.at);const u=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(u.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&u.push("final_report IS NULL");const _=await o.prepareUncached(`UPDATE nodes SET ${s.join(", ")} WHERE ${u.join(" AND ")}`).run(...d);if(Number(_.changes)===0)return 0;const S=await o.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(i.supersede===!0||S.outcome_at===i.at)&&i.documentJson!==null&&i.documentJson!==void 0&&await ce(o,{event:"outcome",object:await _e(o,e),actor:null,attrs:{revision:Number((await o.prepare("SELECT outcome_revision FROM nodes WHERE node_id = ?").get(e)).outcome_revision)},messageBody:JSON.parse(i.documentJson)}),Number(_.changes)})}a(Un,"transitionStatusIntent");async function In(e){return(await(await r()).prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e))?.final_report??null}a(In,"getFinalReport");async function jn(e,n){return(await(await r()).prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n)).changes>0}a(jn,"clearFinalReportIfMatches");async function Wn(e,n){await(await r()).prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}a(Wn,"setPresence");async function Fn(e,n){await(await r()).prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}a(Fn,"recordLaunch");async function bn(e,n){await(await r()).prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}a(bn,"recordSettledTurn");async function Cn(e,n){await(await r()).prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}a(Cn,"setFrozen");async function Hn(e){await(await r()).prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}a(Hn,"clearFrozen");async function Mn(e,n){await(await r()).prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}a(Mn,"recordRespawnAttempt");const m="node_id NOT IN (SELECT node_id FROM warm_pool)",z=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function Fe(e){return e.worktree_state===null?null:me(Object.fromEntries(z.map(n=>[n,e[`worktree_${n}`]])))}a(Fe,"worktreeFromProjection");async function Pn(e){const n=z.map(i=>`w.${i} AS worktree_${i}`).join(", "),t=await(await r()).prepareUncached(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e);return await h(t,async i=>await $(i,Fe(i)))}a(Pn,"listNodesByProfile");async function $n(){return(await(await r()).prepare(`SELECT
4
+ ORDER BY deadline_at, created, node_id`).all(e)).map(f)}i(In,"dueNodeDeadlines");async function jn(e,n){return Number((await(await r()).prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e)).changes)===1}i(jn,"setNodeDeadline");async function Wn(e,n){return!Number.isFinite(n)||n<=0?0:await p(async t=>{const a=await t.prepare(`SELECT node_id, deadline_at FROM nodes
5
+ WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),o=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let s=0;for(const d of a){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(s+=Number((await o.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at)).changes))}return s})}i(Wn,"shiftProfileNodeDeadlines");function T(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}i(T,"sqlInput");async function Fn(e,n){const t=[],a=i((s,d=s)=>{Object.prototype.hasOwnProperty.call(n,s)&&t.push([d,T(n[s],s)])},"add");if(a("description"),a("title"),a("icon"),a("cycles"),a("mode"),a("lifecycle"),a("cwd"),a("host_kind"),a("profile_id"),a("parent"),a("spawned_by"),a("creator"),a("fork_from"),a("fork_source_file"),a("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"isolated"))throw new TypeError("isolated cannot change after node creation");Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",E(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]);const o=i(s=>Object.prototype.hasOwnProperty.call(n,s),"has");return await p(async s=>{const d=await $(s,e);if(d===null||d.type!=="node")throw new Error(`unknown node: ${e}`);if(o("name")&&await Fe(s,d,T(n.name,"name")),o("kind")&&await We(s,d,T(n.kind,"kind")),t.length===0)return;if((await s.prepareUncached(`UPDATE nodes SET ${t.map(([u])=>`${u} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,u])=>u),e)).changes!==1)throw new Error(`unknown node: ${e}`)}),await R(e)}i(Fn,"updateNode");async function bn(e,n){await(await r()).prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}i(bn,"setStatus");async function Cn(e,n){await(await r()).prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}i(Cn,"setIntent");async function Hn(e,n,t={}){if(t.outcome===void 0){const o=[],s=[];Object.prototype.hasOwnProperty.call(n,"status")&&(o.push("status = ?"),s.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(o.push("intent = ?"),s.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(o.push("terminal_reason = ?"),s.push(n.terminal_reason??null));const d=["node_id = ?"];s.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),s.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const l=await(await r()).prepareUncached(`UPDATE nodes SET ${o.join(", ")} WHERE ${d.join(" AND ")}`).run(...s);return Number(l.changes)}const a=t.outcome;return await p(async o=>{const s=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(s.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(s.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(s.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const l=i((I,w)=>a.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${w} END`,"outcomeValue");s.push(`outcome_kind = ${l(a.kind,"outcome_kind")}`,`outcome_reason = ${l(a.reason,"outcome_reason")}`,`outcome_detail_json = ${l(a.detailJson,"outcome_detail_json")}`,`outcome_revision = ${a.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${l(a.at,"outcome_at")}`),d.push(a.kind,a.reason,a.detailJson,a.at);const u=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(u.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&u.push("final_report IS NULL");const _=await o.prepareUncached(`UPDATE nodes SET ${s.join(", ")} WHERE ${u.join(" AND ")}`).run(...d);if(Number(_.changes)===0)return 0;const h=await o.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(a.supersede===!0||h.outcome_at===a.at)&&a.documentJson!==null&&a.documentJson!==void 0&&await ye(o,{event:"outcome",object:await me(o,e),actor:null,attrs:{revision:Number((await o.prepare("SELECT outcome_revision FROM nodes WHERE node_id = ?").get(e)).outcome_revision)},messageBody:JSON.parse(a.documentJson)}),Number(_.changes)})}i(Hn,"transitionStatusIntent");async function Mn(e){return(await(await r()).prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e))?.final_report??null}i(Mn,"getFinalReport");async function Pn(e,n){return(await(await r()).prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n)).changes>0}i(Pn,"clearFinalReportIfMatches");async function $n(e,n){await(await r()).prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}i($n,"setPresence");async function qn(e,n){await(await r()).prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}i(qn,"recordLaunch");async function Bn(e,n){await(await r()).prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}i(Bn,"recordSettledTurn");async function zn(e,n){await(await r()).prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}i(zn,"setFrozen");async function Jn(e){await(await r()).prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}i(Jn,"clearFrozen");async function Yn(e,n){await(await r()).prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}i(Yn,"recordRespawnAttempt");const m="node_id NOT IN (SELECT node_id FROM warm_pool)",J=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function $e(e){return e.worktree_state===null?null:Le(Object.fromEntries(J.map(n=>[n,e[`worktree_${n}`]])))}i($e,"worktreeFromProjection");async function Qn(e){const n=J.map(a=>`w.${a} AS worktree_${a}`).join(", "),t=await(await r()).prepareUncached(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e);return await L(t,async a=>await B(a,$e(a)))}i(Qn,"listNodesByProfile");async function Vn(){return(await(await r()).prepare(`SELECT
6
6
  node_id, name, description, kind, mode, lifecycle, status, cwd, profile_id,
7
7
  grantee, parent, created, frozen_at, terminal_reason, final_report,
8
8
  telemetry_tokens_in, telemetry_updated_at, pi_pid, turn_open_at, turn_closed_at,
@@ -10,13 +10,13 @@ var ee=Object.defineProperty;var a=(e,n)=>ee(e,"name",{value:n,configurable:!0})
10
10
  fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
11
11
  fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
12
12
  fault_provider_error_json
13
- FROM node_rows WHERE ${m} ORDER BY created`).all()).map(f)}a($n,"browseNodes");async function qn(e,n){await(await r()).prepare(`UPDATE nodes
13
+ FROM node_rows WHERE ${m} ORDER BY created`).all()).map(f)}i(Vn,"browseNodes");async function Kn(e,n){await(await r()).prepare(`UPDATE nodes
14
14
  SET telemetry_tokens_in = ?,
15
15
  telemetry_context_tokens = COALESCE(?, telemetry_context_tokens),
16
16
  telemetry_last_activity = COALESCE(?, telemetry_last_activity),
17
17
  telemetry_updated_at = ?
18
18
  WHERE node_id = ?
19
- AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}a(qn,"updateNodeTelemetry");async function zn(){return(await(await r()).prepare(`SELECT
19
+ AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}i(Kn,"updateNodeTelemetry");async function Gn(){return(await(await r()).prepare(`SELECT
20
20
  node_id, name, description, cycles, kind, status, frozen_at,
21
21
  telemetry_context_tokens, telemetry_last_activity,
22
22
  pi_pid, turn_open_at, turn_closed_at,
@@ -24,14 +24,14 @@ var ee=Object.defineProperty;var a=(e,n)=>ee(e,"name",{value:n,configurable:!0})
24
24
  fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
25
25
  fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
26
26
  fault_provider_error_json
27
- FROM node_rows WHERE ${m} ORDER BY created`).all()).map(n=>{const t=n.pi_pid??null,i=b(t),o=P(n);return{node_id:n.node_id,name:n.name,description:n.description??null,cycles:n.cycles??null,kind:n.kind,status:n.status,frozen_at:n.frozen_at??null,pi_pid:t,telemetry_context_tokens:n.telemetry_context_tokens??null,telemetry_last_activity:n.telemetry_last_activity??null,fault:o?.link==="pi\u2192provider"&&o.retry.by==="daemon"&&o.retry.disposition==="auto"&&!i?null:o,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&i}})}a(zn,"graphNodes");async function be(e){const n=[m],t=[];if(e?.under!==void 0&&(e.underInclusive===!0?(n.push(`(node_id IN (${Ue}) OR node_id = ?)`),t.push(e.under,e.under,e.under)):(n.push(`node_id IN (${Ie})`),t.push(e.under,e.under))),e?.lifecycle!==void 0&&(n.push("lifecycle = ?"),t.push(e.lifecycle)),e?.kind!==void 0&&(n.push("kind = ?"),t.push(e.kind)),e?.mode!==void 0&&(n.push("mode = ?"),t.push(e.mode)),e?.profileId!==void 0&&(n.push("profile_id = ?"),t.push(e.profileId)),e?.profilePrefix!==void 0&&(n.push("profile_id LIKE ? ESCAPE '\\'"),t.push(`${e.profilePrefix.replace(/[\\%_]/g,o=>`\\${o}`)}%`)),e?.parent!==void 0&&(n.push("parent = ?"),t.push(e.parent)),e?.topLevel===!0&&n.push("parent IS NULL"),e?.hanging===!0&&n.push("parent IS NOT NULL AND parent NOT IN (SELECT node_id FROM node_rows)"),e?.status!==void 0){const o=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${o.map(()=>"?").join(",")})`),t.push(...o)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),(await(await r()).prepareUncached(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t)).map(f)}a(be,"listNodes");const Ce=`SELECT
27
+ FROM node_rows WHERE ${m} ORDER BY created`).all()).map(n=>{const t=n.pi_pid??null,a=M(t),o=q(n);return{node_id:n.node_id,name:n.name,description:n.description??null,cycles:n.cycles??null,kind:n.kind,status:n.status,frozen_at:n.frozen_at??null,pi_pid:t,telemetry_context_tokens:n.telemetry_context_tokens??null,telemetry_last_activity:n.telemetry_last_activity??null,fault:o?.link==="pi\u2192provider"&&o.retry.by==="daemon"&&o.retry.disposition==="auto"&&!a?null:o,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&a}})}i(Gn,"graphNodes");async function qe(e){const n=[m],t=[];if(e?.under!==void 0&&(e.underInclusive===!0?(n.push(`(node_id IN (${Ce}) OR node_id = ?)`),t.push(e.under,e.under,e.under)):(n.push(`node_id IN (${He})`),t.push(e.under,e.under))),e?.lifecycle!==void 0&&(n.push("lifecycle = ?"),t.push(e.lifecycle)),e?.kind!==void 0&&(n.push("kind = ?"),t.push(e.kind)),e?.mode!==void 0&&(n.push("mode = ?"),t.push(e.mode)),e?.profileId!==void 0&&(n.push("profile_id = ?"),t.push(e.profileId)),e?.profilePrefix!==void 0&&(n.push("profile_id LIKE ? ESCAPE '\\'"),t.push(`${e.profilePrefix.replace(/[\\%_]/g,o=>`\\${o}`)}%`)),e?.parent!==void 0&&(n.push("parent = ?"),t.push(e.parent)),e?.topLevel===!0&&n.push("parent IS NULL"),e?.hanging===!0&&n.push("parent IS NOT NULL AND parent NOT IN (SELECT node_id FROM node_rows)"),e?.status!==void 0){const o=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${o.map(()=>"?").join(",")})`),t.push(...o)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),(await(await r()).prepareUncached(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t)).map(f)}i(qe,"listNodes");const Be=`SELECT
28
28
  node_id, created, launched_at, last_settled_at, finalized_at,
29
29
  outcome_at, last_activity_at, pane, "window", tmux_session
30
30
  FROM nodes
31
31
  WHERE ${m}
32
32
  AND status IN ('done', 'canceled', 'dead')
33
33
  AND (pane IS NOT NULL OR "window" IS NOT NULL OR tmux_session IS NOT NULL)
34
- ORDER BY created`;async function Bn(){return await(await r()).prepare(Ce).all()}a(Bn,"listTerminalPlacementResidue");const He=`WITH candidates AS MATERIALIZED (
34
+ ORDER BY created`;async function Xn(){return await(await r()).prepare(Be).all()}i(Xn,"listTerminalPlacementResidue");const ze=`WITH candidates AS MATERIALIZED (
35
35
  SELECT node_id FROM nodes WHERE status IN ('active', 'idle')
36
36
  UNION
37
37
  SELECT node_id FROM nodes
@@ -45,23 +45,23 @@ var ee=Object.defineProperty;var a=(e,n)=>ee(e,"name",{value:n,configurable:!0})
45
45
  AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
46
46
  AND v.kind != 'human'
47
47
  AND (v.status IN ('active', 'idle') OR (v.status IN ('done', 'canceled', 'dead') AND (v.pi_pid IS NOT NULL OR v.frozen_at IS NOT NULL)))
48
- ORDER BY v.created`;async function Jn(){return(await(await r()).prepare(He).all()).map(f)}a(Jn,"listNodesForSupervision");const B=a(e=>`(${e}.status = 'done' AND ${e}.intent = 'parked' AND ${e}.lifecycle = 'resident' AND ${e}.final_report IS NULL AND ${e}.deleting_at IS NULL)`,"PARKED_RESIDENT_SQL"),Me=a(e=>`(${e}.status IN ('active', 'idle') OR ${B(e)} OR (${e}.status IN ('done', 'canceled', 'dead') AND ${e}.frozen_at IS NOT NULL AND ${e}.final_report IS NULL))`,"RESUMABLE_NODE_SQL");async function Yn(e){return await(await r()).prepare(`SELECT node_id, cwd FROM nodes WHERE ${Me("nodes")} AND node_id != ?`).all(e)}a(Yn,"resumableNodeCwds");async function Qn(){return(await(await r()).prepare(`SELECT v.* FROM node_rows v
49
- WHERE ${B("v")}
50
- AND EXISTS (SELECT 1 FROM deliveries d WHERE d.destination_id = v.node_id AND ${le("d")}) AND v.kind != 'human' AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
51
- ORDER BY v.created`).all()).map(f)}a(Qn,"listParkedResidentsWithWakeMail");async function Vn(e,n){await(await r()).prepare("INSERT INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?) ON CONFLICT (node_id) DO UPDATE SET recipe_key = excluded.recipe_key, created = excluded.created").run(e,n,new Date().toISOString())}a(Vn,"registerWarmSpare");async function Kn(e){return(await(await r()).prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e)).changes>0}a(Kn,"unregisterWarmSpare");async function T(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
48
+ ORDER BY v.created`;async function Zn(){return(await(await r()).prepare(ze).all()).map(f)}i(Zn,"listNodesForSupervision");const Y=i(e=>`(${e}.status = 'done' AND ${e}.intent = 'parked' AND ${e}.lifecycle = 'resident' AND ${e}.final_report IS NULL AND ${e}.deleting_at IS NULL)`,"PARKED_RESIDENT_SQL"),Je=i(e=>`(${e}.status IN ('active', 'idle') OR ${Y(e)} OR (${e}.status IN ('done', 'canceled', 'dead') AND ${e}.frozen_at IS NOT NULL AND ${e}.final_report IS NULL))`,"RESUMABLE_NODE_SQL");async function et(e){return await(await r()).prepare(`SELECT node_id, cwd FROM nodes WHERE ${Je("nodes")} AND node_id != ?`).all(e)}i(et,"resumableNodeCwds");async function nt(){return(await(await r()).prepare(`SELECT v.* FROM node_rows v
49
+ WHERE ${Y("v")}
50
+ AND EXISTS (SELECT 1 FROM deliveries d WHERE d.destination_id = v.node_id AND ${we("d")}) AND v.kind != 'human' AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
51
+ ORDER BY v.created`).all()).map(f)}i(nt,"listParkedResidentsWithWakeMail");async function tt(e,n){await(await r()).prepare("INSERT INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?) ON CONFLICT (node_id) DO UPDATE SET recipe_key = excluded.recipe_key, created = excluded.created").run(e,n,new Date().toISOString())}i(tt,"registerWarmSpare");async function at(e){return(await(await r()).prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e)).changes>0}i(at,"unregisterWarmSpare");async function D(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
52
52
  n.status AS status, n.pi_pid AS pi_pid, n.pi_pid_identity AS pi_pid_identity
53
- FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?await e.prepareUncached(t).all():await e.prepareUncached(t).all(n)).map(o=>({node_id:o.node_id,recipe_key:o.recipe_key,created:o.created,status:o.status,pi_pid:o.pi_pid??null,pi_pid_identity:o.pi_pid_identity??null}))}a(T,"warmSpareRowsFor");async function Gn(){return await T(await r())}a(Gn,"listWarmSpares");async function Xn(e){return await(await r()).prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}a(Xn,"isWarmSpare");function J(e){return e.status!=="active"&&e.status!=="idle"?!1:Re(e.pi_pid,e.pi_pid_identity)==="alive"}a(J,"spareIsClaimable");async function Zn(e,n,t={}){return await p(async i=>{const o=(await T(i,e)).find(J);return o===void 0||t.requestKey!==void 0&&(await i.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'warm_claimed' WHERE request_key = ? AND node_id IS NULL").run(o.node_id,t.requestKey)).changes===0||(await i.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(o.node_id)).changes===0?null:(await i.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,o.node_id),t.outcomeDelivery!==void 0&&await F(i,o.node_id,t.outcomeDelivery),o.node_id)})}a(Zn,"claimWarmSpare");async function et(e){return(await T(await r(),e)).filter(J).length}a(et,"warmSpareCount");async function nt(e){return(await(await r()).prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e)).map(n=>n.node_id)}a(nt,"childrenOf");async function tt(){return(await(await r()).prepareUncached(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created, description
54
- FROM node_rows WHERE ${m} ORDER BY created`).all()).map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created,description:e.description??null}))}a(tt,"rosterNodes");async function at(e){return(await(await r()).prepareUncached(`SELECT * FROM node_rows
53
+ FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?await e.prepareUncached(t).all():await e.prepareUncached(t).all(n)).map(o=>({node_id:o.node_id,recipe_key:o.recipe_key,created:o.created,status:o.status,pi_pid:o.pi_pid??null,pi_pid_identity:o.pi_pid_identity??null}))}i(D,"warmSpareRowsFor");async function it(){return await D(await r())}i(it,"listWarmSpares");async function ot(e){return await(await r()).prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}i(ot,"isWarmSpare");function Q(e){return e.status!=="active"&&e.status!=="idle"?!1:De(e.pi_pid,e.pi_pid_identity)==="alive"}i(Q,"spareIsClaimable");async function rt(e,n,t={}){return await p(async a=>{const o=(await D(a,e)).find(Q);return o===void 0||t.requestKey!==void 0&&(await a.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'warm_claimed' WHERE request_key = ? AND node_id IS NULL").run(o.node_id,t.requestKey)).changes===0||(await a.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(o.node_id)).changes===0?null:(await a.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,o.node_id),t.outcomeDelivery!==void 0&&await H(a,o.node_id,t.outcomeDelivery),o.node_id)})}i(rt,"claimWarmSpare");async function st(e){return(await D(await r(),e)).filter(Q).length}i(st,"warmSpareCount");async function dt(e){return(await(await r()).prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e)).map(n=>n.node_id)}i(dt,"childrenOf");async function ut(){return(await(await r()).prepareUncached(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created, description
54
+ FROM node_rows WHERE ${m} ORDER BY created`).all()).map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created,description:e.description??null}))}i(ut,"rosterNodes");async function lt(e){return(await(await r()).prepareUncached(`SELECT * FROM node_rows
55
55
  WHERE parent IS NULL AND kind != 'human'
56
56
  AND status IN ('active','idle') AND cwd = ?
57
57
  AND ${m}
58
- ORDER BY created DESC`).all(e)).map(f)}a(at,"listResumableRoots");export*from"./tree.js";async function it(e,n,t){return await p(async i=>{const o=await i.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return o===void 0?{kind:"missing"}:n(o)?{kind:"terminal",status:o.status,final_report:o.final_report}:{kind:"ran",result:await t()}})}a(it,"withFreshTerminalGuard");async function R(e){return await Ee(e)}a(R,"hasUnreconciledManagedWorktree");async function Y(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||await R(e.node_id)||e.node_id===U()||W(e)?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}a(Y,"isCollectible");async function L(e){if(e.length===0)return[];const n=e.map(()=>"?").join(",");return(await(await r()).prepareUncached(`SELECT DISTINCT session_id FROM sessions WHERE node_id IN (${n}) AND session_id IS NOT NULL`).all(...e)).map(({session_id:i})=>i)}a(L,"nodeConversationIds");async function D(e){const n=await r(),t=n.prepare("SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),i=n.prepare(`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
59
- AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const o of e)if(!(await t.get(o)!==void 0||await i.get(o)!==void 0))try{await se().delete(o)}catch(s){if(!(s instanceof de))throw s}}a(D,"deleteNodeConversations");async function v(e,n){const t=await M(e,n);return t===null||t.deleted_at!==null?!1:(await xe(e,t),!0)}a(v,"deleteNodeObject");async function g(e){return{nodeId:e,app:await N(e)===null?null:await Te(e)}}a(g,"nodeFiles");async function Q({nodeId:e,app:n}){n!==null&&j(H(n).nodes,await De(e,n)),j(ie(C(e)),C(e))}a(Q,"removeNodeAppTrees");function V({nodeId:e}){return[Oe(e)]}a(V,"nodeOwnedDirs");function K({nodeId:e,app:n}){if(n!==null)try{ne(I(H(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}a(K,"removeNodeConversationDir");async function A(e){await Q(e);for(const n of V(e))te(n,{recursive:!0,force:!0});K(e)}a(A,"removeNodeFiles");async function ot(e){if(await R(e))return{deleted:!1};const n=await g(e),t=await L([e]),i=await p(async o=>(await v(o,e),{deleted:!0}));return await D(t),await A(n),i}a(ot,"deleteNode");async function rt(e){const n=[...new Set(e)];if(n.length===0)return[];const t=await y(n,R);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const i=await h(n,g),o=await L(n),s=n.map(()=>"?").join(","),d=(await(await r()).prepareUncached(`SELECT node_id FROM nodes WHERE node_id IN (${s}) ORDER BY created`).all(...n)).map(({node_id:u})=>u),l=await y(d,async u=>await p(async _=>await v(_,u)));await D(o);for(const u of l){const _=i[n.indexOf(u)];await k(_,async()=>await A(_))}return l}a(rt,"deleteNodes");async function st(e){const n=e.dryRun??!1,t=e.includeStale??!1,i=Date.now()-e.ttlDays*864e5,o=new Date(i).toISOString(),s=U()??"",d=await r(),l=a(c=>Z(c)<i,"quiet"),u=a(c=>({node_id:c.node_id,status:c.status,created:c.created}),"toPruned"),_=await Pe(),S=(await y((await d.prepare(`SELECT * FROM node_rows
58
+ ORDER BY created DESC`).all(e)).map(f)}i(lt,"listResumableRoots");export*from"./tree.js";async function ct(e,n,t){return await p(async a=>{const o=await a.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return o===void 0?{kind:"missing"}:n(o)?{kind:"terminal",status:o.status,final_report:o.final_report}:{kind:"ran",result:await t()}})}i(ct,"withFreshTerminalGuard");async function S(e){return await Se(e)}i(S,"hasUnreconciledManagedWorktree");async function V(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||await S(e.node_id)||e.node_id===j()||C(e)?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}i(V,"isCollectible");async function v(e){if(e.length===0)return[];const n=e.map(()=>"?").join(","),t=await(await r()).prepareUncached(`SELECT s.session_id, s.transcript_path, s.node_id, n.grantee FROM sessions s JOIN node_rows n ON n.node_id = s.node_id WHERE s.node_id IN (${n}) AND s.session_id IS NOT NULL AND s.transcript_path IS NOT NULL ORDER BY s.created_at, s.seq`).all(...e);return[...new Map(t.map(a=>[a.session_id,{id:a.session_id,path:a.transcript_path,dir:N(O(a.grantee).conversations,a.node_id)}])).values()]}i(v,"nodeConversationIds");async function g(e){const n=await r(),t=n.prepare("SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),a=n.prepare(`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
59
+ AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const{id:o,path:s,dir:d}of e)if(!(await t.get(o)!==void 0||await a.get(o)!==void 0)&&ae(s,{throwIfNoEntry:!1})!==void 0){if(!Ye(d,s)){console.error(`[canvas] not deleting transcript outside its node's conversations directory: ${s}`);continue}try{await pe().delete(o,s)}catch(l){if(!(l instanceof fe))throw l}}}i(g,"deleteNodeConversations");function Ye(e,n){try{const t=ue(W(e),N(W(F(n)),se(n)));return t!==""&&t!==".."&&!t.startsWith(`..${ce}`)&&!de(t)}catch(t){if(t.code==="ENOENT")return!1;throw t}}i(Ye,"isBeneath");async function A(e,n){const t=await $(e,n);return t===null||t.deleted_at!==null?!1:(await be(e,t),!0)}i(A,"deleteNodeObject");async function k(e){return{nodeId:e,app:await R(e)===null?null:await ke(e)}}i(k,"nodeFiles");async function K({nodeId:e,app:n}){n!==null&&b(O(n).nodes,await Ue(e,n)),b(F(P(e)),P(e))}i(K,"removeNodeAppTrees");function G({nodeId:e}){return[Ae(e)]}i(G,"nodeOwnedDirs");function X({nodeId:e,app:n}){if(n!==null)try{ie(N(O(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}i(X,"removeNodeConversationDir");async function x(e){await K(e);for(const n of G(e))oe(n,{recursive:!0,force:!0});X(e)}i(x,"removeNodeFiles");async function _t(e){if(await S(e))return{deleted:!1};const n=await k(e),t=await v([e]),a=await p(async o=>(await A(o,e),{deleted:!0}));return await g(t),await x(n),a}i(_t,"deleteNode");async function pt(e){const n=[...new Set(e)];if(n.length===0)return[];const t=await y(n,S);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const a=await L(n,k),o=await v(n),s=n.map(()=>"?").join(","),d=(await(await r()).prepareUncached(`SELECT node_id FROM nodes WHERE node_id IN (${s}) ORDER BY created`).all(...n)).map(({node_id:u})=>u),l=await y(d,async u=>await p(async _=>await A(_,u)));await g(o);for(const u of l){const _=a[n.indexOf(u)];await U(_,async()=>await x(_))}return l}i(pt,"deleteNodes");async function ft(e){const n=e.dryRun??!1,t=e.includeStale??!1,a=Date.now()-e.ttlDays*864e5,o=new Date(a).toISOString(),s=j()??"",d=await r(),l=i(c=>ne(c)<a,"quiet"),u=i(c=>({node_id:c.node_id,status:c.status,created:c.created}),"toPruned"),_=await Qe(),h=(await y((await d.prepare(`SELECT * FROM node_rows
60
60
  WHERE status IN ('dead', 'done', 'canceled') AND created < ?
61
- ORDER BY created`).all(o)).map(f),async c=>await Y(c,{pastTtl:!0})&&l(c)&&!_.has(c.node_id)&&!await e.held(c.node_id))).map(u),x=t?(await y((await d.prepare(`SELECT * FROM node_rows
61
+ ORDER BY created`).all(o)).map(f),async c=>await V(c,{pastTtl:!0})&&l(c)&&!_.has(c.node_id)&&!await e.held(c.node_id))).map(u),I=t?(await y((await d.prepare(`SELECT * FROM node_rows
62
62
  WHERE status IN ('active', 'idle') AND created < ?
63
- ORDER BY created`).all(o)).map(f),async c=>c.node_id!==s&&!Ne(c.pi_pid??null)&&(c.frozen_at??null)===null&&(c.respawn_not_before??null)===null&&c.intent!=="idle-release"&&!W(c)&&!await ue(c.node_id)&&!await R(c.node_id)&&l(c)&&!await e.held(c.node_id))).map(u):[],w=await G([...S,...x]);return n||w.length===0?{pruned:w,dryRun:n}:(await X(w,e.removeDirs),{pruned:w,dryRun:n})}a(st,"pruneNodes");async function Pe(){const e=await(await r()).prepare(`SELECT DISTINCT d.owner AS owner FROM watches w
63
+ ORDER BY created`).all(o)).map(f),async c=>c.node_id!==s&&!Te(c.pi_pid??null)&&(c.frozen_at??null)===null&&(c.respawn_not_before??null)===null&&c.intent!=="idle-release"&&!C(c)&&!await Ee(c.node_id)&&!await S(c.node_id)&&l(c)&&!await e.held(c.node_id))).map(u):[],w=await Z([...h,...I]);return n||w.length===0?{pruned:w,dryRun:n}:(await ee(w,e.removeDirs),{pruned:w,dryRun:n})}i(ft,"pruneNodes");async function Qe(){const e=await(await r()).prepare(`SELECT DISTINCT d.owner AS owner FROM watches w
64
64
  JOIN objects d ON d.id = w.object AND d.type = 'document' AND d.deleted_at IS NULL
65
65
  JOIN objects o ON o.id = w.watcher AND o.deleted_at IS NULL
66
66
  LEFT JOIN nodes n ON n.node_id = w.watcher
67
- WHERE w.watcher != d.owner AND d.owner IS NOT NULL AND (n.node_id IS NULL OR n.status IN ('active', 'idle'))`).all();return new Set(e.map(n=>n.owner))}a(Pe,"ownersOfWatchedDocuments");async function G(e){const t=(await r()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),i=new Set(e.map(o=>o.node_id));return await y(e,async o=>(await t.all(o.node_id,o.node_id)).every(s=>i.has(s.node_id)))}a(G,"retainRunRootsWithMembers");async function X(e,n){if(e.length===0)return;const t=await h(e,async o=>await g(o.node_id)),i=await L(e.map(o=>o.node_id));for(const o of e)await p(async s=>await v(s,o.node_id));if(await D(i),n!==void 0){for(const o of t)await k(o,async()=>{await Q(o),K(o)});n(t.flatMap(V));return}for(const o of t)await k(o,async()=>await A(o))}a(X,"deletePrunedNodes");async function k(e,n){try{n()}catch(t){re({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}a(k,"eachNodeBestEffort");function Z(e){let n=0;for(const t of[e.created,e.launched_at,e.last_settled_at,e.finalized_at,e.outcome_at,e.last_activity_at]){if(t==null)continue;const i=Date.parse(t);Number.isFinite(i)&&i>n&&(n=i)}try{const t=ae(I(he(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}a(Z,"lastActivityMs");async function dt(e){const n=e.dryRun??!1,t=await be(),i=await y(t,async u=>await Y(u)&&!await e.held(u.node_id)),o=t.length-i.length,s=Math.max(0,e.maxNodes-o),d=i.map(u=>({row:u,recency:Z(u)})).sort((u,_)=>_.recency-u.recency).slice(s).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created})),l=await G(d);return n||l.length===0?{pruned:l,dryRun:n}:(await X(l),{pruned:l,dryRun:n})}a(dt,"pruneToLimit");export{B as PARKED_RESIDENT_SQL,Me as RESUMABLE_NODE_SQL,Sn as abandonCreateRequest,pn as assertRunNotDeleting,$n as browseNodes,hn as canonicalSessionFile,nt as childrenOf,Zn as claimWarmSpare,jn as clearFinalReportIfMatches,Hn as clearFrozen,Rn as completeCreateRequest,fn as createNode,ot as deleteNode,rt as deleteNodes,Dn as dueNodeDeadlines,En as findCreateRequest,On as findNodeBySessionFile,In as getFinalReport,N as getNode,Tn as getRow,Ln as getRowByPane,zn as graphNodes,Y as isCollectible,Xn as isWarmSpare,Z as lastActivityMs,be as listNodes,Pn as listNodesByProfile,Jn as listNodesForSupervision,Qn as listParkedResidentsWithWakeMail,at as listResumableRoots,Bn as listTerminalPlacementResidue,Gn as listWarmSpares,g as nodeFiles,He as nodesForSupervisionSql,yn as pruneExpiredCreateRequests,st as pruneNodes,dt as pruneToLimit,mn as recordCreateRequestNode,Fn as recordLaunch,Mn as recordRespawnAttempt,bn as recordSettledTurn,Vn as registerWarmSpare,A as removeNodeFiles,wn as reserveCreateRequest,Nn as reserveCreateRequestNode,Yn as resumableNodeCwds,tt as rosterNodes,Cn as setFrozen,xn as setIntent,vn as setNodeDeadline,Wn as setPresence,kn as setStatus,gn as shiftProfileNodeDeadlines,Ce as terminalPlacementResidueSql,Un as transitionStatusIntent,Kn as unregisterWarmSpare,An as updateNode,qn as updateNodeTelemetry,et as warmSpareCount,it as withFreshTerminalGuard};
67
+ WHERE w.watcher != d.owner AND d.owner IS NOT NULL AND (n.node_id IS NULL OR n.status IN ('active', 'idle'))`).all();return new Set(e.map(n=>n.owner))}i(Qe,"ownersOfWatchedDocuments");async function Z(e){const t=(await r()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),a=new Set(e.map(o=>o.node_id));return await y(e,async o=>(await t.all(o.node_id,o.node_id)).every(s=>a.has(s.node_id)))}i(Z,"retainRunRootsWithMembers");async function ee(e,n){if(e.length===0)return;const t=await L(e,async o=>await k(o.node_id)),a=await v(e.map(o=>o.node_id));for(const o of e)await p(async s=>await A(s,o.node_id));if(await g(a),n!==void 0){for(const o of t)await U(o,async()=>{await K(o),X(o)});n(t.flatMap(G));return}for(const o of t)await U(o,async()=>await x(o))}i(ee,"deletePrunedNodes");async function U(e,n){try{n()}catch(t){_e({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}i(U,"eachNodeBestEffort");function ne(e){let n=0;for(const t of[e.created,e.launched_at,e.last_settled_at,e.finalized_at,e.outcome_at,e.last_activity_at]){if(t==null)continue;const a=Date.parse(t);Number.isFinite(a)&&a>n&&(n=a)}try{const t=re(N(ge(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}i(ne,"lastActivityMs");async function Et(e){const n=e.dryRun??!1,t=await qe(),a=await y(t,async u=>await V(u)&&!await e.held(u.node_id)),o=t.length-a.length,s=Math.max(0,e.maxNodes-o),d=a.map(u=>({row:u,recency:ne(u)})).sort((u,_)=>_.recency-u.recency).slice(s).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created})),l=await Z(d);return n||l.length===0?{pruned:l,dryRun:n}:(await ee(l),{pruned:l,dryRun:n})}i(Et,"pruneToLimit");export{Y as PARKED_RESIDENT_SQL,Je as RESUMABLE_NODE_SQL,gn as abandonCreateRequest,Rn as assertRunNotDeleting,Vn as browseNodes,An as canonicalSessionFile,dt as childrenOf,rt as claimWarmSpare,Pn as clearFinalReportIfMatches,Jn as clearFrozen,vn as completeCreateRequest,Sn as createNode,_t as deleteNode,pt as deleteNodes,In as dueNodeDeadlines,hn as findCreateRequest,kn as findNodeBySessionFile,Mn as getFinalReport,R as getNode,xn as getRow,Un as getRowByPane,Gn as graphNodes,V as isCollectible,ot as isWarmSpare,ne as lastActivityMs,qe as listNodes,Qn as listNodesByProfile,Zn as listNodesForSupervision,nt as listParkedResidentsWithWakeMail,lt as listResumableRoots,Xn as listTerminalPlacementResidue,it as listWarmSpares,k as nodeFiles,ze as nodesForSupervisionSql,Ln as pruneExpiredCreateRequests,ft as pruneNodes,Et as pruneToLimit,Tn as recordCreateRequestNode,qn as recordLaunch,Yn as recordRespawnAttempt,Bn as recordSettledTurn,tt as registerWarmSpare,x as removeNodeFiles,On as reserveCreateRequest,Dn as reserveCreateRequestNode,et as resumableNodeCwds,ut as rosterNodes,zn as setFrozen,Cn as setIntent,jn as setNodeDeadline,$n as setPresence,bn as setStatus,Wn as shiftProfileNodeDeadlines,Be as terminalPlacementResidueSql,Hn as transitionStatusIntent,at as unregisterWarmSpare,Fn as updateNode,Kn as updateNodeTelemetry,st as warmSpareCount,ct as withFreshTerminalGuard};
@@ -1,9 +1,9 @@
1
- var G=Object.defineProperty;var u=(l,o)=>G(l,"name",{value:o,configurable:!0});import{randomUUID as J}from"node:crypto";import{closeSync as v,createReadStream as K,existsSync as $,fsyncSync as k,mkdirSync as L,openSync as z,readFileSync as P,readSync as M,renameSync as Q,statSync as S,unlinkSync as O,writeFileSync as j}from"node:fs";import{createInterface as T}from"node:readline";import{dirname as V,join as F,relative as X,resolve as b}from"node:path";import{SessionManager as Y}from"@earendil-works/pi-coding-agent";import{ConversationNotFoundError as Z}from"./index.js";function E(l){const o=[];for(const w of l.split(`
2
- `))if(w.trim())try{o.push(JSON.parse(w))}catch{}return o}u(E,"parseLines");function I(l){const o=z(l,"r");try{const w=Buffer.allocUnsafe(4096);let f="";for(;;){const h=M(o,w,0,w.length,null);f+=w.toString("utf8",0,h);let y=f.indexOf(`
3
- `);for(;y!==-1||h===0;){const m=y===-1?f:f.slice(0,y),[d]=E(m);if(d!==void 0)return d;if(y===-1)return;f=f.slice(y+1),y=f.indexOf(`
4
- `)}}}finally{v(o)}}u(I,"firstLine");function ee(l,o){const w=z(l,"r");try{const f=Buffer.alloc(1);return M(w,f,0,1,o-1),f[0]}finally{v(w)}}u(ee,"lastByte");function C(l,o){return[l,...o].map(w=>`${JSON.stringify(w)}
5
- `).join("")}u(C,"lines");function W(l,o){const w=`--${b(o).replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`;return F(l,w)}u(W,"sessionDirectory");function A(l){return`${l.timestamp.replace(/[:.]/g,"-")}_${l.id}.jsonl`}u(A,"fileName");function ce(l,o){const{appendSection:w}=o,f=new Map,h=new Map;L(l,{recursive:!0,mode:448});const y=new Set;async function m(e){if(y.has(e))return;const t=await d(e);if(await o.repair?.(e,t),!$(t)){f.delete(e),h.delete(e);return}y.add(e)}u(m,"repair");async function d(e){const t=f.get(e)??await o.pathFor?.(e);if(!t)throw new Z(e);return f.set(e,t),t}u(d,"pathFor");async function x(e){await m(e);const t=await d(e),r=E(P(t,"utf8")),n=r.shift();if(n?.type!=="session"||n.id!==e)throw new Error(`invalid conversation: ${e}`);return{header:n,entries:r,path:t}}u(x,"read");function B(e,t){const r=I(t);return r?.type==="session"&&r.id===e?r:void 0}u(B,"validHeader");async function N(e){const t=await d(e),r=B(e,t);if(!r)throw new Error(`invalid conversation: ${e}`);return{header:r,path:t}}u(N,"headerOf");async function H(e,t){await m(e);const{header:r,path:n}=await N(e),c=S(n).size;if(c<=t.head+t.tail)return await x(e);const i=z(n,"r");try{const a=u((R,_)=>{if(_<=0)return[];const U=Buffer.allocUnsafe(_),q=M(i,U,0,_,R);return U.subarray(0,q).toString("utf8").split(`
6
- `)},"slice"),s=a(0,t.head),p=a(c-t.tail,t.tail);s.pop(),p.shift();const g=E(s.join(`
1
+ var G=Object.defineProperty;var u=(l,o)=>G(l,"name",{value:o,configurable:!0});import{randomUUID as J}from"node:crypto";import{closeSync as v,createReadStream as K,existsSync as $,fsyncSync as M,mkdirSync as L,openSync as z,readFileSync as C,readSync as k,renameSync as Q,rmSync as T,statSync as S,unlinkSync as O,writeFileSync as j}from"node:fs";import{createInterface as V}from"node:readline";import{dirname as X,join as F,relative as Y,resolve as b}from"node:path";import{SessionManager as Z}from"@earendil-works/pi-coding-agent";import{ConversationNotFoundError as I}from"./index.js";function E(l){const o=[];for(const w of l.split(`
2
+ `))if(w.trim())try{o.push(JSON.parse(w))}catch{}return o}u(E,"parseLines");function ee(l){const o=z(l,"r");try{const w=Buffer.allocUnsafe(4096);let f="";for(;;){const h=k(o,w,0,w.length,null);f+=w.toString("utf8",0,h);let d=f.indexOf(`
3
+ `);for(;d!==-1||h===0;){const m=d===-1?f:f.slice(0,d),[y]=E(m);if(y!==void 0)return y;if(d===-1)return;f=f.slice(d+1),d=f.indexOf(`
4
+ `)}}}finally{v(o)}}u(ee,"firstLine");function te(l,o){const w=z(l,"r");try{const f=Buffer.alloc(1);return k(w,f,0,1,o-1),f[0]}finally{v(w)}}u(te,"lastByte");function P(l,o){return[l,...o].map(w=>`${JSON.stringify(w)}
5
+ `).join("")}u(P,"lines");function W(l,o){const w=`--${b(o).replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`;return F(l,w)}u(W,"sessionDirectory");function A(l){return`${l.timestamp.replace(/[:.]/g,"-")}_${l.id}.jsonl`}u(A,"fileName");function fe(l,o){const{appendSection:w}=o,f=new Map,h=new Map;L(l,{recursive:!0,mode:448});const d=new Set;async function m(t){if(d.has(t))return;const e=await y(t);if(await o.repair?.(t,e),!$(e)){f.delete(t),h.delete(t);return}d.add(t)}u(m,"repair");async function y(t){const e=f.get(t)??await o.pathFor?.(t);if(!e)throw new I(t);return f.set(t,e),e}u(y,"pathFor");async function x(t){await m(t);const e=await y(t),r=E(C(e,"utf8")),n=r.shift();if(n?.type!=="session"||n.id!==t)throw new Error(`invalid conversation: ${t}`);return{header:n,entries:r,path:e}}u(x,"read");function B(t,e){const r=ee(e);return r?.type==="session"&&r.id===t?r:void 0}u(B,"validHeader");async function N(t){const e=await y(t),r=B(t,e);if(!r)throw new Error(`invalid conversation: ${t}`);return{header:r,path:e}}u(N,"headerOf");async function H(t,e){await m(t);const{header:r,path:n}=await N(t),c=S(n).size;if(c<=e.head+e.tail)return await x(t);const i=z(n,"r");try{const a=u((R,_)=>{if(_<=0)return[];const U=Buffer.allocUnsafe(_),q=k(i,U,0,_,R);return U.subarray(0,q).toString("utf8").split(`
6
+ `)},"slice"),s=a(0,e.head),p=a(c-e.tail,e.tail);s.pop(),p.shift();const g=E(s.join(`
7
7
  `));return g[0]?.type==="session"&&g.shift(),{header:r,entries:g,tail:E(p.join(`
8
- `)),path:n}}finally{v(i)}}u(H,"readWindow");async function D(e,t,r,n,c){if(f.has(t.id))throw new Error(`conversation already exists: ${t.id}`);const i=X(l,n);if(i.startsWith("..")||i===""||b(n)===b(l))throw new Error("conversation path outside store root");if(L(V(n),{recursive:!0,mode:448}),$(n))throw new Error(`conversation file already exists: ${n}`);let a=!1;try{const s=u(()=>{const p=z(n,"wx",384);a=!0;try{return j(p,C(t,r)),k(p),a=!1,S(n).size}finally{v(p)}},"write");return e===void 0?s():await w(t.id,{kind:"create",nodeId:e,path:n,entries:r,...c?{sourceId:c}:{}},s),f.set(t.id,n),t.id}catch(s){throw a||!$(n)?($(n)&&O(n),await o.abortCreate?.(t.id)):f.set(t.id,n),s}}return u(D,"createAt"),{recover(e){for(const t of e){if(!t.transcript_path)continue;const r=f.get(t.session_id);if(r&&r!==t.transcript_path)throw new Error(`conflicting conversation paths: ${t.session_id}`);f.set(t.session_id,t.transcript_path)}},repair:m,async readLines(e){await m(e);const t=await d(e),r=T({input:K(t),crlfDelay:1/0});return{path:t,lines:r}},async create(e,t,r,n){return await D(e,t,r,await o.createPath?.(e,t)??n??F(W(l,t.cwd),A(t)))},async append(e,t,r){if(t.length===0)return;await m(e);const n=await d(e);if(r?.dedupe){const i=new Set((await x(e)).entries.map(a=>a.id));if(t=t.filter(a=>!i.has(a.id)),t.length===0)return}const c=S(n).size;if(c>0&&ee(n,c)!==10)throw new Error(`incomplete conversation tail: ${e}`);try{await w(e,{kind:"append",entries:t},()=>{const i=z(n,"a");try{return j(i,t.map(a=>`${JSON.stringify(a)}
9
- `).join("")),k(i),S(n).size}finally{v(i)}})}catch(i){throw y.delete(e),i}},async replace(e,t,r){await m(e);const n=await d(e);if(t.id!==e)throw new Error("replacement header id differs from conversation id");const c=P(n),i=u(s=>{const p=`${n}.${J()}.tmp`;try{j(p,s,{flag:"wx",mode:384});const g=z(p,"r");try{k(g)}finally{v(g)}Q(p,n)}finally{$(p)&&O(p)}},"swap");let a=!1;try{await w(e,{kind:"replace"},()=>(i(C(t,r)),a=!0,S(n).size))}catch(s){throw a&&i(c),s}finally{h.delete(e)}},async read(e,t){return t?await H(e,t):await x(e)},async header(e){await m(e);const{header:t,path:r}=await N(e),n=S(r);return{header:t,path:r,mtime:n.mtimeMs,size:n.size}},async fork(e,t,r,n){const c=await x(e);let i=c.entries;if(r!==void 0){const p=Y.inMemory(c.header.cwd,void 0,[c.header,...i]);p.createBranchedSession(r),i=p.getEntries()}const a=new Date().toISOString(),s={...c.header,id:J(),timestamp:a,cwd:n??c.header.cwd,parentSession:c.path};return await D(t,s,i,t&&o.createPath?await o.createPath(t,s):F(W(l,s.cwd),A(s)),e)},async list(e){const t=[],r=await o.owners();for(const n of new Set([...f.keys(),...r.keys()])){const c=r.get(n);if(e!==void 0&&c!==e||(await m(n),!f.has(n)))continue;const i=await d(n),a=S(i);let s=h.get(n);(!s||s.mtime!==a.mtimeMs||s.size!==a.size)&&(s={mtime:a.mtimeMs,size:a.size,header:B(n,i)},h.set(n,s)),s.header&&t.push({conversation_id:n,...c?{node_id:c}:{},header:s.header,mtime:a.mtimeMs,size:a.size,path:i})}return t.sort((n,c)=>c.mtime-n.mtime)},async delete(e){O(await d(e)),await o.delete?.(e),f.delete(e),y.delete(e),h.delete(e)}}}u(ce,"createFileStore");export{ce as createFileStore,W as sessionDirectory};
8
+ `)),path:n}}finally{v(i)}}u(H,"readWindow");async function D(t,e,r,n,c){if(f.has(e.id))throw new Error(`conversation already exists: ${e.id}`);const i=Y(l,n);if(i.startsWith("..")||i===""||b(n)===b(l))throw new Error("conversation path outside store root");if(L(X(n),{recursive:!0,mode:448}),$(n))throw new Error(`conversation file already exists: ${n}`);let a=!1;try{const s=u(()=>{const p=z(n,"wx",384);a=!0;try{return j(p,P(e,r)),M(p),a=!1,S(n).size}finally{v(p)}},"write");return t===void 0?s():await w(e.id,{kind:"create",nodeId:t,path:n,entries:r,...c?{sourceId:c}:{}},s),f.set(e.id,n),e.id}catch(s){throw a||!$(n)?($(n)&&O(n),await o.abortCreate?.(e.id)):f.set(e.id,n),s}}return u(D,"createAt"),{recover(t){for(const e of t){if(!e.transcript_path)continue;const r=f.get(e.session_id);if(r&&r!==e.transcript_path)throw new Error(`conflicting conversation paths: ${e.session_id}`);f.set(e.session_id,e.transcript_path)}},repair:m,async readLines(t){await m(t);const e=await y(t),r=V({input:K(e),crlfDelay:1/0});return{path:e,lines:r}},async create(t,e,r,n){return await D(t,e,r,await o.createPath?.(t,e)??n??F(W(l,e.cwd),A(e)))},async append(t,e,r){if(e.length===0)return;await m(t);const n=await y(t);if(r?.dedupe){const i=new Set((await x(t)).entries.map(a=>a.id));if(e=e.filter(a=>!i.has(a.id)),e.length===0)return}const c=S(n).size;if(c>0&&te(n,c)!==10)throw new Error(`incomplete conversation tail: ${t}`);try{await w(t,{kind:"append",entries:e},()=>{const i=z(n,"a");try{return j(i,e.map(a=>`${JSON.stringify(a)}
9
+ `).join("")),M(i),S(n).size}finally{v(i)}})}catch(i){throw d.delete(t),i}},async replace(t,e,r){await m(t);const n=await y(t);if(e.id!==t)throw new Error("replacement header id differs from conversation id");const c=C(n),i=u(s=>{const p=`${n}.${J()}.tmp`;try{j(p,s,{flag:"wx",mode:384});const g=z(p,"r");try{M(g)}finally{v(g)}Q(p,n)}finally{$(p)&&O(p)}},"swap");let a=!1;try{await w(t,{kind:"replace"},()=>(i(P(e,r)),a=!0,S(n).size))}catch(s){throw a&&i(c),s}finally{h.delete(t)}},async read(t,e){return e?await H(t,e):await x(t)},async header(t){await m(t);const{header:e,path:r}=await N(t),n=S(r);return{header:e,path:r,mtime:n.mtimeMs,size:n.size}},async fork(t,e,r,n){const c=await x(t);let i=c.entries;if(r!==void 0){const p=Z.inMemory(c.header.cwd,void 0,[c.header,...i]);p.createBranchedSession(r),i=p.getEntries()}const a=new Date().toISOString(),s={...c.header,id:J(),timestamp:a,cwd:n??c.header.cwd,parentSession:c.path};return await D(e,s,i,e&&o.createPath?await o.createPath(e,s):F(W(l,s.cwd),A(s)),t)},async list(t){const e=[],r=await o.owners();for(const n of new Set([...f.keys(),...r.keys()])){const c=r.get(n);if(t!==void 0&&c!==t||(await m(n),!f.has(n)))continue;const i=await y(n),a=S(i);let s=h.get(n);(!s||s.mtime!==a.mtimeMs||s.size!==a.size)&&(s={mtime:a.mtimeMs,size:a.size,header:B(n,i)},h.set(n,s)),s.header&&e.push({conversation_id:n,...c?{node_id:c}:{},header:s.header,mtime:a.mtimeMs,size:a.size,path:i})}return e.sort((n,c)=>c.mtime-n.mtime)},async delete(t,e){e===void 0?O(await y(t)):T(e,{force:!0}),await o.delete?.(t),f.delete(t),d.delete(t),h.delete(t)}}}u(fe,"createFileStore");export{fe as createFileStore,W as sessionDirectory};
@@ -78,7 +78,9 @@ export interface ConversationStore {
78
78
  }>;
79
79
  fork(id: string, nodeId?: string, leafId?: string, cwd?: string): Promise<string>;
80
80
  list(nodeId?: string): Promise<ConversationInfo[]>;
81
- delete(id: string): Promise<void>;
81
+ /** `path` names the transcript when its sessions row is already gone (the in-process store only;
82
+ * the socket client resolves from the row and ignores it). A file already missing there is not an error. */
83
+ delete(id: string, path?: string): Promise<void>;
82
84
  }
83
85
  export declare function conversationIdFromPath(path: string): string | null;
84
86
  export declare function defaultConversationRoot(): string;
@@ -1 +1 @@
1
- var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});import{appsRoot as i,socketDir as p}from"../layout.js";import{join as d}from"node:path";import{createStoreClient as f}from"./client.js";import{currentNodeToken as u}from"../runtime/broker/node-token.js";class l extends Error{static{o(this,"ConversationNotFoundError")}code="not_found";constructor(r){super(`conversation not found: ${r}`)}}function h(e){return e instanceof l}o(h,"isConversationNotFound");function k(e){return/(?:^|\/)[^/]+_([0-9a-f-]{36})\.jsonl$/i.exec(e)?.[1]??null}o(k,"conversationIdFromPath");function R(){return i()}o(R,"defaultConversationRoot");function m(){return process.env.CRTR_STORE_ADDRESS||d(p(),"store.sock")}o(m,"storeAddress");let t,s;function A(e){t=e}o(A,"installConversationStore");function F(){if(t)return t;const e=a();return{create:o(async(...r)=>e.create(...r),"create"),append:o(async(...r)=>e.append(...r),"append"),replace:o(async(...r)=>e.replace(...r),"replace"),read:o(async(...r)=>e.read(...r),"read"),header:o(async(...r)=>e.header(...r),"header"),fork:o(async(...r)=>e.fork(...r),"fork"),list:o(async(...r)=>e.list(...r),"list"),delete:o(async(...r)=>e.delete(...r),"delete")}}o(F,"conversationStore");function a(){const e=m();return s?.address!==e&&(s={address:e,store:f(e,u())}),s.store}o(a,"conversationClient");async function D(e,r){if(t)return t.read(e,r);const n=a();return n.readAsync?n.readAsync(e,r):n.read(e,r)}o(D,"readConversationAsync");import{createFileStore as _,sessionDirectory as N}from"./file-store.js";import{installSessionManagerStorePatch as T}from"./patch.js";import{findOrphanedParents as $,relinkOrphanedParents as g,repairConversationFile as I}from"./repair.js";export{l as ConversationNotFoundError,a as conversationClient,k as conversationIdFromPath,F as conversationStore,_ as createFileStore,R as defaultConversationRoot,$ as findOrphanedParents,A as installConversationStore,T as installSessionManagerStorePatch,h as isConversationNotFound,D as readConversationAsync,g as relinkOrphanedParents,I as repairConversationFile,N as sessionDirectory,m as storeAddress};
1
+ var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});import{appsRoot as i,socketDir as p}from"../layout.js";import{join as d}from"node:path";import{createStoreClient as f}from"./client.js";import{currentNodeToken as u}from"../runtime/broker/node-token.js";class l extends Error{static{o(this,"ConversationNotFoundError")}code="not_found";constructor(r){super(`conversation not found: ${r}`)}}function h(e){return e instanceof l}o(h,"isConversationNotFound");function k(e){return/(?:^|\/)[^/]+_([0-9a-f-]{36})\.jsonl$/i.exec(e)?.[1]??null}o(k,"conversationIdFromPath");function R(){return i()}o(R,"defaultConversationRoot");function m(){return process.env.CRTR_STORE_ADDRESS||d(p(),"store.sock")}o(m,"storeAddress");let t,s;function A(e){t=e}o(A,"installConversationStore");function F(){if(t)return t;const e=a();return{create:o(async(...r)=>e.create(...r),"create"),append:o(async(...r)=>e.append(...r),"append"),replace:o(async(...r)=>e.replace(...r),"replace"),read:o(async(...r)=>e.read(...r),"read"),header:o(async(...r)=>e.header(...r),"header"),fork:o(async(...r)=>e.fork(...r),"fork"),list:o(async(...r)=>e.list(...r),"list"),delete:o(async r=>e.delete(r),"delete")}}o(F,"conversationStore");function a(){const e=m();return s?.address!==e&&(s={address:e,store:f(e,u())}),s.store}o(a,"conversationClient");async function D(e,r){if(t)return t.read(e,r);const n=a();return n.readAsync?n.readAsync(e,r):n.read(e,r)}o(D,"readConversationAsync");import{createFileStore as _,sessionDirectory as N}from"./file-store.js";import{installSessionManagerStorePatch as T}from"./patch.js";import{findOrphanedParents as $,relinkOrphanedParents as g,repairConversationFile as I}from"./repair.js";export{l as ConversationNotFoundError,a as conversationClient,k as conversationIdFromPath,F as conversationStore,_ as createFileStore,R as defaultConversationRoot,$ as findOrphanedParents,A as installConversationStore,T as installSessionManagerStorePatch,h as isConversationNotFound,D as readConversationAsync,g as relinkOrphanedParents,I as repairConversationFile,N as sessionDirectory,m as storeAddress};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.546",
3
+ "version": "0.3.547",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -140,7 +140,7 @@
140
140
  },
141
141
  "license": "UNLICENSED",
142
142
  "dependencies": {
143
- "@north-light/identity": "0.3.546",
143
+ "@north-light/identity": "0.3.547",
144
144
  "@earendil-works/pi-agent-core": "1.1.0",
145
145
  "@earendil-works/pi-ai": "1.1.0",
146
146
  "@earendil-works/pi-coding-agent": "1.1.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/identity",
3
- "version": "0.3.546",
3
+ "version": "0.3.547",
4
4
  "description": "Northlight access-token verification and scope rules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.546",
3
+ "version": "0.3.547",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/cli",
9
- "version": "0.3.546",
9
+ "version": "0.3.547",
10
10
  "hasInstallScript": true,
11
11
  "license": "UNLICENSED",
12
12
  "workspaces": [
@@ -24,7 +24,7 @@
24
24
  "@milkdown/preset-gfm": "^7.22.3",
25
25
  "@milkdown/prose": "^7.22.3",
26
26
  "@milkdown/utils": "^7.22.3",
27
- "@north-light/identity": "0.3.546",
27
+ "@north-light/identity": "0.3.547",
28
28
  "cron-parser": "^5.6.0",
29
29
  "esbuild": "^0.27.7",
30
30
  "jose": "^6.2.12",
@@ -12455,17 +12455,17 @@
12455
12455
  },
12456
12456
  "packages/crouter-api": {
12457
12457
  "name": "@north-light/api",
12458
- "version": "0.3.546",
12458
+ "version": "0.3.547",
12459
12459
  "license": "UNLICENSED"
12460
12460
  },
12461
12461
  "packages/crouter-env-docker": {
12462
12462
  "name": "@north-light/env-docker",
12463
- "version": "0.3.546",
12463
+ "version": "0.3.547",
12464
12464
  "license": "UNLICENSED"
12465
12465
  },
12466
12466
  "packages/crouter-identity": {
12467
12467
  "name": "@north-light/identity",
12468
- "version": "0.3.546",
12468
+ "version": "0.3.547",
12469
12469
  "license": "UNLICENSED",
12470
12470
  "dependencies": {
12471
12471
  "jose": "^6.2.1"
@@ -12473,21 +12473,21 @@
12473
12473
  },
12474
12474
  "packages/crouter-plugin": {
12475
12475
  "name": "@north-light/plugin",
12476
- "version": "0.3.546",
12476
+ "version": "0.3.547",
12477
12477
  "license": "UNLICENSED",
12478
12478
  "dependencies": {
12479
- "@north-light/api": "0.3.546",
12480
- "@north-light/identity": "0.3.546"
12479
+ "@north-light/api": "0.3.547",
12480
+ "@north-light/identity": "0.3.547"
12481
12481
  }
12482
12482
  },
12483
12483
  "packages/crouter-sdk": {
12484
12484
  "name": "@north-light/sdk",
12485
- "version": "0.3.546",
12485
+ "version": "0.3.547",
12486
12486
  "license": "UNLICENSED",
12487
12487
  "dependencies": {
12488
- "@north-light/api": "0.3.546",
12489
- "@north-light/identity": "0.3.546",
12490
- "@north-light/plugin": "0.3.546",
12488
+ "@north-light/api": "0.3.547",
12489
+ "@north-light/identity": "0.3.547",
12490
+ "@north-light/plugin": "0.3.547",
12491
12491
  "jose": "^6.2.1"
12492
12492
  },
12493
12493
  "bin": {