@north-light/cli 0.3.460 → 0.3.461
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,11 +1,11 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Z=Object.defineProperty;var r=(e,n)=>Z(e,"name",{value:n,configurable:!0});import{prepared as a}from"../sqlite-statements.js";import{envNodeId as k}from"../../shared/env.js";import{rmdirSync as ee,rmSync as ne,statSync as te}from"node:fs";import{dirname as oe,join as x,resolve as re}from"node:path";import{removeTreeBeneath as W}from"../spaces/open-beneath.js";import{emitEvent as ie}from"../events/emit.js";import{openDb as d,prepared as j,withCanvasWrite as p}from"./db.js";import{conversationStore as se,ConversationNotFoundError as ae}from"../conversation-store/index.js";import{hasUnseenWakeMail as de}from"./deliveries.js";import{isAppRun as H}from"./app-run.js";import{registerOutcomeAction as F}from"./outcome-actions.js";import{publish as le}from"../graph/events.js";import{nodeObject as ue}from"../graph/objects.js";import{findNodeBySessionFileSql as _e}from"./sessions.js";import{hydrateFault as ce}from"./recovery.js";import{hasUnreconciledWorktree as pe,openWorktree as fe,readWorktree as Ee,worktreeFromRow as me}from"./worktrees.js";import{isPidAlive as Ne,isPidPresent as b,recordedPidLiveness as Re}from"./pid.js";import{ensureHome as we,jobDir as ye,nodeDir as Se,nodeRunDir as C}from"./paths.js";import{appForNode as ge,ensureNodeDirs as Oe,nodeAgentDir as Te}from"./node-agent-paths.js";import{appSpace as I}from"../layout.js";import{createObject as he,getById as U,ownerForGrantee as M,setObjectKind as Le,setObjectName as De}from"../graph/objects.js";import{deleteNodeWithOwned as ve}from"../graph/deletion.js";function m(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}r(m,"jsonValue");function rn(e,n){if(a(e,"SELECT deleting_at FROM nodes WHERE node_id = ?").get(n)?.deleting_at)throw new Error("run is deleting")}r(rn,"assertRunNotDeleting");function Ae(e,n){const t=M(n,e.grantee??"app:terminal");he(n,{id:e.node_id,type:"node",kind:e.kind,owner:t.rowid,privacy:"public",name:e.name,preview:""}),a(n,`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, waiting_for, 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(41).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,m(e.persona_ack,"persona_ack"),m(e.review_binding,"review_binding"),m(e.launch,"launch"),m(e.scopes,"scopes"),e.isolated===!0?1:0,e.status??"active",e.intent??null,e.waiting_for??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)}r(Ae,"seedRow");function P(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,o])=>[t==="fault_id"?t:t.slice(6),o]);return ce(Object.fromEntries(n))}r(P,"faultFrom");function E(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,waiting_for:e.waiting_for??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),o=P(e);return n.fault=o?.link==="pi\u2192provider"&&o.retry.by==="daemon"&&o.retry.disposition==="auto"&&!t?null:o,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}r(E,"rowFrom");function q(e,n=Ee(e.node_id)){return{...E(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}}}r(q,"metaFrom");function sn(e,n={}){return we(),p(t=>{Ae(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&fe(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&F(t,e.node_id,n.outcomeDelivery),n.withinCreate?.(t,e)}),Oe(e.node_id),R(e.node_id)}r(sn,"createNode");function R(e){const n=j(d(),"SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:q(n)}r(R,"getNode");const ke=1440*60*1e3;function $(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}r($,"createRequestRecord");function an(e){const n=d().prepare("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return n===void 0?null:$(n)}r(an,"findCreateRequest");function dn(e){return p(n=>{const t=Date.now();n.prepare("DELETE FROM create_requests WHERE expires_at <= ?").run(t);const o=n.prepare("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return o!==void 0?$(o):(n.prepare("INSERT INTO create_requests (request_key, node_id, expires_at, state) VALUES (?, NULL, ?, 'reserved')").run(e,t+ke),{requestKey:e,nodeId:null,state:"reserved"})})}r(dn,"reserveCreateRequest");function ln(e=Date.now()){return p(n=>Number(n.prepare("DELETE FROM create_requests WHERE expires_at <= ?").run(e).changes))}r(ln,"pruneExpiredCreateRequests");function un(e,n){p(t=>{t.prepare("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)})}r(un,"recordCreateRequestNode");function _n(e,n){p(t=>{t.prepare("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ?").run(n,e)})}r(_n,"reserveCreateRequestNode");function cn(e,n){p(t=>{t.prepare("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)})}r(cn,"completeCreateRequest");function pn(e,n){p(t=>{if(n===null){t.prepare("DELETE FROM create_requests WHERE request_key = ? AND node_id IS NULL").run(e);return}t.prepare("DELETE FROM create_requests WHERE request_key = ? AND node_id = ?").run(e,n)})}r(pn,"abandonCreateRequest");function fn(e){return re(e)}r(fn,"canonicalSessionFile");function En(e){const n=_e(e);return n===null?null:R(n)}r(En,"findNodeBySessionFile");function mn(e){const n=a(d(),"SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?E(n):null}r(mn,"getRow");function Nn(e){const n=a(d(),"SELECT * FROM node_rows WHERE pane = ?").get(e);return n?E(n):null}r(Nn,"getRowByPane");function Rn(e){return a(d(),`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(
|
|
5
|
-
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=a(t,"UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let s=0;for(const l of o){const
|
|
4
|
+
ORDER BY deadline_at, created, node_id`).all(e).map(E)}r(Rn,"dueNodeDeadlines");function wn(e,n){return Number(a(d(),"UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e).changes)===1}r(wn,"setNodeDeadline");function yn(e,n){return!Number.isFinite(n)||n<=0?0:p(t=>{const o=a(t,`SELECT node_id, deadline_at FROM nodes
|
|
5
|
+
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=a(t,"UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let s=0;for(const l of o){const c=Date.parse(l.deadline_at);Number.isNaN(c)||(s+=Number(i.run(new Date(c+n).toISOString(),l.node_id,l.deadline_at).changes))}return s})}r(yn,"shiftProfileNodeDeadlines");function Sn(e,n,t){const o=`SELECT o.rowid FROM objects o JOIN identities i ON i.object = o.owner
|
|
6
6
|
WHERE o.type = 'node' AND i.scheme = 'local-user' AND i.external_id = 'user:local'`,s=e.prepare(`${o} LIMIT 1`).get()!==void 0?Number(e.prepare(`UPDATE objects SET owner = ? WHERE rowid IN (${o})`).run(M(e,"app:terminal").rowid).changes):0;return Number(a(e,"UPDATE nodes SET sub = ? WHERE sub = 'user:local'").run(n).changes)+s+Number(a(e,`UPDATE nodes SET sub = ? WHERE sub IS NULL AND node_id IN (
|
|
7
7
|
SELECT o.id FROM objects o JOIN identities i ON i.object = o.owner
|
|
8
|
-
WHERE o.type = 'node' AND i.scheme = 'app' AND i.external_id = 'app:terminal')`).run(n).changes)+Number(a(e,"UPDATE nodes SET grant_id = NULL WHERE grant_id = ?").run(t).changes)}r(
|
|
8
|
+
WHERE o.type = 'node' AND i.scheme = 'app' AND i.external_id = 'app:terminal')`).run(n).changes)+Number(a(e,"UPDATE nodes SET grant_id = NULL WHERE grant_id = ?").run(t).changes)}r(Sn,"rewriteLocalNodeIdentity");function g(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`)}r(g,"sqlInput");function gn(e,n){const t=[],o=r((s,l=s)=>{Object.prototype.hasOwnProperty.call(n,s)&&t.push([l,g(n[s],s)])},"add");if(o("description"),o("title"),o("icon"),o("cycles"),o("mode"),o("lifecycle"),o("cwd"),o("host_kind"),o("profile_id"),o("parent"),o("spawned_by"),o("creator"),o("fork_from"),o("fork_source_file"),o("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",m(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",m(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",m(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",m(n.launch,"launch")]);const i=r(s=>Object.prototype.hasOwnProperty.call(n,s),"has");return p(s=>{const l=U(s,e);if(l===null||l.type!=="node")throw new Error(`unknown node: ${e}`);if(i("name")&&De(s,l,g(n.name,"name")),i("kind")&&Le(s,l,g(n.kind,"kind")),t.length===0)return;if(s.prepare(`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}`)}),R(e)}r(gn,"updateNode");function On(e,n){a(d(),"UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}r(On,"setStatus");function Tn(e,n){a(d(),"UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}r(Tn,"setIntent");function hn(e,n,t={}){if(t.outcome===void 0){const i=[],s=[];Object.prototype.hasOwnProperty.call(n,"status")&&(i.push("status = ?"),s.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(i.push("intent = ?"),s.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(i.push("terminal_reason = ?"),s.push(n.terminal_reason??null));const l=["node_id = ?"];s.push(e),t.fromStatuses!==void 0&&(l.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),s.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&l.push("final_report IS NULL");const c=d().prepare(`UPDATE nodes SET ${i.join(", ")} WHERE ${l.join(" AND ")}`).run(...s);return Number(c.changes)}const o=t.outcome;return p(i=>{const s=[],l=[];Object.prototype.hasOwnProperty.call(n,"status")&&(s.push("status = ?"),l.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(s.push("intent = ?"),l.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(s.push("terminal_reason = ?"),l.push(n.terminal_reason??null));const c=r((w,_)=>o.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${_} END`,"outcomeValue");s.push(`outcome_kind = ${c(o.kind,"outcome_kind")}`,`outcome_reason = ${c(o.reason,"outcome_reason")}`,`outcome_detail_json = ${c(o.detailJson,"outcome_detail_json")}`,`outcome_revision = ${o.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${c(o.at,"outcome_at")}`),l.push(o.kind,o.reason,o.detailJson,o.at);const u=["node_id = ?"];l.push(e),t.fromStatuses!==void 0&&(u.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),l.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&u.push("final_report IS NULL");const f=i.prepare(`UPDATE nodes SET ${s.join(", ")} WHERE ${u.join(" AND ")}`).run(...l);if(Number(f.changes)===0)return 0;const S=a(i,"SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(o.supersede===!0||S.outcome_at===o.at)&&o.documentJson!==null&&o.documentJson!==void 0&&le(i,{event:"outcome",object:ue(i,e),actor:null,attrs:{revision:Number(a(i,"SELECT outcome_revision FROM nodes WHERE node_id = ?").get(e).outcome_revision)},messageBody:JSON.parse(o.documentJson)}),Number(f.changes)})}r(hn,"transitionStatusIntent");function Ln(e){return a(d(),"SELECT final_report FROM nodes WHERE node_id = ?").get(e)?.final_report??null}r(Ln,"getFinalReport");function Dn(e,n){return a(d(),"UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n).changes>0}r(Dn,"clearFinalReportIfMatches");function vn(e,n){a(d(),'UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}r(vn,"setPresence");function An(e,n){a(d(),"UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}r(An,"recordLaunch");function kn(e,n){a(d(),"UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}r(kn,"recordSettledTurn");function xn(e,n){a(d(),"UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}r(xn,"setFrozen");function Wn(e){a(d(),"UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}r(Wn,"clearFrozen");function jn(e,n){a(d(),"UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}r(jn,"recordRespawnAttempt");const N="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 xe(e){return e.worktree_state===null?null:me(Object.fromEntries(z.map(n=>[n,e[`worktree_${n}`]])))}r(xe,"worktreeFromProjection");function Hn(e){const n=z.map(o=>`w.${o} AS worktree_${o}`).join(", ");return d().prepare(`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).map(o=>q(o,xe(o)))}r(Hn,"listNodesByProfile");function Fn(){const e=d();return j(e,`SELECT
|
|
9
9
|
node_id, name, description, kind, mode, lifecycle, status, cwd, profile_id,
|
|
10
10
|
grantee, parent, created, frozen_at, terminal_reason, final_report,
|
|
11
11
|
telemetry_tokens_in, telemetry_updated_at, pi_pid, turn_open_at, turn_closed_at,
|
|
@@ -13,13 +13,13 @@ var K=Object.defineProperty;var r=(e,n)=>K(e,"name",{value:n,configurable:!0});i
|
|
|
13
13
|
fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
|
|
14
14
|
fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
|
|
15
15
|
fault_provider_error_json
|
|
16
|
-
FROM node_rows WHERE ${N} ORDER BY created`).all().map(
|
|
16
|
+
FROM node_rows WHERE ${N} ORDER BY created`).all().map(E)}r(Fn,"browseNodes");function bn(e,n){a(d(),`UPDATE nodes
|
|
17
17
|
SET telemetry_tokens_in = ?,
|
|
18
18
|
telemetry_context_tokens = COALESCE(?, telemetry_context_tokens),
|
|
19
19
|
telemetry_last_activity = COALESCE(?, telemetry_last_activity),
|
|
20
20
|
telemetry_updated_at = ?
|
|
21
21
|
WHERE node_id = ?
|
|
22
|
-
AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}r(
|
|
22
|
+
AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}r(bn,"updateNodeTelemetry");function Cn(){return a(d(),`SELECT
|
|
23
23
|
node_id, name, description, cycles, kind, status, frozen_at,
|
|
24
24
|
telemetry_context_tokens, telemetry_last_activity,
|
|
25
25
|
pi_pid, turn_open_at, turn_closed_at,
|
|
@@ -27,14 +27,14 @@ var K=Object.defineProperty;var r=(e,n)=>K(e,"name",{value:n,configurable:!0});i
|
|
|
27
27
|
fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
|
|
28
28
|
fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
|
|
29
29
|
fault_provider_error_json
|
|
30
|
-
FROM node_rows WHERE ${N} ORDER BY created`).all().map(n=>{const t=n.pi_pid??null,o=b(t),i=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:i?.link==="pi\u2192provider"&&i.retry.by==="daemon"&&i.retry.disposition==="auto"&&!o?null:i,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&o}})}r(
|
|
30
|
+
FROM node_rows WHERE ${N} ORDER BY created`).all().map(n=>{const t=n.pi_pid??null,o=b(t),i=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:i?.link==="pi\u2192provider"&&i.retry.by==="daemon"&&i.retry.disposition==="auto"&&!o?null:i,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&o}})}r(Cn,"graphNodes");function We(e){const n=[N],t=[];if(e?.status!==void 0){const i=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${i.map(()=>"?").join(",")})`),t.push(...i)}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)"),d().prepare(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t).map(E)}r(We,"listNodes");const je=`SELECT
|
|
31
31
|
node_id, created, launched_at, last_settled_at, finalized_at,
|
|
32
32
|
outcome_at, last_activity_at, pane, "window", tmux_session
|
|
33
33
|
FROM nodes INDEXED BY idx_nodes_terminal_placement_created
|
|
34
34
|
WHERE ${N}
|
|
35
35
|
AND status IN ('done', 'canceled', 'dead')
|
|
36
36
|
AND (pane IS NOT NULL OR "window" IS NOT NULL OR tmux_session IS NOT NULL)
|
|
37
|
-
ORDER BY created`;function In(){return a(d(),
|
|
37
|
+
ORDER BY created`;function In(){return a(d(),je).all()}r(In,"listTerminalPlacementResidue");const He=`WITH candidates AS MATERIALIZED (
|
|
38
38
|
SELECT node_id FROM nodes WHERE status IN ('active', 'idle')
|
|
39
39
|
UNION
|
|
40
40
|
SELECT node_id FROM nodes INDEXED BY idx_nodes_supervision_frozen
|
|
@@ -48,18 +48,18 @@ var K=Object.defineProperty;var r=(e,n)=>K(e,"name",{value:n,configurable:!0});i
|
|
|
48
48
|
AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
|
|
49
49
|
AND v.kind != 'human'
|
|
50
50
|
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)))
|
|
51
|
-
ORDER BY v.created`;function
|
|
51
|
+
ORDER BY v.created`;function Un(){return a(d(),He).all().map(E)}r(Un,"listNodesForSupervision");function Mn(){return a(d(),`SELECT node_id, name, created, grantee FROM node_rows WHERE ${N} ORDER BY created`).all()}r(Mn,"listNodeIdentities");function Pn(e,n){p(t=>{a(t,"INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)").run(e,n,new Date().toISOString())})}r(Pn,"registerWarmSpare");function qn(e){return p(n=>a(n,"DELETE FROM warm_pool WHERE node_id = ?").run(e).changes>0)}r(qn,"unregisterWarmSpare");function O(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?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}r(O,"warmSpareRowsFor");function
|
|
54
|
-
FROM node_rows WHERE ${N} 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}))}r(
|
|
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?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}r(O,"warmSpareRowsFor");function $n(){return O(d())}r($n,"listWarmSpares");function zn(e){return a(d(),"SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}r(zn,"isWarmSpare");function B(e){return e.status!=="active"&&e.status!=="idle"?!1:Re(e.pi_pid,e.pi_pid_identity)==="alive"}r(B,"spareIsClaimable");function Bn(e,n,t={}){return p(o=>{const i=O(o,e).find(B);return i===void 0||t.requestKey!==void 0&&o.prepare("UPDATE create_requests SET node_id = ?, state = 'warm_claimed' WHERE request_key = ? AND node_id IS NULL").run(i.node_id,t.requestKey).changes===0||a(o,"DELETE FROM warm_pool WHERE node_id = ?").run(i.node_id).changes===0?null:(a(o,"UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,i.node_id),t.outcomeDelivery!==void 0&&F(o,i.node_id,t.outcomeDelivery),i.node_id)})}r(Bn,"claimWarmSpare");function Jn(e){return O(d(),e).filter(B).length}r(Jn,"warmSpareCount");function Yn(e){return a(d(),"SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e).map(n=>n.node_id)}r(Yn,"childrenOf");function Vn(){return d().prepare(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created
|
|
54
|
+
FROM node_rows WHERE ${N} 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}))}r(Vn,"rosterNodes");function Xn(e){return d().prepare(`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 ${N}
|
|
58
|
-
ORDER BY created DESC`).all(e).map(
|
|
58
|
+
ORDER BY created DESC`).all(e).map(E)}r(Xn,"listResumableRoots");export*from"./tree.js";function Gn(e){const n=R(e)?.waiting_for;if(n==null)return!1;const t=R(n);return t!==null&&(t.status==="active"||t.status==="idle")}r(Gn,"hasLiveMessageWait");function Qn(e,n){a(d(),"UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?").run(n,e)}r(Qn,"setMessageWait");function Kn(e,n,t){return p(o=>{const i=a(o,"SELECT waiting_for_generation FROM nodes WHERE node_id = ? AND waiting_for = ?").get(e,n),s=t();return n!==null&&i!==void 0&&a(o,"UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),s})}r(Kn,"deliverAndSettleMessageWait");function Zn(e,n,t){return p(o=>{const i=a(o,`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
|
|
59
59
|
FROM nodes AS waiter LEFT JOIN nodes AS target ON target.node_id = waiter.waiting_for
|
|
60
|
-
WHERE waiter.node_id = ?`).get(e),s=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||s)return null;const l=t();return a(o,"UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),l})}r(
|
|
61
|
-
AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const i of e)if(!(t.get(i)!==void 0||o.get(i)!==void 0))try{
|
|
60
|
+
WHERE waiter.node_id = ?`).get(e),s=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||s)return null;const l=t();return a(o,"UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),l})}r(Zn,"settleDeadMessageWait");function et(e,n,t){return p(o=>{const i=a(o,"SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return i===void 0?{kind:"missing"}:n(i)?{kind:"terminal",status:i.status,final_report:i.final_report}:{kind:"ran",result:t()}})}r(et,"withFreshTerminalGuard");function y(e){return pe(e)}r(y,"hasUnreconciledManagedWorktree");function J(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||y(e.node_id)||e.node_id===k()||H(e)?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}r(J,"isCollectible");function T(e){if(e.length===0)return[];const n=e.map(()=>"?").join(",");return d().prepare(`SELECT DISTINCT session_id FROM sessions WHERE node_id IN (${n}) AND session_id IS NOT NULL`).all(...e).map(({session_id:o})=>o)}r(T,"nodeConversationIds");function h(e){const n=d(),t=a(n,"SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),o=a(n,`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
|
|
61
|
+
AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const i of e)if(!(t.get(i)!==void 0||o.get(i)!==void 0))try{se().delete(i)}catch(s){if(!(s instanceof ae))throw s}}r(h,"deleteNodeConversations");function L(e,n){const t=U(e,n);return t===null||t.deleted_at!==null?!1:(ve(e,t),!0)}r(L,"deleteNodeObject");function D(e){return{nodeId:e,app:R(e)===null?null:ge(e)}}r(D,"nodeFiles");function Y({nodeId:e,app:n}){n!==null&&W(I(n).nodes,Te(e,n)),W(oe(C(e)),C(e))}r(Y,"removeNodeAppTrees");function V({nodeId:e}){return[Se(e)]}r(V,"nodeOwnedDirs");function X({nodeId:e,app:n}){if(n!==null)try{ee(x(I(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}r(X,"removeNodeConversationDir");function v(e){Y(e);for(const n of V(e))ne(n,{recursive:!0,force:!0});X(e)}r(v,"removeNodeFiles");function nt(e){if(y(e))return{deleted:!1};const n=D(e),t=T([e]),o=p(i=>(L(i,e),{deleted:!0}));return h(t),v(n),o}r(nt,"deleteNode");function tt(e){const n=[...new Set(e)];if(n.length===0)return[];const t=n.filter(y);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const o=n.map(D),i=T(n),s=n.map(()=>"?").join(","),c=d().prepare(`SELECT node_id FROM nodes WHERE node_id IN (${s}) ORDER BY created`).all(...n).map(({node_id:u})=>u).filter(u=>p(f=>L(f,u)));h(i);for(const u of c){const f=o[n.indexOf(u)];A(f,()=>v(f))}return c}r(tt,"deleteNodes");function ot(e){const n=e.dryRun??!1,t=e.includeStale??!1,o=Date.now()-e.ttlDays*864e5,i=new Date(o).toISOString(),s=k()??"",l=d(),c=r(_=>K(_)<o,"quiet"),u=r(_=>({node_id:_.node_id,status:_.status,created:_.created}),"toPruned"),f=a(l,`SELECT * FROM node_rows
|
|
62
62
|
WHERE status IN ('dead', 'done', 'canceled') AND created < ?
|
|
63
|
-
ORDER BY created`).all(i).map(
|
|
63
|
+
ORDER BY created`).all(i).map(E).filter(_=>J(_,{pastTtl:!0})&&c(_)&&!e.held(_.node_id)).map(u),S=t?a(l,`SELECT * FROM node_rows
|
|
64
64
|
WHERE status IN ('active', 'idle') AND created < ?
|
|
65
|
-
ORDER BY created`).all(i).map(
|
|
65
|
+
ORDER BY created`).all(i).map(E).filter(_=>_.node_id!==s&&!Ne(_.pi_pid??null)&&(_.frozen_at??null)===null&&(_.respawn_not_before??null)===null&&_.intent!=="idle-release"&&!H(_)&&!de(_.node_id)&&!y(_.node_id)&&c(_)&&!e.held(_.node_id)).map(u):[],w=G([...f,...S]);return n||w.length===0?{pruned:w,dryRun:n}:(Q(w,e.removeDirs),{pruned:w,dryRun:n})}r(ot,"pruneNodes");function G(e){const n=d(),t=a(n,"SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),o=new Set(e.map(i=>i.node_id));return e.filter(i=>t.all(i.node_id,i.node_id).every(s=>o.has(s.node_id)))}r(G,"retainRunRootsWithMembers");function Q(e,n){if(e.length===0)return;const t=e.map(i=>D(i.node_id)),o=T(e.map(i=>i.node_id));for(const i of e)p(s=>L(s,i.node_id));if(h(o),n!==void 0){for(const i of t)A(i,()=>{Y(i),X(i)});n(t.flatMap(V));return}for(const i of t)A(i,()=>v(i))}r(Q,"deletePrunedNodes");function A(e,n){try{n()}catch(t){ie({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}r(A,"eachNodeBestEffort");function K(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 o=Date.parse(t);Number.isFinite(o)&&o>n&&(n=o)}try{const t=te(x(ye(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}r(K,"lastActivityMs");function rt(e){const n=e.dryRun??!1,t=We(),o=t.filter(u=>J(u)&&!e.held(u.node_id)),i=t.length-o.length,s=Math.max(0,e.maxNodes-i),l=o.map(u=>({row:u,recency:K(u)})).sort((u,f)=>f.recency-u.recency).slice(s).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created})),c=G(l);return n||c.length===0?{pruned:c,dryRun:n}:(Q(c),{pruned:c,dryRun:n})}r(rt,"pruneToLimit");export{pn as abandonCreateRequest,rn as assertRunNotDeleting,Fn as browseNodes,fn as canonicalSessionFile,Yn as childrenOf,Bn as claimWarmSpare,Dn as clearFinalReportIfMatches,Wn as clearFrozen,cn as completeCreateRequest,sn as createNode,nt as deleteNode,tt as deleteNodes,Kn as deliverAndSettleMessageWait,Rn as dueNodeDeadlines,an as findCreateRequest,En as findNodeBySessionFile,Ln as getFinalReport,R as getNode,mn as getRow,Nn as getRowByPane,Cn as graphNodes,Gn as hasLiveMessageWait,J as isCollectible,zn as isWarmSpare,K as lastActivityMs,Mn as listNodeIdentities,We as listNodes,Hn as listNodesByProfile,Un as listNodesForSupervision,Xn as listResumableRoots,In as listTerminalPlacementResidue,$n as listWarmSpares,D as nodeFiles,He as nodesForSupervisionSql,ln as pruneExpiredCreateRequests,ot as pruneNodes,rt as pruneToLimit,un as recordCreateRequestNode,An as recordLaunch,jn as recordRespawnAttempt,kn as recordSettledTurn,Pn as registerWarmSpare,v as removeNodeFiles,dn as reserveCreateRequest,_n as reserveCreateRequestNode,Sn as rewriteLocalNodeIdentity,Vn as rosterNodes,xn as setFrozen,Tn as setIntent,Qn as setMessageWait,wn as setNodeDeadline,vn as setPresence,On as setStatus,Zn as settleDeadMessageWait,yn as shiftProfileNodeDeadlines,je as terminalPlacementResidueSql,hn as transitionStatusIntent,qn as unregisterWarmSpare,gn as updateNode,bn as updateNodeTelemetry,Jn as warmSpareCount,et as withFreshTerminalGuard};
|
|
@@ -1027,4 +1027,8 @@ CREATE INDEX idx_structured_requests_effects ON structured_requests(effects_done
|
|
|
1027
1027
|
key TEXT PRIMARY KEY,
|
|
1028
1028
|
ingested_at INTEGER NOT NULL
|
|
1029
1029
|
);
|
|
1030
|
+
`),e=>e.exec(`
|
|
1031
|
+
UPDATE nodes SET run_id = NULL
|
|
1032
|
+
WHERE run_id IS NOT NULL AND run_id != node_id AND isolated = 0
|
|
1033
|
+
AND NOT EXISTS (SELECT 1 FROM nodes r WHERE r.node_id = nodes.run_id);
|
|
1030
1034
|
`)];function B(e,t,n){const E=e.prepare("PRAGMA foreign_keys").get().foreign_keys;e.exec("PRAGMA foreign_keys = OFF;");try{e.exec("BEGIN IMMEDIATE");try{W(e)===t&&(n(),e.exec(`PRAGMA user_version = ${t+1}`)),e.exec("COMMIT")}catch(T){try{e.exec("ROLLBACK")}catch{}throw T}}finally{e.exec(`PRAGMA foreign_keys = ${E};`)}}o(B,"selfTransactionalMigration");const bt=new Set([3,61,63,66]);function W(e){return e.prepare("PRAGMA user_version").get().user_version}o(W,"currentUserVersion");function se(e,t){F[t](e),e.exec(`PRAGMA user_version = ${t+1}`)}o(se,"applyMigration");function En(e){const t=W(e);if(t>F.length)throw new Error(`unsupported canvas schema version ${t} (latest supported ${F.length})`);if(t===F.length)return;const n=e.prepare("PRAGMA busy_timeout").get().timeout;e.exec("PRAGMA busy_timeout = 60000;");try{Bt(e)}finally{e.exec(`PRAGMA busy_timeout = ${n};`)}}o(En,"migrate");function Bt(e){for(;;){const t=W(e);if(t>=F.length)return;if(bt.has(t)){if(e.isTransaction)throw new Error(`canvas migration v${t+1} requires autocommit`);F[t](e);continue}if(e.isTransaction){se(e,t);continue}e.exec("BEGIN IMMEDIATE");try{W(e)===t&&se(e,t),e.exec("COMMIT")}catch(n){try{e.exec("ROLLBACK")}catch{}throw n}}}o(Bt,"runPendingMigrations");export{F as MIGRATIONS,En as migrate};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var R=Object.defineProperty;var E=(e,t)=>R(e,"name",{value:t,configurable:!0});import{prepared as n}from"../sqlite-statements.js";import{hasUnreconciledWorktree as f}from"../canvas/worktrees.js";import{deleteDocument as p}from"./documents.js";import{publish as
|
|
2
|
-
WHERE i.scheme = 'profile' AND i.external_id = ? AND o.type = 'profile' AND o.deleted_at IS NULL`).get(t);if(!o)return!1;const i=`graph_delete_${++a}`;e.exec(`SAVEPOINT ${i}`);try{u(e,o),n(e,"UPDATE objects SET deleted_at = ?, name = ? WHERE rowid = ?").run(new Date().toISOString(),`${o.name}.deleted-${o.rowid}`,o.rowid),
|
|
1
|
+
var R=Object.defineProperty;var E=(e,t)=>R(e,"name",{value:t,configurable:!0});import{prepared as n}from"../sqlite-statements.js";import{hasUnreconciledWorktree as f}from"../canvas/worktrees.js";import{deleteDocument as p}from"./documents.js";import{publish as s}from"./events.js";import{getByRowid as w}from"./objects.js";import{rememberDeletedIsolated as S}from"../runs/confinement.js";let a=0;function I(e,t){if(t.type!=="node")throw new Error(`deleteNodeWithOwned: ${t.id} is a ${t.type}, not a node`);if(f(t.id))throw new Error(`refusing to delete node ${t.id}: its managed worktree is not reconciled`);const o=`graph_delete_${++a}`;e.exec(`SAVEPOINT ${o}`);try{h(e,t),e.exec(`RELEASE ${o}`)}catch(i){throw e.exec(`ROLLBACK TO ${o}`),e.exec(`RELEASE ${o}`),i}}E(I,"deleteNodeWithOwned");function j(e,t){const o=n(e,`SELECT o.* FROM identities i JOIN objects o ON o.rowid = i.object
|
|
2
|
+
WHERE i.scheme = 'profile' AND i.external_id = ? AND o.type = 'profile' AND o.deleted_at IS NULL`).get(t);if(!o)return!1;const i=`graph_delete_${++a}`;e.exec(`SAVEPOINT ${i}`);try{u(e,o),n(e,"UPDATE objects SET deleted_at = ?, name = ? WHERE rowid = ?").run(new Date().toISOString(),`${o.name}.deleted-${o.rowid}`,o.rowid),s(e,{event:"deleted",object:w(e,o.rowid),actor:null,attrs:{}}),n(e,"DELETE FROM watches WHERE object = ? OR watcher = ?").run(o.rowid,o.rowid),e.exec(`RELEASE ${i}`)}catch(d){throw e.exec(`ROLLBACK TO ${i}`),e.exec(`RELEASE ${i}`),d}return!0}E(j,"deleteProfileWithOwned");function h(e,t){const o=u(e,t);n(e,"UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(o,t.rowid),s(e,{event:"deleted",object:w(e,t.rowid),actor:null,attrs:{}}),n(e,"DELETE FROM watches WHERE object = ? OR watcher = ?").run(t.rowid,t.rowid),S(t.id,e),n(e,"UPDATE nodes SET run_id = NULL WHERE run_id = ? AND node_id != ? AND isolated = 0").run(t.id,t.id),n(e,"DELETE FROM nodes WHERE node_id = ?").run(t.id)}E(h,"deleteInside");function u(e,t){const o=n(e,`WITH RECURSIVE sub(rowid) AS (
|
|
3
3
|
SELECT rowid FROM objects WHERE owner = ?
|
|
4
4
|
UNION SELECT o.rowid FROM objects o JOIN sub ON o.owner = sub.rowid)
|
|
5
|
-
SELECT o.* FROM objects o JOIN sub ON sub.rowid = o.rowid WHERE o.deleted_at IS NULL`).all(t.rowid),i=new Set(o.map(r=>r.rowid)),
|
|
6
|
-
WHERE e.type = 'links-to' AND e.dst = ? AND s.deleted_at IS NULL`);for(let r=!0;r;){r=!1;for(const c of o)c.type!=="document"||!i.has(c.rowid)||
|
|
5
|
+
SELECT o.* FROM objects o JOIN sub ON sub.rowid = o.rowid WHERE o.deleted_at IS NULL`).all(t.rowid),i=new Set(o.map(r=>r.rowid)),d=n(e,`SELECT e.src FROM edges e JOIN objects s ON s.rowid = e.src
|
|
6
|
+
WHERE e.type = 'links-to' AND e.dst = ? AND s.deleted_at IS NULL`);for(let r=!0;r;){r=!1;for(const c of o)c.type!=="document"||!i.has(c.rowid)||d.all(c.rowid).some(({src:O})=>!i.has(O))&&(i.delete(c.rowid),r=!0)}const l=new Date().toISOString();for(const r of o)if(i.has(r.rowid)){if(r.type==="document"){p(e,null,r);continue}n(e,"UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(l,r.rowid),s(e,{event:"deleted",object:w(e,r.rowid),actor:null,attrs:{}}),n(e,"DELETE FROM watches WHERE object = ? OR watcher = ?").run(r.rowid,r.rowid)}return l}E(u,"deleteOwned");export{I as deleteNodeWithOwned,j as deleteProfileWithOwned};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var D=Object.defineProperty;var r=(n,t)=>D(n,"name",{value:t,configurable:!0});import{prepared as d}from"../../core/sqlite-statements.js";import{randomUUID as O}from"node:crypto";import{openDb as l}from"../../core/canvas/db.js";import{getNode as p}from"../../core/canvas/canvas.js";import{BrokerClient as T,SocketTransport as I}from"../../core/broker-client/client.js";import{emitRunEvent as c,emitRunSettlement as m}from"../../core/runs/events.js";import{cancelOpenQuestions as R}from"../../core/runs/questions.js";import{emitEvent as _}from"../../core/events/emit.js";import{toRunOutcomeDTO as v}from"../api/map.js";import{readOutputResult as N}from"../../core/runtime/structured-output.js";const A=JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),h=new Map,y=250;class b{static{r(this,"RunObserver")}nodeId;runId;client;timer;status;outcomeRevision;openAssistant=!1;assistantStartSequence=0;block=null;thinking="";output="";pendingThinking="";pendingOutput="";flushTimer;closed=!1;constructor(t,e){this.nodeId=t,this.runId=e;const i=l(),s=d(i,"SELECT body_json FROM run_events WHERE node_id = ? AND type = ? ORDER BY sequence_number DESC LIMIT 1").get(t,t===e?"node.settled":"child.settled");s&&(this.outcomeRevision=JSON.parse(s.body_json).outcome.revision);const o=d(i,"SELECT body_json FROM run_events WHERE node_id = ? AND type = 'node.status.changed' ORDER BY sequence_number DESC LIMIT 1").get(t);o&&(this.status=JSON.parse(o.body_json).status),this.timer=setInterval(()=>this.pollOrClose(),250),this.timer.unref(),h.set(t,this),this.poll()}pollOrClose(){try{this.poll()}catch(t){this.close(),_({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:t})}}poll(){const t=p(this.nodeId);if(!t||t.run_id!==this.runId||!g(this.runId)){this.close();return}const e=t.pi_pid===null?"dormant":t.status;this.status!==e&&c(this.runId,this.nodeId,"node.status.changed",{status:e,reason:t.intent??null}),this.status=e;const i=v(t);if(i&&i.revision!==this.outcomeRevision&&Date.now()-Date.parse(i.settled_at)<720*60*6e4){if(this.nodeId===this.runId){const s=d(l(),"SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(this.runId,this.runId);for(const o of s)E(o.node_id,this.runId),h.get(o.node_id)?.poll()}if(this.outcomeRevision=i.revision,this.nodeId===this.runId){const s=i.kind==="result"?N(this.nodeId,t.grantee):void 0;m(this.runId,this.nodeId,"node.settled",{outcome:i,usage:JSON.parse(t.usage_json??A),...s===void 0?{}:{result:s}})}else m(this.runId,this.nodeId,"child.settled",{child_node_id:this.nodeId,outcome:i});if(t.grantee&&t.grantee!=="app:terminal"){const s=this.nodeId===this.runId?{run_id:this.runId}:{node_id:this.nodeId};R(s,this.nodeId===this.runId?"the run settled":"the asking node was closed").catch(o=>_({level:"error",event:"daemon.runs.question_cancel_failed",node_id:this.nodeId,error:o}))}}t.pi_pid===null?this.close():this.connect()}get assistantMessageStartSequence(){return this.openAssistant&&this.client&&p(this.nodeId)?.pi_pid!=null?this.assistantStartSequence:null}get openBlock(){return this.assistantMessageStartSequence===null?null:this.block}connect(){if(this.client||this.closed)return;const t=new T(this.nodeId,{transport:new I(this.nodeId,{recordsViewerFaults:!1})});this.client=t,t.on("connect",()=>t.send({type:"hello",role:"observer",client_id:O(),attends:!1})),t.on("frame",e=>{if(e.type==="message_start"&&e.message.role==="assistant"&&(this.discardDeltas(),this.openAssistant=!0,this.block=null,this.thinking="",this.output="",this.assistantStartSequence=d(l(),"SELECT event_cursor FROM nodes WHERE node_id = ?").get(this.runId).event_cursor),e.type==="message_update"&&e.message.role==="assistant"&&this.openAssistant){const i=e.message.content;if(!Array.isArray(i))return;const s=i.at(-1);s&&typeof s=="object"&&"type"in s&&(s.type==="toolCall"?this.block={kind:"tool_call",name:"name"in s&&typeof s.name=="string"?s.name:""}:(s.type==="text"||s.type==="thinking")&&(this.block={kind:s.type}));const o=i.filter(u=>u?.type==="thinking").map(u=>u.thinking).join(""),a=i.filter(u=>u?.type==="text").map(u=>u.text).join(""),S=o.startsWith(this.thinking)?o.slice(this.thinking.length):o,k=a.startsWith(this.output)?a.slice(this.output.length):a;this.thinking=o,this.output=a,this.pendingThinking+=S,this.pendingOutput+=k,(this.pendingThinking||this.pendingOutput)&&!this.flushTimer&&(this.flushTimer=setTimeout(()=>this.flushDeltas(),y),this.flushTimer.unref())}e.type==="message_end"&&e.message.role==="assistant"&&(this.flushDeltas(),this.openAssistant=!1,this.block=null)}),t.on("error",()=>{}),t.on("close",()=>{this.client===t&&(this.client=void 0,this.discardDeltas(),this.openAssistant=!1,this.block=null)}),t.connect()}flushDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0;const t=this.pendingThinking,e=this.pendingOutput;if(this.pendingThinking="",this.pendingOutput="",!this.openAssistant||!t&&!e)return;if(d(l(),"SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND sequence_number >= ? AND type IN ('node.output_text.done', 'node.thinking.done', 'usage') LIMIT 1").get(this.runId,this.nodeId,this.assistantStartSequence)){this.openAssistant=!1;return}t&&c(this.runId,this.nodeId,"node.thinking.delta",{delta:t}),e&&c(this.runId,this.nodeId,"node.output_text.delta",{delta:e})}discardDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0,this.pendingThinking="",this.pendingOutput=""}close(){this.closed=!0,this.discardDeltas(),clearInterval(this.timer),h.delete(this.nodeId);const t=this.client;this.client=void 0,t?.close()}}function J(n){return h.get(n)?.assistantMessageStartSequence??null}r(J,"openAssistantMessageStartSequence");function Y(n){return h.get(n)?.openBlock??null}r(Y,"openAssistantBlock");function g(n){return d(l(),"SELECT 1 FROM nodes WHERE node_id = ? AND run_id = ? AND event_cursor IS NOT NULL").get(n,n)!==void 0}r(g,"runRootExists");function E(n,t){if(!h.has(n)&&g(t)){if(n!==t){const e=p(n);!d(l(),"SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'child.started' LIMIT 1").get(t,n)&&e&&Date.now()-Date.parse(e.created)<720*60*6e4&&c(t,n,"child.started",{child_node_id:n,kind:e.kind})}new b(n,t)}}r(E,"ensureRunObserver");function G(){const n=new Date(Date.now()-2592e6).toISOString(),t=d(l(),`SELECT n.node_id, n.run_id FROM node_rows n WHERE n.run_id IS NOT NULL AND (n.pi_pid IS NOT NULL OR (n.outcome_at IS NOT NULL AND n.outcome_at > ?
|
|
2
2
|
AND n.outcome_reason != 'parked' AND NOT EXISTS (
|
|
3
3
|
SELECT 1 FROM run_events e WHERE e.run_id = n.run_id AND e.node_id = n.node_id AND e.type = CASE WHEN n.node_id = n.run_id THEN 'node.settled' ELSE 'child.settled' END
|
|
4
|
-
AND json_extract(e.body_json, '$.outcome.revision') = COALESCE(n.outcome_revision, 1))))`).all(
|
|
4
|
+
AND json_extract(e.body_json, '$.outcome.revision') = COALESCE(n.outcome_revision, 1))))`).all(n);for(const e of t)try{E(e.node_id,e.run_id),f.delete(e.node_id)}catch(i){L(e.node_id,i)}}r(G,"pollRunObservers");const f=new Map;function L(n,t){const e=t instanceof Error?t.message:String(t);f.get(n)!==e&&(f.set(n,e),_({level:"error",event:"daemon.runs.observer_failed",node_id:n,error:t}))}r(L,"reportObserverFailure");export{E as ensureRunObserver,Y as openAssistantBlock,J as openAssistantMessageStartSequence,G as pollRunObservers};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.461",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
},
|
|
138
138
|
"license": "UNLICENSED",
|
|
139
139
|
"dependencies": {
|
|
140
|
-
"@north-light/identity": "0.3.
|
|
140
|
+
"@north-light/identity": "0.3.461",
|
|
141
141
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
142
142
|
"@earendil-works/pi-ai": "1.1.0",
|
|
143
143
|
"@earendil-works/pi-coding-agent": "1.1.0",
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.461",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/cli",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.461",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"workspaces": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@earendil-works/pi-ai": "1.1.0",
|
|
19
19
|
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
20
20
|
"@earendil-works/pi-tui": "1.1.0",
|
|
21
|
-
"@north-light/identity": "0.3.
|
|
21
|
+
"@north-light/identity": "0.3.461",
|
|
22
22
|
"cron-parser": "^5.6.0",
|
|
23
23
|
"esbuild": "^0.27.7",
|
|
24
24
|
"jose": "^6.2.12",
|
|
@@ -12095,17 +12095,17 @@
|
|
|
12095
12095
|
},
|
|
12096
12096
|
"packages/crouter-api": {
|
|
12097
12097
|
"name": "@north-light/api",
|
|
12098
|
-
"version": "0.3.
|
|
12098
|
+
"version": "0.3.461",
|
|
12099
12099
|
"license": "UNLICENSED"
|
|
12100
12100
|
},
|
|
12101
12101
|
"packages/crouter-env-docker": {
|
|
12102
12102
|
"name": "@north-light/env-docker",
|
|
12103
|
-
"version": "0.3.
|
|
12103
|
+
"version": "0.3.461",
|
|
12104
12104
|
"license": "UNLICENSED"
|
|
12105
12105
|
},
|
|
12106
12106
|
"packages/crouter-identity": {
|
|
12107
12107
|
"name": "@north-light/identity",
|
|
12108
|
-
"version": "0.3.
|
|
12108
|
+
"version": "0.3.461",
|
|
12109
12109
|
"license": "UNLICENSED",
|
|
12110
12110
|
"dependencies": {
|
|
12111
12111
|
"jose": "^6.2.1"
|
|
@@ -12113,20 +12113,20 @@
|
|
|
12113
12113
|
},
|
|
12114
12114
|
"packages/crouter-plugin": {
|
|
12115
12115
|
"name": "@north-light/plugin",
|
|
12116
|
-
"version": "0.3.
|
|
12116
|
+
"version": "0.3.461",
|
|
12117
12117
|
"license": "UNLICENSED",
|
|
12118
12118
|
"dependencies": {
|
|
12119
|
-
"@north-light/api": "0.3.
|
|
12120
|
-
"@north-light/identity": "0.3.
|
|
12119
|
+
"@north-light/api": "0.3.461",
|
|
12120
|
+
"@north-light/identity": "0.3.461"
|
|
12121
12121
|
}
|
|
12122
12122
|
},
|
|
12123
12123
|
"packages/crouter-sdk": {
|
|
12124
12124
|
"name": "@north-light/sdk",
|
|
12125
|
-
"version": "0.3.
|
|
12125
|
+
"version": "0.3.461",
|
|
12126
12126
|
"license": "UNLICENSED",
|
|
12127
12127
|
"dependencies": {
|
|
12128
|
-
"@north-light/api": "0.3.
|
|
12129
|
-
"@north-light/identity": "0.3.
|
|
12128
|
+
"@north-light/api": "0.3.461",
|
|
12129
|
+
"@north-light/identity": "0.3.461",
|
|
12130
12130
|
"jose": "^6.2.1"
|
|
12131
12131
|
},
|
|
12132
12132
|
"bin": {
|