@north-light/cli 0.3.460 → 0.3.462

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,5 +1,5 @@
1
1
  /** The contract level this build serves and requires. Written by `scripts/contract.mjs release`; never edit by hand. */
2
- export declare const CONTRACT_LEVEL = "1.5";
2
+ export declare const CONTRACT_LEVEL = "1.6";
3
3
  /** Request header naming the one contract level the caller needs, e.g. `1.3`. Optional: absent means no check. */
4
4
  export declare const REQUIRED_CONTRACT_HEADER = "Crouter-Required-Contract";
5
5
  /** Response header listing the contract levels the server serves, comma-separated, one per major, e.g. `1.3`. */
@@ -1 +1 @@
1
- var c=Object.defineProperty;var e=(r,t)=>c(r,"name",{value:t,configurable:!0});const f="1.5",i="Crouter-Required-Contract",p="Crouter-Contract";function l(r){const t=/^(\d+)\.(\d+)$/.exec(r.trim());return t===null?null:{major:Number(t[1]),minor:Number(t[2])}}e(l,"parseContractLevel");function a(r){return r==null?[]:r.split(",").map(t=>l(t)).filter(t=>t!==null)}e(a,"parseServedContracts");function s(r,t){const n=l(r);return n===null?!1:(typeof t=="string"||t===null||t===void 0?a(t):t).some(u=>u.major===n.major&&u.minor>=n.minor)}e(s,"contractSatisfies");function C(r,t,n={}){if(r===void 0)return null;if(l(r)===null)return{status:400,code:"invalid_request",param:i,message:`${i} must be a contract level like 1.0.`};if(s(r,t))return null;const o=r.trim();return{status:426,code:"runtime_version_unsupported",message:t===null||a(t).length===0?`The runtime did not name its contract level; the caller requires contract ${o} or later. Roll the runtime forward.`:`The runtime serves contract ${t}; the caller requires contract ${o} or later within the same major. Roll the runtime forward, or pin an SDK whose crouterContract the runtime serves.`,details:{sdk_version:(n.legacyMinimum??"").trim(),runtime_version:n.runtimeVersion??null,required_contract:o,runtime_contract:t}}}e(C,"contractRefusal");export{p as CONTRACT_HEADER,f as CONTRACT_LEVEL,i as REQUIRED_CONTRACT_HEADER,C as contractRefusal,s as contractSatisfies,l as parseContractLevel,a as parseServedContracts};
1
+ var c=Object.defineProperty;var e=(r,t)=>c(r,"name",{value:t,configurable:!0});const f="1.6",i="Crouter-Required-Contract",p="Crouter-Contract";function l(r){const t=/^(\d+)\.(\d+)$/.exec(r.trim());return t===null?null:{major:Number(t[1]),minor:Number(t[2])}}e(l,"parseContractLevel");function a(r){return r==null?[]:r.split(",").map(t=>l(t)).filter(t=>t!==null)}e(a,"parseServedContracts");function s(r,t){const n=l(r);return n===null?!1:(typeof t=="string"||t===null||t===void 0?a(t):t).some(u=>u.major===n.major&&u.minor>=n.minor)}e(s,"contractSatisfies");function C(r,t,n={}){if(r===void 0)return null;if(l(r)===null)return{status:400,code:"invalid_request",param:i,message:`${i} must be a contract level like 1.0.`};if(s(r,t))return null;const o=r.trim();return{status:426,code:"runtime_version_unsupported",message:t===null||a(t).length===0?`The runtime did not name its contract level; the caller requires contract ${o} or later. Roll the runtime forward.`:`The runtime serves contract ${t}; the caller requires contract ${o} or later within the same major. Roll the runtime forward, or pin an SDK whose crouterContract the runtime serves.`,details:{sdk_version:(n.legacyMinimum??"").trim(),runtime_version:n.runtimeVersion??null,required_contract:o,runtime_contract:t}}}e(C,"contractRefusal");export{p as CONTRACT_HEADER,f as CONTRACT_LEVEL,i as REQUIRED_CONTRACT_HEADER,C as contractRefusal,s as contractSatisfies,l as parseContractLevel,a as parseServedContracts};
@@ -114,6 +114,4 @@ export interface ProfileDTO {
114
114
  last_used_at: string | null;
115
115
  /** Absolute path of the profile's directory, `<app space>/profiles/<id>`: its settings root. The profile's documents live in the canvas, not here. */
116
116
  profile_path: string;
117
- /** @deprecated The same path as `profile_path`; kept for clients written before it existed. Removed in the next breaking release. */
118
- memory_path: string;
119
117
  }
@@ -9,6 +9,12 @@ when-and-why-to-read: When you need Release notes, this knowledge should be read
9
9
 
10
10
  Changes to `@north-light/sdk` that can change what an existing app sees. Newest first.
11
11
 
12
+ ## 0.3.462
13
+
14
+ ### `ProfileDTO.memory_path` is removed (profile objects carry only `profile_path`)
15
+
16
+ `memory_path`, the deprecated alias of `profile_path` that 0.3.459 kept, is no longer sent. Read `profile_path`, which holds the same value (`<app space>/profiles/<id>`). A runtime older than 0.3.459 sends only `memory_path`.
17
+
12
18
  ## 0.3.460
13
19
 
14
20
  ### `crouter-sdk keygen` releases its key file when the add fails (no app change)
@@ -1 +1 @@
1
- var l=Object.defineProperty;var i=(e,t)=>l(e,"name",{value:t,configurable:!0});import{defineLeaf as p}from"../../core/command.js";import{usage as n}from"../../core/errors.js";import{resolve as f}from"node:path";import{cliClient as s}from"../api-client.js";import{resolveMetaPairs as c}from"./meta.js";const k=p({name:"new",description:"create a new profile",whenToUse:"you are establishing a new agent identity \u2014 a stable id, a display name, and its own documents (a profile owns documents like any other owner). Pass at most one initial project directory here (the parser has no repeatable-flag support); use `profile project add` afterward for every additional one. Use `--root` (no name) to provision the canonical stable root profile \u2014 the default identity a home falls back to \u2014 idempotently, without spawning a node.",help:{name:"profile new",summary:"create a profile of the caller's app in the scoped store, with its own app directory",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Display name for the profile. Also slugified into the stable profile id \u2014 the id never changes on later rename. Required unless `--root` is given; mutually exclusive with `--root`."},{kind:"flag",name:"root",type:"bool",required:!1,constraint:"Provision the canonical stable root profile (fixed id `root-00000000`, name `root`) \u2014 the fallback default identity for a home \u2014 instead of a fresh named one. Idempotent: re-running returns the existing root. Node-free (no `node new --root` needed). Mutually exclusive with `--name`/`--project`/`--default-kind`/`--meta`."},{kind:"flag",name:"project",type:"path",required:!1,constraint:"One initial project directory. Must already exist and be a directory; resolved to its absolute real path before storing. Creates a purview relationship. Singular \u2014 add more with `crtr profile project add` after creation."},{kind:"flag",name:"default-kind",type:"string",required:!1,constraint:"Installed persona kind for node creates under this profile that omit --kind. Defaults to general when omitted; the daemon validates it against its installed kind registry."},{kind:"flag",name:"meta",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE metadata entry (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`. Each entry reaches every broker launched under the profile as `CRTR_PROFILE_META_<KEY>` env; readable back via `profile show` \u2014 not for secrets (those go to `profile env`)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id (`<slug>-<shortid>`). Pass this, or the name, to every other `profile` verb and to `--profile` elsewhere."},{name:"profile_path",type:"string",required:!0,constraint:"Absolute path to the profile directory, `<app space>/profiles/<id>`: its settings root. Documents the profile owns are canvas documents, read with `crtr canvas read`, not files here."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` project relationships in manifest order. `path` defines purview. Empty when --project was omitted."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"default_kind",type:"string",required:!0,constraint:"Default persona kind for node creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map; empty when --meta was omitted."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."}],outputKind:"object",effects:["Creates a profile row owned by the caller's app (the terminal app for a person) and its directory under that app's space. A name the caller's app already holds is refused."]},run:i(async e=>{const t=e.name,r=e.project,a=e.defaultKind,o=c(e.meta,"meta");if(e.root===!0){if(t!==void 0||r!==void 0||a!==void 0||Object.keys(o).length>0)throw n("`--root` provisions the canonical stable root profile and takes no `--name`/`--project`/`--default-kind`/`--meta`.");return d(await s().ensureProfile("root"))}if(t===void 0)throw n("provide `--name <name>` to create a profile, or `--root` to provision the stable root profile.");return d(await s().createProfile({name:t,...r!==void 0?{projects:[{path:f(r)}]}:{},...a!==void 0?{default_kind:a}:{},...Object.keys(o).length>0?{metadata:o}:{}}))},"run")});function d(e){return{profile_id:e.id,profile_path:e.profile_path??e.memory_path,projects:e.projects,app:e.app,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at}}i(d,"newProfileOutput");export{k as newLeaf};
1
+ var l=Object.defineProperty;var i=(e,t)=>l(e,"name",{value:t,configurable:!0});import{defineLeaf as p}from"../../core/command.js";import{usage as n}from"../../core/errors.js";import{resolve as f}from"node:path";import{cliClient as s}from"../api-client.js";import{resolveMetaPairs as c}from"./meta.js";const k=p({name:"new",description:"create a new profile",whenToUse:"you are establishing a new agent identity \u2014 a stable id, a display name, and its own documents (a profile owns documents like any other owner). Pass at most one initial project directory here (the parser has no repeatable-flag support); use `profile project add` afterward for every additional one. Use `--root` (no name) to provision the canonical stable root profile \u2014 the default identity a home falls back to \u2014 idempotently, without spawning a node.",help:{name:"profile new",summary:"create a profile of the caller's app in the scoped store, with its own app directory",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Display name for the profile. Also slugified into the stable profile id \u2014 the id never changes on later rename. Required unless `--root` is given; mutually exclusive with `--root`."},{kind:"flag",name:"root",type:"bool",required:!1,constraint:"Provision the canonical stable root profile (fixed id `root-00000000`, name `root`) \u2014 the fallback default identity for a home \u2014 instead of a fresh named one. Idempotent: re-running returns the existing root. Node-free (no `node new --root` needed). Mutually exclusive with `--name`/`--project`/`--default-kind`/`--meta`."},{kind:"flag",name:"project",type:"path",required:!1,constraint:"One initial project directory. Must already exist and be a directory; resolved to its absolute real path before storing. Creates a purview relationship. Singular \u2014 add more with `crtr profile project add` after creation."},{kind:"flag",name:"default-kind",type:"string",required:!1,constraint:"Installed persona kind for node creates under this profile that omit --kind. Defaults to general when omitted; the daemon validates it against its installed kind registry."},{kind:"flag",name:"meta",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE metadata entry (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`. Each entry reaches every broker launched under the profile as `CRTR_PROFILE_META_<KEY>` env; readable back via `profile show` \u2014 not for secrets (those go to `profile env`)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id (`<slug>-<shortid>`). Pass this, or the name, to every other `profile` verb and to `--profile` elsewhere."},{name:"profile_path",type:"string",required:!0,constraint:"Absolute path to the profile directory, `<app space>/profiles/<id>`: its settings root. Documents the profile owns are canvas documents, read with `crtr canvas read`, not files here."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` project relationships in manifest order. `path` defines purview. Empty when --project was omitted."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"default_kind",type:"string",required:!0,constraint:"Default persona kind for node creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map; empty when --meta was omitted."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."}],outputKind:"object",effects:["Creates a profile row owned by the caller's app (the terminal app for a person) and its directory under that app's space. A name the caller's app already holds is refused."]},run:i(async e=>{const t=e.name,r=e.project,a=e.defaultKind,o=c(e.meta,"meta");if(e.root===!0){if(t!==void 0||r!==void 0||a!==void 0||Object.keys(o).length>0)throw n("`--root` provisions the canonical stable root profile and takes no `--name`/`--project`/`--default-kind`/`--meta`.");return d(await s().ensureProfile("root"))}if(t===void 0)throw n("provide `--name <name>` to create a profile, or `--root` to provision the stable root profile.");return d(await s().createProfile({name:t,...r!==void 0?{projects:[{path:f(r)}]}:{},...a!==void 0?{default_kind:a}:{},...Object.keys(o).length>0?{metadata:o}:{}}))},"run")});function d(e){return{profile_id:e.id,profile_path:e.profile_path,projects:e.projects,app:e.app,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at}}i(d,"newProfileOutput");export{k as newLeaf};
@@ -1 +1 @@
1
- var a=Object.defineProperty;var i=(r,e)=>a(r,"name",{value:e,configurable:!0});import{defineLeaf as n}from"../../core/command.js";import{resolveProfileViaDaemon as o}from"./daemon-profiles.js";const l=n({name:"show",description:"one profile's manifest in full",whenToUse:"you need a profile's full project list, owning app, id, and timestamps \u2014 after `profile list` narrows to a name, to find where its nodes will run, or to inspect what a node's bearings named as its profile.",help:{name:"profile show",summary:"print one profile's settings and directory path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` relationships in manifest order. `path` defines profile purview."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string",required:!0,constraint:"Default node kind for creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map \u2014 each entry reaches brokers launched under the profile as `CRTR_PROFILE_META_<KEY>` env. Empty when none."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."},{name:"profile_path",type:"string",required:!0,constraint:"Absolute path to the profile directory, `<app space>/profiles/<id>`: its settings root. Documents the profile owns are canvas documents, read with `crtr canvas read`, not files here."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands, including the SQL-backed raw settings surface."}],outputKind:"object",effects:["None. Read-only."]},run:i(async r=>{const e=await o(r.profile),t=e.id;return{profile_id:t,name:e.name,projects:e.projects,app:e.app,paused_at:e.paused_at,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at,last_used_at:e.last_used_at,profile_path:e.profile_path??e.memory_path,follow_up:e.paused_at===null?`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path>\`, pause it with \`crtr profile pause ${t}\`, or set its default kind with \`crtr profile kind ${t} <kind>\`.`:`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path>\`, or resume it with \`crtr profile resume ${t}\`.`}},"run")});export{l as showLeaf};
1
+ var a=Object.defineProperty;var i=(r,e)=>a(r,"name",{value:e,configurable:!0});import{defineLeaf as n}from"../../core/command.js";import{resolveProfileViaDaemon as s}from"./daemon-profiles.js";const l=n({name:"show",description:"one profile's manifest in full",whenToUse:"you need a profile's full project list, owning app, id, and timestamps \u2014 after `profile list` narrows to a name, to find where its nodes will run, or to inspect what a node's bearings named as its profile.",help:{name:"profile show",summary:"print one profile's settings and directory path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` relationships in manifest order. `path` defines profile purview."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string",required:!0,constraint:"Default node kind for creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map \u2014 each entry reaches brokers launched under the profile as `CRTR_PROFILE_META_<KEY>` env. Empty when none."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."},{name:"profile_path",type:"string",required:!0,constraint:"Absolute path to the profile directory, `<app space>/profiles/<id>`: its settings root. Documents the profile owns are canvas documents, read with `crtr canvas read`, not files here."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands, including the SQL-backed raw settings surface."}],outputKind:"object",effects:["None. Read-only."]},run:i(async r=>{const e=await s(r.profile),t=e.id;return{profile_id:t,name:e.name,projects:e.projects,app:e.app,paused_at:e.paused_at,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at,last_used_at:e.last_used_at,profile_path:e.profile_path,follow_up:e.paused_at===null?`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path>\`, pause it with \`crtr profile pause ${t}\`, or set its default kind with \`crtr profile kind ${t} <kind>\`.`:`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path>\`, or resume it with \`crtr profile resume ${t}\`.`}},"run")});export{l as showLeaf};
@@ -1,11 +1,11 @@
1
- var K=Object.defineProperty;var r=(e,n)=>K(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 Z,rmSync as ee,statSync as ne}from"node:fs";import{dirname as te,join as x,resolve as oe}from"node:path";import{removeTreeBeneath as W}from"../spaces/open-beneath.js";import{emitEvent as re}from"../events/emit.js";import{openDb as d,prepared as j,withCanvasWrite as c}from"./db.js";import{conversationStore as ie,ConversationNotFoundError as se}from"../conversation-store/index.js";import{hasUnseenWakeMail as ae}from"./deliveries.js";import{isAppRun as H}from"./app-run.js";import{registerOutcomeAction as F}from"./outcome-actions.js";import{publish as de}from"../graph/events.js";import{nodeObject as le}from"../graph/objects.js";import{findNodeBySessionFileSql as ue}from"./sessions.js";import{hydrateFault as _e}from"./recovery.js";import{hasUnreconciledWorktree as ce,openWorktree as pe,readWorktree as fe,worktreeFromRow as Ee}from"./worktrees.js";import{isPidAlive as me,isPidPresent as b,recordedPidLiveness as Ne}from"./pid.js";import{ensureHome as Re,jobDir as ye,nodeDir as we,nodeRunDir as I}from"./paths.js";import{appForNode as Se,ensureNodeDirs as ge,nodeAgentDir as Oe}from"./node-agent-paths.js";import{appSpace as C}from"../layout.js";import{createObject as Te,getById as U,ownerForGrantee as M,setObjectKind as he,setObjectName as Le}from"../graph/objects.js";import{deleteNodeWithOwned as De}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 on(e,n){if(a(e,"SELECT deleting_at FROM nodes WHERE node_id = ?").get(n)?.deleting_at)throw new Error("run is deleting")}r(on,"assertRunNotDeleting");function ve(e,n){const t=M(n,e.grantee??"app:terminal");Te(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(ve,"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 _e(Object.fromEntries(n))}r(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,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(f,"rowFrom");function q(e,n=fe(e.node_id)){return{...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}}}r(q,"metaFrom");function rn(e,n={}){return Re(),c(t=>{ve(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&pe(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&F(t,e.node_id,n.outcomeDelivery),n.withinCreate?.(t,e)}),ge(e.node_id),R(e.node_id)}r(rn,"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 Ae=1440*60*1e3;function $(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}r($,"createRequestRecord");function sn(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(sn,"findCreateRequest");function an(e){return c(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+Ae),{requestKey:e,nodeId:null,state:"reserved"})})}r(an,"reserveCreateRequest");function dn(e=Date.now()){return c(n=>Number(n.prepare("DELETE FROM create_requests WHERE expires_at <= ?").run(e).changes))}r(dn,"pruneExpiredCreateRequests");function ln(e,n){c(t=>{t.prepare("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)})}r(ln,"recordCreateRequestNode");function un(e,n){c(t=>{t.prepare("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ?").run(n,e)})}r(un,"reserveCreateRequestNode");function _n(e,n){c(t=>{t.prepare("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)})}r(_n,"completeCreateRequest");function cn(e,n){c(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(cn,"abandonCreateRequest");function pn(e){return oe(e)}r(pn,"canonicalSessionFile");function fn(e){const n=ue(e);return n===null?null:R(n)}r(fn,"findNodeBySessionFile");function En(e){const n=a(d(),"SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}r(En,"getRow");function mn(e){const n=a(d(),"SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}r(mn,"getRowByPane");function Nn(e){return a(d(),`SELECT * FROM node_rows
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(f)}r(Nn,"dueNodeDeadlines");function Rn(e,n){return Number(a(d(),"UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e).changes)===1}r(Rn,"setNodeDeadline");function yn(e,n){return!Number.isFinite(n)||n<=0?0:c(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 u=Date.parse(l.deadline_at);Number.isNaN(u)||(s+=Number(i.run(new Date(u+n).toISOString(),l.node_id,l.deadline_at).changes))}return s})}r(yn,"shiftProfileNodeDeadlines");function wn(e,n,t){const o=`SELECT o.rowid FROM objects o JOIN identities i ON i.object = o.owner
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(wn,"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 Sn(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 c(s=>{const l=U(s,e);if(l===null||l.type!=="node")throw new Error(`unknown node: ${e}`);if(i("name")&&Le(s,l,g(n.name,"name")),i("kind")&&he(s,l,g(n.kind,"kind")),t.length===0)return;if(s.prepare(`UPDATE nodes SET ${t.map(([p])=>`${p} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,p])=>p),e).changes!==1)throw new Error(`unknown node: ${e}`)}),R(e)}r(Sn,"updateNode");function gn(e,n){a(d(),"UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}r(gn,"setStatus");function On(e,n){a(d(),"UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}r(On,"setIntent");function Tn(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 u=d().prepare(`UPDATE nodes SET ${i.join(", ")} WHERE ${l.join(" AND ")}`).run(...s);return Number(u.changes)}const o=t.outcome;return c(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 u=r((y,_)=>o.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${_} END`,"outcomeValue");s.push(`outcome_kind = ${u(o.kind,"outcome_kind")}`,`outcome_reason = ${u(o.reason,"outcome_reason")}`,`outcome_detail_json = ${u(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 = ${u(o.at,"outcome_at")}`),l.push(o.kind,o.reason,o.detailJson,o.at);const p=["node_id = ?"];l.push(e),t.fromStatuses!==void 0&&(p.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),l.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&p.push("final_report IS NULL");const E=i.prepare(`UPDATE nodes SET ${s.join(", ")} WHERE ${p.join(" AND ")}`).run(...l);if(Number(E.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&&de(i,{event:"outcome",object:le(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(E.changes)})}r(Tn,"transitionStatusIntent");function hn(e){return a(d(),"SELECT final_report FROM nodes WHERE node_id = ?").get(e)?.final_report??null}r(hn,"getFinalReport");function Ln(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(Ln,"clearFinalReportIfMatches");function Dn(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(Dn,"setPresence");function vn(e,n){a(d(),"UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}r(vn,"recordLaunch");function An(e,n){a(d(),"UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}r(An,"recordSettledTurn");function kn(e,n){a(d(),"UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}r(kn,"setFrozen");function xn(e){a(d(),"UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}r(xn,"clearFrozen");function Wn(e,n){a(d(),"UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}r(Wn,"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 ke(e){return e.worktree_state===null?null:Ee(Object.fromEntries(z.map(n=>[n,e[`worktree_${n}`]])))}r(ke,"worktreeFromProjection");function jn(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,ke(o)))}r(jn,"listNodesByProfile");function Hn(){const e=d();return j(e,`SELECT
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(f)}r(Hn,"browseNodes");function Fn(e,n){a(d(),`UPDATE nodes
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(Fn,"updateNodeTelemetry");function bn(){return a(d(),`SELECT
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(bn,"graphNodes");function xe(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(f)}r(xe,"listNodes");const We=`SELECT
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(),We).all()}r(In,"listTerminalPlacementResidue");const je=`WITH candidates AS MATERIALIZED (
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 Cn(){return a(d(),je).all().map(f)}r(Cn,"listNodesForSupervision");function Un(){return a(d(),`SELECT node_id, name, created, grantee FROM node_rows WHERE ${N} ORDER BY created`).all()}r(Un,"listNodeIdentities");function Mn(e,n){c(t=>{a(t,"INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)").run(e,n,new Date().toISOString())})}r(Mn,"registerWarmSpare");function Pn(e){return c(n=>a(n,"DELETE FROM warm_pool WHERE node_id = ?").run(e).changes>0)}r(Pn,"unregisterWarmSpare");function O(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
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 qn(){return O(d())}r(qn,"listWarmSpares");function $n(e){return a(d(),"SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}r($n,"isWarmSpare");function B(e){return e.status!=="active"&&e.status!=="idle"?!1:Ne(e.pi_pid,e.pi_pid_identity)==="alive"}r(B,"spareIsClaimable");function zn(e,n,t={}){return c(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(zn,"claimWarmSpare");function Bn(e){return O(d(),e).filter(B).length}r(Bn,"warmSpareCount");function Jn(e){return a(d(),"SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e).map(n=>n.node_id)}r(Jn,"childrenOf");function Yn(){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(Yn,"rosterNodes");function Vn(e){return d().prepare(`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?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(f)}r(Vn,"listResumableRoots");export*from"./tree.js";function Xn(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(Xn,"hasLiveMessageWait");function Gn(e,n){a(d(),"UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?").run(n,e)}r(Gn,"setMessageWait");function Qn(e,n,t){return c(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(Qn,"deliverAndSettleMessageWait");function Kn(e,n,t){return c(o=>{const i=a(o,`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
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(Kn,"settleDeadMessageWait");function Zn(e,n,t){return c(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(Zn,"withFreshTerminalGuard");function w(e){return ce(e)}r(w,"hasUnreconciledManagedWorktree");function J(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||w(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{ie().delete(i)}catch(s){if(!(s instanceof se))throw s}}r(h,"deleteNodeConversations");function L(e,n){const t=U(e,n);return t===null||t.deleted_at!==null?!1:(De(e,t),!0)}r(L,"deleteNodeObject");function D(e){return{nodeId:e,app:R(e)===null?null:Se(e)}}r(D,"nodeFiles");function Y({nodeId:e,app:n}){n!==null&&W(C(n).nodes,Oe(e,n)),W(te(I(e)),I(e))}r(Y,"removeNodeAppTrees");function V({nodeId:e}){return[we(e)]}r(V,"nodeOwnedDirs");function X({nodeId:e,app:n}){if(n!==null)try{Z(x(C(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))ee(n,{recursive:!0,force:!0});X(e)}r(v,"removeNodeFiles");function et(e){if(w(e))return{deleted:!1};const n=D(e),t=T([e]),o=c(i=>(L(i,e),{deleted:!0}));return h(t),v(n),o}r(et,"deleteNode");function nt(e){const n=[...new Set(e)];if(n.length===0)return[];const t=n.filter(w);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(","),u=d().prepare(`SELECT node_id FROM nodes WHERE node_id IN (${s}) ORDER BY created`).all(...n).map(({node_id:p})=>p).filter(p=>c(E=>L(E,p)));h(i);for(const p of u){const E=o[n.indexOf(p)];A(E,()=>v(E))}return u}r(nt,"deleteNodes");function tt(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(),u=r(_=>Q(_)<o,"quiet"),p=r(_=>({node_id:_.node_id,status:_.status,created:_.created}),"toPruned"),E=a(l,`SELECT * FROM node_rows
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(f).filter(_=>J(_,{pastTtl:!0})&&u(_)&&!e.held(_.node_id)).map(p),S=t?a(l,`SELECT * FROM node_rows
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(f).filter(_=>_.node_id!==s&&!me(_.pi_pid??null)&&(_.frozen_at??null)===null&&(_.respawn_not_before??null)===null&&_.intent!=="idle-release"&&!H(_)&&!ae(_.node_id)&&!w(_.node_id)&&u(_)&&!e.held(_.node_id)).map(p):[],y=[...E,...S];return n||y.length===0?{pruned:y,dryRun:n}:(G(y,e.removeDirs),{pruned:y,dryRun:n})}r(tt,"pruneNodes");function G(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)c(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(G,"deletePrunedNodes");function A(e,n){try{n()}catch(t){re({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}r(A,"eachNodeBestEffort");function Q(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=ne(x(ye(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}r(Q,"lastActivityMs");function ot(e){const n=e.dryRun??!1,t=xe(),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:Q(u)})).sort((u,p)=>p.recency-u.recency).slice(s).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created}));return n||l.length===0?{pruned:l,dryRun:n}:(G(l),{pruned:l,dryRun:n})}r(ot,"pruneToLimit");export{cn as abandonCreateRequest,on as assertRunNotDeleting,Hn as browseNodes,pn as canonicalSessionFile,Jn as childrenOf,zn as claimWarmSpare,Ln as clearFinalReportIfMatches,xn as clearFrozen,_n as completeCreateRequest,rn as createNode,et as deleteNode,nt as deleteNodes,Qn as deliverAndSettleMessageWait,Nn as dueNodeDeadlines,sn as findCreateRequest,fn as findNodeBySessionFile,hn as getFinalReport,R as getNode,En as getRow,mn as getRowByPane,bn as graphNodes,Xn as hasLiveMessageWait,J as isCollectible,$n as isWarmSpare,Q as lastActivityMs,Un as listNodeIdentities,xe as listNodes,jn as listNodesByProfile,Cn as listNodesForSupervision,Vn as listResumableRoots,In as listTerminalPlacementResidue,qn as listWarmSpares,D as nodeFiles,je as nodesForSupervisionSql,dn as pruneExpiredCreateRequests,tt as pruneNodes,ot as pruneToLimit,ln as recordCreateRequestNode,vn as recordLaunch,Wn as recordRespawnAttempt,An as recordSettledTurn,Mn as registerWarmSpare,v as removeNodeFiles,an as reserveCreateRequest,un as reserveCreateRequestNode,wn as rewriteLocalNodeIdentity,Yn as rosterNodes,kn as setFrozen,On as setIntent,Gn as setMessageWait,Rn as setNodeDeadline,Dn as setPresence,gn as setStatus,Kn as settleDeadMessageWait,yn as shiftProfileNodeDeadlines,We as terminalPlacementResidueSql,Tn as transitionStatusIntent,Pn as unregisterWarmSpare,Sn as updateNode,Fn as updateNodeTelemetry,Bn as warmSpareCount,Zn as withFreshTerminalGuard};
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 d}from"./events.js";import{getByRowid as w}from"./objects.js";import{rememberDeletedIsolated as h}from"../runs/confinement.js";let a=0;function W(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{S(e,t),e.exec(`RELEASE ${o}`)}catch(i){throw e.exec(`ROLLBACK TO ${o}`),e.exec(`RELEASE ${o}`),i}}E(W,"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),d(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(s){throw e.exec(`ROLLBACK TO ${i}`),e.exec(`RELEASE ${i}`),s}return!0}E(j,"deleteProfileWithOwned");function S(e,t){const o=u(e,t);n(e,"UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(o,t.rowid),d(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),h(t.id,e),n(e,"DELETE FROM nodes WHERE node_id = ?").run(t.id)}E(S,"deleteInside");function u(e,t){const o=n(e,`WITH RECURSIVE sub(rowid) AS (
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)),s=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)||s.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),d(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{W as deleteNodeWithOwned,j as deleteProfileWithOwned};
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,2 +1,2 @@
1
- var g=Object.defineProperty;var r=(e,t)=>g(e,"name",{value:t,configurable:!0});import{join as b}from"node:path";import{readOutputResult as y}from"../../core/runtime/structured-output.js";import{ReviewOperationError as _}from"../../core/review/types.js";import{cronSinkDisplay as x}from"../../core/canvas/crons.js";import{isProfilePaused as c,profileDir as f,sanitizeProfileMetadata as O}from"../../core/profiles/manifest.js";import{nodeMetaPath as D,transcriptPath as T,viewSocketPath as E}from"../../core/canvas/paths.js";import{appForNode as p,contextDir as S,nodeAgentDir as A}from"../../core/canvas/node-agent-paths.js";import{FinalizationError as R}from"../../core/feed/feed.js";import{NodeIdConflictError as z}from"../../core/runtime/nodes.js";import{ScopeDeniedError as N}from"../../core/scopes.js";import{isBeneathRefusal as C}from"../../core/spaces/open-beneath.js";import{CrtrError as s}from"../../core/errors.js";import{WorktreeError as j}from"../../core/worktree.js";import{ApiError as q}from"../../api/errors.js";import{RunError as l}from"../../core/runs/operations.js";import{ExitCode as o}from"../../types.js";function ce(e,t){const{report:n}=e;return{stores:n.stores.map(i=>({root:i.root,owner:{...i.owner},docs:i.docs,...i.skipped===void 0?{}:{skipped:i.skipped}})),counts:n.counts,rewrites:n.rewrites,dropped_fields:n.droppedFields,skipped:n.skipped,resolutions:n.resolutions.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),blockers:e.blockers.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),dryRun:e.dryRun,pending:e.pending,resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}r(ce,"toMigrateStateDTO");function F(e,t){try{return y(e,t)??null}catch{return null}}r(F,"readStructuredResult");function I(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}r(I,"toNodeOutcomeSummaryDTO");function m(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const n=e.final_report??null,i={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:n===null?null:`${e.node_id}/${n}`,structured_result:e.outcome_kind==="result"?F(e.node_id,e.grantee):null,detail:t};return e.outcome_kind==="result"?{...i,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...i,kind:"failure",reason:"declined",declined:t?.declined??null}:{...i,kind:"failure",reason:e.outcome_reason,declined:null}}r(m,"toNodeOutcomeDTO");function fe(e){const t=m(e);return t===null||t.reason==="parked"?null:t.kind==="result"||t.reason==="finished"?{...t,kind:"result",reason:"finalized",declined:null}:t.reason==="declined"?{...t,reason:"declined",details:t.declined}:t.reason==="deadline_exceeded"?{...t,reason:"deadline_exceeded",declined:null}:t.reason==="cap_exhausted"?{...t,reason:"cap_exhausted",declined:null}:t.reason==="closed"||t.reason==="stranded"||t.reason==="retired"?{...t,reason:"canceled",declined:null}:{...t,reason:"runtime_error",declined:null,details:{crouter_reason:t.reason}}}r(fe,"toRunOutcomeDTO");function pe(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}r(pe,"toOutcomeDeliveryDTO");function me(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,status:e.status,frozen_at:e.frozen_at,pi_pid:e.pi_pid,telemetry_context_tokens:e.telemetry_context_tokens,telemetry_last_activity:e.telemetry_last_activity,fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming}}r(me,"toGraphNodeDTO");function ve(e,t=c(e.profile_id)){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,scopes:e.scopes,isolated:e.isolated,grantee:e.grantee??p(e.node_id),profile_paused:t,parent:e.parent,created:e.created,intent:e.intent,waiting_for:e.waiting_for,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??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,outcome:I(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}r(ve,"toNodeSummaryDTO");function P(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(n=>n.node_id),subscribers:t.subscribers.map(n=>n.node_id),children:[...t.children]}}r(P,"toNodeEdgesDTO");function U(e,t){return{node_dir:A(e,t),context_dir:S(e,t),meta_path:D(e),transcript_path:T(e),view_socket:E(e)}}r(U,"toNodePathsDTO");function G(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}r(G,"toNodeWorktreeDTO");function he(e,t){const n=p(e.node_id),i={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,profile_id:e.profile_id??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:n,profile_paused:c(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??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,final_report:e.final_report??null,finalized_at:e.finalized_at??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,outcome:m(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:P(e,t),paths:U(e.node_id,n)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=e.telemetry_context_tokens??e.telemetry_tokens_in??null,e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=G(e.managed_worktree)),i}r(he,"toNodeDetailDTO");function ke(e,t,n){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:n,outcome:t.outcome}}r(ke,"toReviveResultDTO");function ge(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}r(ge,"toCloseResultDTO");function be(e,t,n){const i={report:e.report,notified:[...e.deliveredTo]};return t!==void 0&&(i.transitioned=t),n!==void 0&&(i.worktree_auto_dropped=!0,i.worktree_auto_dropped_path=n),i}r(be,"toReportResultDTO");function ye(e){return{node_id:e.node_id,active:e.active,created:e.created}}r(ye,"toSubscriptionDTO");function M(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}r(M,"envKeys");function xe(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,grant_id:e.grant_id,scopes:e.scopes,origin_run_id:e.origin_run_id,isolated:e.isolated,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:M(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:x(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}r(xe,"toCronDTO");function Oe(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}r(Oe,"toCronRunDTO");function De(e){return{id:e.profileId,app:e.manifest.grantee??"app:terminal",name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),delivery_limits:{...e.manifest.delivery_limits},paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:O(e.manifest.metadata),default_dir:null,created_at:e.manifest.created_at,last_used_at:e.manifest.last_used_at,profile_path:f(e.profileId),memory_path:f(e.profileId)}}r(De,"toProfileDTO");function v(e,t={}){const n={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.document_name!==null&&(n.document=e.document_name),e.opened_at!==null&&(n.opened_at=e.opened_at),e.submit_requested_at!==null&&(n.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(n.approved_at=e.approved_at),e.changed!==null&&(n.changed=e.changed),e.comments_total!==null&&(n.comments_total=e.comments_total),e.comments_unresolved!==null&&(n.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(n.canceled_at=e.canceled_at),e.cancel_reason!==null&&(n.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(n.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(n.result_path=t.result_path),e.delivery_error!==null&&(n.delivery_error=e.delivery_error),e.projection_error!==null&&(n.projection_error=e.projection_error),n}r(v,"toReviewDTO");function Te(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}r(Te,"toReviewCommentDTO");function B(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}r(B,"toPageFeedbackCommentDTO");function Ee(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(B)}}r(Ee,"toPageFeedbackDTO");function Se(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}r(Se,"toReviewCommentEventDTO");function Ae(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(n=>({...n})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}r(Ae,"toFeedbackResultDTO");const L=!0,W=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},stale_revision:{status:409,code:"stale_revision"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function $(e){const t=h(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof R)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof z)return{status:409,code:"node_id_exists"};if(t instanceof N)return{status:403,code:"scope_denied"};if(C(t))return{status:400,code:"invalid_request"};if(t instanceof _)return W[t.code];if(t instanceof s)return["kind_owned","name_taken","hop_limit","not_a_queue"].includes(t.code)?{status:409,code:t.code}:t.code==="invalid_publish_token"?{status:401,code:t.code}:t.code==="forbidden"||t.code==="argv_forbidden"?{status:403,code:t.code}:{status:H(t.exitCode),code:t.code};if(t instanceof Error){const n=t.message;if(/unknown node/i.test(n))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(n))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(n))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}r($,"errorToStatus");function h(e){if(!(e instanceof j))return e;const t=e.code==="unknown_node"?o.NOT_FOUND:o.GENERAL,n={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(n.received=e.detail),new s(e.code,e.message,t,n)}r(h,"normalizeThrow");function K(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...n}=e.detail;return{...n,review:V(t)}}r(K,"reviewErrorDetails");function V(e){return e.state!=="approved"?v(e):v(e,{result_path:b(e.review_dir,"result.json")})}r(V,"terminalConflictReviewDTO");function H(e){switch(e){case o.NOT_FOUND:return 404;case o.USAGE:return 400;case o.AMBIGUOUS:return 400;case o.NETWORK:return 503;case o.GENERAL:return 400;default:return 500}}r(H,"statusForExitCode");function J(e){const n=(e instanceof Error?e.message:String(e)).split(`
2
- `,1)[0].trim();return n===""?"internal error":n.length>500?`${n.slice(0,497)}\u2026`:n}r(J,"boundedCause");function Re(e){const t=h(e),{status:n,code:i}=$(t);if(n>=500){const a={error:{code:i,message:J(t)}};return t instanceof l&&(a.error.origin="runtime",a.error.retryable=t.retryable),{status:n,body:a}}const k=t instanceof Error?t.message:String(t),u=t instanceof _?K(t):(t instanceof s||t instanceof q||t instanceof l)&&t.details!==void 0?t.details:void 0,d={error:{code:i,message:k}};return u!==void 0&&(d.error.details=u),t instanceof l&&(t.param&&(d.error.param=t.param),t.scope&&(d.error.scope=t.scope),d.error.origin="runtime",d.error.retryable=t.retryable),{status:n,body:d}}r(Re,"toErrorBody");export{W as REVIEW_ERROR_MAP,$ as errorToStatus,ge as toCloseResultDTO,xe as toCronDTO,Oe as toCronRunDTO,Re as toErrorBody,Ae as toFeedbackResultDTO,me as toGraphNodeDTO,ce as toMigrateStateDTO,he as toNodeDetailDTO,P as toNodeEdgesDTO,m as toNodeOutcomeDTO,I as toNodeOutcomeSummaryDTO,U as toNodePathsDTO,ve as toNodeSummaryDTO,G as toNodeWorktreeDTO,pe as toOutcomeDeliveryDTO,B as toPageFeedbackCommentDTO,Ee as toPageFeedbackDTO,De as toProfileDTO,be as toReportResultDTO,Te as toReviewCommentDTO,Se as toReviewCommentEventDTO,v as toReviewDTO,ke as toReviveResultDTO,fe as toRunOutcomeDTO,ye as toSubscriptionDTO};
1
+ var h=Object.defineProperty;var r=(e,t)=>h(e,"name",{value:t,configurable:!0});import{join as g}from"node:path";import{readOutputResult as b}from"../../core/runtime/structured-output.js";import{ReviewOperationError as _}from"../../core/review/types.js";import{cronSinkDisplay as y}from"../../core/canvas/crons.js";import{isProfilePaused as c,profileDir as x,sanitizeProfileMetadata as O}from"../../core/profiles/manifest.js";import{nodeMetaPath as D,transcriptPath as T,viewSocketPath as E}from"../../core/canvas/paths.js";import{appForNode as f,contextDir as S,nodeAgentDir as A}from"../../core/canvas/node-agent-paths.js";import{FinalizationError as R}from"../../core/feed/feed.js";import{NodeIdConflictError as z}from"../../core/runtime/nodes.js";import{ScopeDeniedError as N}from"../../core/scopes.js";import{isBeneathRefusal as C}from"../../core/spaces/open-beneath.js";import{CrtrError as s}from"../../core/errors.js";import{WorktreeError as j}from"../../core/worktree.js";import{ApiError as q}from"../../api/errors.js";import{RunError as l}from"../../core/runs/operations.js";import{ExitCode as o}from"../../types.js";function ce(e,t){const{report:n}=e;return{stores:n.stores.map(i=>({root:i.root,owner:{...i.owner},docs:i.docs,...i.skipped===void 0?{}:{skipped:i.skipped}})),counts:n.counts,rewrites:n.rewrites,dropped_fields:n.droppedFields,skipped:n.skipped,resolutions:n.resolutions.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),blockers:e.blockers.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),dryRun:e.dryRun,pending:e.pending,resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}r(ce,"toMigrateStateDTO");function F(e,t){try{return b(e,t)??null}catch{return null}}r(F,"readStructuredResult");function I(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}r(I,"toNodeOutcomeSummaryDTO");function p(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const n=e.final_report??null,i={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:n===null?null:`${e.node_id}/${n}`,structured_result:e.outcome_kind==="result"?F(e.node_id,e.grantee):null,detail:t};return e.outcome_kind==="result"?{...i,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...i,kind:"failure",reason:"declined",declined:t?.declined??null}:{...i,kind:"failure",reason:e.outcome_reason,declined:null}}r(p,"toNodeOutcomeDTO");function fe(e){const t=p(e);return t===null||t.reason==="parked"?null:t.kind==="result"||t.reason==="finished"?{...t,kind:"result",reason:"finalized",declined:null}:t.reason==="declined"?{...t,reason:"declined",details:t.declined}:t.reason==="deadline_exceeded"?{...t,reason:"deadline_exceeded",declined:null}:t.reason==="cap_exhausted"?{...t,reason:"cap_exhausted",declined:null}:t.reason==="closed"||t.reason==="stranded"||t.reason==="retired"?{...t,reason:"canceled",declined:null}:{...t,reason:"runtime_error",declined:null,details:{crouter_reason:t.reason}}}r(fe,"toRunOutcomeDTO");function pe(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}r(pe,"toOutcomeDeliveryDTO");function me(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,status:e.status,frozen_at:e.frozen_at,pi_pid:e.pi_pid,telemetry_context_tokens:e.telemetry_context_tokens,telemetry_last_activity:e.telemetry_last_activity,fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming}}r(me,"toGraphNodeDTO");function ve(e,t=c(e.profile_id)){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,scopes:e.scopes,isolated:e.isolated,grantee:e.grantee??f(e.node_id),profile_paused:t,parent:e.parent,created:e.created,intent:e.intent,waiting_for:e.waiting_for,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??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,outcome:I(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}r(ve,"toNodeSummaryDTO");function P(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(n=>n.node_id),subscribers:t.subscribers.map(n=>n.node_id),children:[...t.children]}}r(P,"toNodeEdgesDTO");function U(e,t){return{node_dir:A(e,t),context_dir:S(e,t),meta_path:D(e),transcript_path:T(e),view_socket:E(e)}}r(U,"toNodePathsDTO");function G(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}r(G,"toNodeWorktreeDTO");function ke(e,t){const n=f(e.node_id),i={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,profile_id:e.profile_id??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:n,profile_paused:c(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??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,final_report:e.final_report??null,finalized_at:e.finalized_at??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,outcome:p(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:P(e,t),paths:U(e.node_id,n)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=e.telemetry_context_tokens??e.telemetry_tokens_in??null,e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=G(e.managed_worktree)),i}r(ke,"toNodeDetailDTO");function he(e,t,n){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:n,outcome:t.outcome}}r(he,"toReviveResultDTO");function ge(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}r(ge,"toCloseResultDTO");function be(e,t,n){const i={report:e.report,notified:[...e.deliveredTo]};return t!==void 0&&(i.transitioned=t),n!==void 0&&(i.worktree_auto_dropped=!0,i.worktree_auto_dropped_path=n),i}r(be,"toReportResultDTO");function ye(e){return{node_id:e.node_id,active:e.active,created:e.created}}r(ye,"toSubscriptionDTO");function M(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}r(M,"envKeys");function xe(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,grant_id:e.grant_id,scopes:e.scopes,origin_run_id:e.origin_run_id,isolated:e.isolated,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:M(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:y(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}r(xe,"toCronDTO");function Oe(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}r(Oe,"toCronRunDTO");function De(e){return{id:e.profileId,app:e.manifest.grantee??"app:terminal",name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),delivery_limits:{...e.manifest.delivery_limits},paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:O(e.manifest.metadata),default_dir:null,created_at:e.manifest.created_at,last_used_at:e.manifest.last_used_at,profile_path:x(e.profileId)}}r(De,"toProfileDTO");function m(e,t={}){const n={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.document_name!==null&&(n.document=e.document_name),e.opened_at!==null&&(n.opened_at=e.opened_at),e.submit_requested_at!==null&&(n.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(n.approved_at=e.approved_at),e.changed!==null&&(n.changed=e.changed),e.comments_total!==null&&(n.comments_total=e.comments_total),e.comments_unresolved!==null&&(n.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(n.canceled_at=e.canceled_at),e.cancel_reason!==null&&(n.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(n.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(n.result_path=t.result_path),e.delivery_error!==null&&(n.delivery_error=e.delivery_error),e.projection_error!==null&&(n.projection_error=e.projection_error),n}r(m,"toReviewDTO");function Te(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}r(Te,"toReviewCommentDTO");function B(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}r(B,"toPageFeedbackCommentDTO");function Ee(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(B)}}r(Ee,"toPageFeedbackDTO");function Se(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}r(Se,"toReviewCommentEventDTO");function Ae(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(n=>({...n})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}r(Ae,"toFeedbackResultDTO");const L=!0,W=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},stale_revision:{status:409,code:"stale_revision"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function $(e){const t=v(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof R)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof z)return{status:409,code:"node_id_exists"};if(t instanceof N)return{status:403,code:"scope_denied"};if(C(t))return{status:400,code:"invalid_request"};if(t instanceof _)return W[t.code];if(t instanceof s)return["kind_owned","name_taken","hop_limit","not_a_queue"].includes(t.code)?{status:409,code:t.code}:t.code==="invalid_publish_token"?{status:401,code:t.code}:t.code==="forbidden"||t.code==="argv_forbidden"?{status:403,code:t.code}:{status:H(t.exitCode),code:t.code};if(t instanceof Error){const n=t.message;if(/unknown node/i.test(n))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(n))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(n))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}r($,"errorToStatus");function v(e){if(!(e instanceof j))return e;const t=e.code==="unknown_node"?o.NOT_FOUND:o.GENERAL,n={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(n.received=e.detail),new s(e.code,e.message,t,n)}r(v,"normalizeThrow");function K(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...n}=e.detail;return{...n,review:V(t)}}r(K,"reviewErrorDetails");function V(e){return e.state!=="approved"?m(e):m(e,{result_path:g(e.review_dir,"result.json")})}r(V,"terminalConflictReviewDTO");function H(e){switch(e){case o.NOT_FOUND:return 404;case o.USAGE:return 400;case o.AMBIGUOUS:return 400;case o.NETWORK:return 503;case o.GENERAL:return 400;default:return 500}}r(H,"statusForExitCode");function J(e){const n=(e instanceof Error?e.message:String(e)).split(`
2
+ `,1)[0].trim();return n===""?"internal error":n.length>500?`${n.slice(0,497)}\u2026`:n}r(J,"boundedCause");function Re(e){const t=v(e),{status:n,code:i}=$(t);if(n>=500){const a={error:{code:i,message:J(t)}};return t instanceof l&&(a.error.origin="runtime",a.error.retryable=t.retryable),{status:n,body:a}}const k=t instanceof Error?t.message:String(t),u=t instanceof _?K(t):(t instanceof s||t instanceof q||t instanceof l)&&t.details!==void 0?t.details:void 0,d={error:{code:i,message:k}};return u!==void 0&&(d.error.details=u),t instanceof l&&(t.param&&(d.error.param=t.param),t.scope&&(d.error.scope=t.scope),d.error.origin="runtime",d.error.retryable=t.retryable),{status:n,body:d}}r(Re,"toErrorBody");export{W as REVIEW_ERROR_MAP,$ as errorToStatus,ge as toCloseResultDTO,xe as toCronDTO,Oe as toCronRunDTO,Re as toErrorBody,Ae as toFeedbackResultDTO,me as toGraphNodeDTO,ce as toMigrateStateDTO,ke as toNodeDetailDTO,P as toNodeEdgesDTO,p as toNodeOutcomeDTO,I as toNodeOutcomeSummaryDTO,U as toNodePathsDTO,ve as toNodeSummaryDTO,G as toNodeWorktreeDTO,pe as toOutcomeDeliveryDTO,B as toPageFeedbackCommentDTO,Ee as toPageFeedbackDTO,De as toProfileDTO,be as toReportResultDTO,Te as toReviewCommentDTO,Se as toReviewCommentEventDTO,m as toReviewDTO,he as toReviveResultDTO,fe as toRunOutcomeDTO,ye as toSubscriptionDTO};
@@ -1,4 +1,4 @@
1
- var E=Object.defineProperty;var u=(i,t)=>E(i,"name",{value:t,configurable:!0});import{prepared as r}from"../../core/sqlite-statements.js";import{randomUUID as S}from"node:crypto";import{openDb as h}from"../../core/canvas/db.js";import{getNode as p}from"../../core/canvas/canvas.js";import{BrokerClient as k,SocketTransport as I}from"../../core/broker-client/client.js";import{emitRunEvent as c,emitRunSettlement as _}from"../../core/runs/events.js";import{cancelOpenQuestions as D}from"../../core/runs/questions.js";import{emitEvent as T}from"../../core/events/emit.js";import{toRunOutcomeDTO as O}from"../api/map.js";import{readOutputResult as R}from"../../core/runtime/structured-output.js";const N=JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),l=new Map,A=250;class v{static{u(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 s=h(),n=r(s,"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");n&&(this.outcomeRevision=JSON.parse(n.body_json).outcome.revision);const o=r(s,"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.poll(),250),this.timer.unref(),l.set(t,this),this.poll()}poll(){const t=p(this.nodeId);if(!t||t.run_id!==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 s=O(t);if(s&&s.revision!==this.outcomeRevision&&Date.now()-Date.parse(s.settled_at)<720*60*6e4){if(this.nodeId===this.runId){const n=r(h(),"SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(this.runId,this.runId);for(const o of n)f(o.node_id,this.runId),l.get(o.node_id)?.poll()}if(this.outcomeRevision=s.revision,this.nodeId===this.runId){const n=s.kind==="result"?R(this.nodeId,t.grantee):void 0;_(this.runId,this.nodeId,"node.settled",{outcome:s,usage:JSON.parse(t.usage_json??N),...n===void 0?{}:{result:n}})}else _(this.runId,this.nodeId,"child.settled",{child_node_id:this.nodeId,outcome:s});if(t.grantee&&t.grantee!=="app:terminal"){const n=this.nodeId===this.runId?{run_id:this.runId}:{node_id:this.nodeId};D(n,this.nodeId===this.runId?"the run settled":"the asking node was closed").catch(o=>T({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 k(this.nodeId,{transport:new I(this.nodeId,{recordsViewerFaults:!1})});this.client=t,t.on("connect",()=>t.send({type:"hello",role:"observer",client_id:S(),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=r(h(),"SELECT event_cursor FROM nodes WHERE node_id = ?").get(this.runId).event_cursor),e.type==="message_update"&&e.message.role==="assistant"&&this.openAssistant){const s=e.message.content;if(!Array.isArray(s))return;const n=s.at(-1);n&&typeof n=="object"&&"type"in n&&(n.type==="toolCall"?this.block={kind:"tool_call",name:"name"in n&&typeof n.name=="string"?n.name:""}:(n.type==="text"||n.type==="thinking")&&(this.block={kind:n.type}));const o=s.filter(d=>d?.type==="thinking").map(d=>d.thinking).join(""),a=s.filter(d=>d?.type==="text").map(d=>d.text).join(""),m=o.startsWith(this.thinking)?o.slice(this.thinking.length):o,g=a.startsWith(this.output)?a.slice(this.output.length):a;this.thinking=o,this.output=a,this.pendingThinking+=m,this.pendingOutput+=g,(this.pendingThinking||this.pendingOutput)&&!this.flushTimer&&(this.flushTimer=setTimeout(()=>this.flushDeltas(),A),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(r(h(),"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),l.delete(this.nodeId);const t=this.client;this.client=void 0,t?.close()}}function F(i){return l.get(i)?.assistantMessageStartSequence??null}u(F,"openAssistantMessageStartSequence");function B(i){return l.get(i)?.openBlock??null}u(B,"openAssistantBlock");function f(i,t){if(!l.has(i)){if(i!==t){const e=p(i);!r(h(),"SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'child.started' LIMIT 1").get(t,i)&&e&&Date.now()-Date.parse(e.created)<720*60*6e4&&c(t,i,"child.started",{child_node_id:i,kind:e.kind})}new v(i,t)}}u(f,"ensureRunObserver");function U(){const i=new Date(Date.now()-2592e6).toISOString(),t=r(h(),`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 > ?
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(i);for(const e of t)f(e.node_id,e.run_id)}u(U,"pollRunObservers");export{f as ensureRunObserver,B as openAssistantBlock,F as openAssistantMessageStartSequence,U as pollRunObservers};
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};
@@ -7,6 +7,12 @@ description: Behavior changes in @north-light/sdk that an app must act on, newes
7
7
 
8
8
  Changes to `@north-light/sdk` that can change what an existing app sees. Newest first.
9
9
 
10
+ ## 0.3.462
11
+
12
+ ### `ProfileDTO.memory_path` is removed (profile objects carry only `profile_path`)
13
+
14
+ `memory_path`, the deprecated alias of `profile_path` that 0.3.459 kept, is no longer sent. Read `profile_path`, which holds the same value (`<app space>/profiles/<id>`). A runtime older than 0.3.459 sends only `memory_path`.
15
+
10
16
  ## 0.3.460
11
17
 
12
18
  ### `crouter-sdk keygen` releases its key file when the add fails (no app change)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.460",
3
+ "version": "0.3.462",
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.460",
140
+ "@north-light/identity": "0.3.462",
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",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/identity",
3
- "version": "0.3.460",
3
+ "version": "0.3.462",
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.460",
3
+ "version": "0.3.462",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/cli",
9
- "version": "0.3.460",
9
+ "version": "0.3.462",
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.460",
21
+ "@north-light/identity": "0.3.462",
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.460",
12098
+ "version": "0.3.462",
12099
12099
  "license": "UNLICENSED"
12100
12100
  },
12101
12101
  "packages/crouter-env-docker": {
12102
12102
  "name": "@north-light/env-docker",
12103
- "version": "0.3.460",
12103
+ "version": "0.3.462",
12104
12104
  "license": "UNLICENSED"
12105
12105
  },
12106
12106
  "packages/crouter-identity": {
12107
12107
  "name": "@north-light/identity",
12108
- "version": "0.3.460",
12108
+ "version": "0.3.462",
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.460",
12116
+ "version": "0.3.462",
12117
12117
  "license": "UNLICENSED",
12118
12118
  "dependencies": {
12119
- "@north-light/api": "0.3.460",
12120
- "@north-light/identity": "0.3.460"
12119
+ "@north-light/api": "0.3.462",
12120
+ "@north-light/identity": "0.3.462"
12121
12121
  }
12122
12122
  },
12123
12123
  "packages/crouter-sdk": {
12124
12124
  "name": "@north-light/sdk",
12125
- "version": "0.3.460",
12125
+ "version": "0.3.462",
12126
12126
  "license": "UNLICENSED",
12127
12127
  "dependencies": {
12128
- "@north-light/api": "0.3.460",
12129
- "@north-light/identity": "0.3.460",
12128
+ "@north-light/api": "0.3.462",
12129
+ "@north-light/identity": "0.3.462",
12130
12130
  "jose": "^6.2.1"
12131
12131
  },
12132
12132
  "bin": {