@north-light/cli 0.3.556 → 0.3.558

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 +1 @@
1
- var B=Object.defineProperty;var l=(e,o)=>B(e,"name",{value:o,configurable:!0});import{killBashJobObject as E,recordBashJobObject as J}from"../../../core/spaces/stop.js";import{readerFor as P}from"../reader.js";import{join as $}from"node:path";import{createFileBeneath as g,existsBeneath as m,unlinkBeneath as A}from"../../../core/spaces/open-beneath.js";import{launchAppProcess as q,appProcessSandboxed as O}from"../../../core/spaces/process.js";import{BASH_JOB_SUPERVISOR_SCRIPT as N}from"../../../core/bash-job-supervisor.js";import{resolveAdmittedHostCommand as L}from"../../../core/runtime/spawn-env.js";import{requireCurrentExecution as _}from"./broker-recovery.js";import{isSafeNodeId as T}from"../../../core/canvas/paths.js";import{contextDir as v}from"../../../core/canvas/node-agent-paths.js";import{getNode as f}from"../../../core/canvas/canvas.js";import{isBrokerLive as D}from"../../../core/runtime/model-swap.js";import{assertNotFinalized as R}from"../../../core/runtime/reopen.js";import{reviveNode as C}from"../../../core/runtime/revive.js";import{checkStart as z}from"../../../core/runtime/start-check.js";import{activeBackgroundBashJobs as F,bashJobPaths as k,isBashJobProcessGroupAlive as M,readJobPgid as G,readJobPgidIdentity as H,isSafeBashJobId as I,readBashNiceness as Z,stopBackgroundBashJob as U}from"../../../core/bash-jobs.js";import{ApiError as i}from"../../../api/index.js";import{notFound as V}from"../../../core/errors.js";import{freshChildNodeExecPath as X}from"../../../core/runtime/branded-host.js";async function w(e){const o=e.params.id;if(o===void 0||!T(o))throw new i(400,"invalid_node_id",`invalid node id: ${JSON.stringify(o)}`);if(await f(o)===null)throw V(`unknown node: ${o}`,{received:o});const a=e.params.jobId;if(a!==void 0){if(!I(a))throw new i(400,"invalid_job_id",`invalid background job id: ${JSON.stringify(a)}`);return{nodeId:o,jobId:a,dir:await v(o)}}return{nodeId:o,dir:await v(o)}}l(w,"requireTarget");async function x(e){const{nodeId:o,dir:n}=await w(e);if(e.principal.class!=="broker"||e.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may start a job");const a=e.body;if(!a||typeof a!="object"||Array.isArray(a))throw new i(400,"invalid_request","job.start requires a JSON body");const d=a;await _(o,d.expected_execution_id);const r=d.job_id,s=d.cwd,p=d.env;if(typeof r!="string"||!I(r)||typeof s!="string"||!p||typeof p!="object"||Array.isArray(p)||Object.entries(p).some(([c,b])=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(c)||typeof b!="string"))throw new i(400,"invalid_request","invalid job id, cwd or environment");const h=await f(o);if(await z({grantee:h.grantee??"app:terminal",sub:h.sub,grant_id:h.grant_id}),!O())throw new i(400,"invalid_request","job.start is only used with the root launcher");const t=k(n,r);if(!(m(t.root,t.jobRun)||m(t.root,t.jobBg))||![t.cmdSh,t.jobLog].every(c=>m(t.root,c)))throw new i(404,"job_not_found","job was not prepared by this node");const j=$(t.dir,"job.starting");try{g(t.root,j,"")}catch(c){throw c.code==="EEXIST"?new i(409,"job_already_started","job was already started"):c}let u;try{const c=p,b=L("bash",c,s),y=await f(o),S=await X();return u=await q({nodeId:o,app:y.grantee??"app:terminal",isolated:y.isolated,cwd:s,env:c,capture:!1,command:[b,"-c",N,"--",t.cmdSh,t.jobLog,t.jobExit,t.jobRun,t.jobDone,b,String(Z(n)),S]}),g(t.root,t.jobPgid,String(u.pid),384),g(t.root,t.jobPgidIdentity,`launcher:${u.pid}`,384),{status:201,body:{pid:u.pid}}}catch(c){if(u!==void 0)try{await u.stop()}catch(b){throw new AggregateError([c,b],`job ${r} launched but could not be recorded or stopped`)}try{A(t.root,j)}catch(b){if(b.code!=="ENOENT")throw b}throw c}}l(x,"handleStart");async function K(e){const{nodeId:o,dir:n}=await w(e),a=Date.now();return{status:200,body:F(n).map(r=>{const s=G(n,r.jobId)??null;return{job_id:r.jobId,command:r.command,purpose:r.purpose,started_at:new Date(r.startedAtMs).toISOString(),elapsed_ms:Math.max(0,a-r.startedAtMs),pgid:s,pgid_alive:s!==null&&M(s,H(n,r.jobId))}})}}l(K,"handleList");async function Q(e){const{nodeId:o,jobId:n,dir:a}=await w(e);if(n===void 0)throw new i(400,"invalid_request","a job id is required");const d=e.query.get("foreground")==="1";if(d){if(e.principal.class!=="broker"||e.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may abort its foreground job");await _(o,e.body?.expected_execution_id)}const r=await U(a,n,d,o);if(r.kind==="missing")throw new i(404,"job_not_found",`no background job ${n} for ${o}`);if(r.kind==="retired")throw new i(404,"job_not_found",`background job ${n} for ${o} is no longer running`,{log_path:r.logPath});if(r.kind==="not-stoppable")throw new i(409,"job_not_stoppable",`job ${n} recorded no trusted process identity`,{log_path:r.logPath});if(d)return{status:200,body:{node_id:o,job_id:n,signaled:r.signaled}};await R(o),await E(n,async h=>{const t=await P(h,e);return t.class==="person"?t.person:t.class==="app"?t.app:t.node});const s=await f(o);if(s!==null&&!D(s))try{await C(o,{resume:!0,capacity:"freeze"})}catch{}return{status:200,body:{node_id:o,job_id:n,signaled:r.signaled}}}l(Q,"handleStop");async function W(e){const{nodeId:o,jobId:n,dir:a}=await w(e);if(n===void 0)throw new i(400,"invalid_request","a job id is required");if(e.principal.class!=="broker"||e.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may record its job");const d=e.body,r=k(a,n);if(typeof d?.command!="string"||d.job_dir!==r.dir||d.log_path!==r.jobLog)throw new i(400,"invalid_request",`job.background requires command, job_dir ${r.dir} and log_path ${r.jobLog}`);if(!m(r.root,r.jobBg))throw new i(404,"job_not_found",`job ${n} of ${o} is not backgrounded`);const s=d.command;return{status:201,body:{id:(await J(o,n,{command:s,jobDir:r.dir,logPath:r.jobLog})).id}}}l(W,"handleBackground");const _o=[{method:"POST",pattern:"/v1/nodes/:id/jobs/:jobId/background",handler:W},{method:"POST",pattern:"/v1/nodes/:id/jobs/start",handler:x},{method:"GET",pattern:"/v1/nodes/:id/jobs",handler:K},{method:"DELETE",pattern:"/v1/nodes/:id/jobs/:jobId",handler:Q}];export{_o as bashJobRoutes};
1
+ var B=Object.defineProperty;var l=(e,o)=>B(e,"name",{value:o,configurable:!0});import{killBashJobObject as E,recordBashJobObject as J}from"../../../core/spaces/stop.js";import{readerFor as P}from"../reader.js";import{join as A}from"node:path";import{createFileBeneath as g,existsBeneath as m,unlinkBeneath as $}from"../../../core/spaces/open-beneath.js";import{launchAppProcess as q,appProcessSandboxed as O}from"../../../core/spaces/process.js";import{BASH_JOB_SUPERVISOR_SCRIPT as N}from"../../../core/bash-job-supervisor.js";import{resolveAdmittedHostCommand as L}from"../../../core/runtime/spawn-env.js";import{requireCurrentExecution as _}from"./broker-recovery.js";import{isSafeNodeId as T}from"../../../core/canvas/paths.js";import{contextDir as v}from"../../../core/canvas/node-agent-paths.js";import{getNode as f}from"../../../core/canvas/canvas.js";import{isBrokerLive as D}from"../../../core/runtime/model-swap.js";import{assertNotFinalized as R}from"../../../core/runtime/reopen.js";import{reviveNode as C}from"../../../core/runtime/revive.js";import{checkStart as z}from"../../../core/runtime/start-check.js";import{activeBackgroundBashJobs as F,bashJobPaths as k,isBashJobProcessGroupAlive as M,readJobPgid as G,readJobPgidIdentity as H,isSafeBashJobId as I,readBashNiceness as Z,stopBackgroundBashJob as U}from"../../../core/bash-jobs.js";import{ApiError as i}from"../../../api/index.js";import{notFound as V}from"../../../core/errors.js";import{freshChildNodeExecPath as X}from"../../../core/runtime/branded-host.js";async function w(e){const o=e.params.id;if(o===void 0||!T(o))throw new i(400,"invalid_node_id",`invalid node id: ${JSON.stringify(o)}`);if(await f(o)===null)throw V(`unknown node: ${o}`,{received:o});const a=e.params.jobId;if(a!==void 0){if(!I(a))throw new i(400,"invalid_job_id",`invalid background job id: ${JSON.stringify(a)}`);return{nodeId:o,jobId:a,dir:await v(o)}}return{nodeId:o,dir:await v(o)}}l(w,"requireTarget");async function x(e){const{nodeId:o,dir:n}=await w(e);if(e.principal.class!=="broker"||e.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may start a job");const a=e.body;if(!a||typeof a!="object"||Array.isArray(a))throw new i(400,"invalid_request","job.start requires a JSON body");const d=a;await _(o,d.expected_execution_id);const r=d.job_id,s=d.cwd,p=d.env;if(typeof r!="string"||!I(r)||typeof s!="string"||!p||typeof p!="object"||Array.isArray(p)||Object.entries(p).some(([c,b])=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(c)||typeof b!="string"))throw new i(400,"invalid_request","invalid job id, cwd or environment");const h=await f(o);if(await z({grantee:h.grantee??"app:terminal",sub:h.sub,grant_id:h.grant_id}),!O())throw new i(400,"invalid_request","job.start is only used with the root launcher");const t=k(n,r);if(!(m(t.root,t.jobRun)||m(t.root,t.jobBg))||![t.cmdSh,t.jobLog].every(c=>m(t.root,c)))throw new i(404,"job_not_found","job was not prepared by this node");const j=A(t.dir,"job.starting");try{g(t.root,j,"")}catch(c){throw c.code==="EEXIST"?new i(409,"job_already_started","job was already started"):c}let u;try{const c=p,b=L("bash",c,s),y=await f(o),S=await X();return u=await q({nodeId:o,app:y.grantee??"app:terminal",isolated:y.isolated,cwd:s,env:c,capture:!1,command:[b,"-c",N,"--",t.cmdSh,t.jobLog,t.jobExit,t.jobRun,t.jobDone,b,String(Z(n)),S,t.jobActivity]}),g(t.root,t.jobPgid,String(u.pid),384),g(t.root,t.jobPgidIdentity,`launcher:${u.pid}`,384),{status:201,body:{pid:u.pid}}}catch(c){if(u!==void 0)try{await u.stop()}catch(b){throw new AggregateError([c,b],`job ${r} launched but could not be recorded or stopped`)}try{$(t.root,j)}catch(b){if(b.code!=="ENOENT")throw b}throw c}}l(x,"handleStart");async function K(e){const{nodeId:o,dir:n}=await w(e),a=Date.now();return{status:200,body:F(n).map(r=>{const s=G(n,r.jobId)??null;return{job_id:r.jobId,command:r.command,purpose:r.purpose,started_at:new Date(r.startedAtMs).toISOString(),elapsed_ms:Math.max(0,a-r.startedAtMs),pgid:s,pgid_alive:s!==null&&M(s,H(n,r.jobId))}})}}l(K,"handleList");async function Q(e){const{nodeId:o,jobId:n,dir:a}=await w(e);if(n===void 0)throw new i(400,"invalid_request","a job id is required");const d=e.query.get("foreground")==="1";if(d){if(e.principal.class!=="broker"||e.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may abort its foreground job");await _(o,e.body?.expected_execution_id)}const r=await U(a,n,d,o);if(r.kind==="missing")throw new i(404,"job_not_found",`no background job ${n} for ${o}`);if(r.kind==="retired")throw new i(404,"job_not_found",`background job ${n} for ${o} is no longer running`,{log_path:r.logPath});if(r.kind==="not-stoppable")throw new i(409,"job_not_stoppable",`job ${n} recorded no trusted process identity`,{log_path:r.logPath});if(d)return{status:200,body:{node_id:o,job_id:n,signaled:r.signaled}};await R(o),await E(n,async h=>{const t=await P(h,e);return t.class==="person"?t.person:t.class==="app"?t.app:t.node});const s=await f(o);if(s!==null&&!D(s))try{await C(o,{resume:!0,capacity:"freeze"})}catch{}return{status:200,body:{node_id:o,job_id:n,signaled:r.signaled}}}l(Q,"handleStop");async function W(e){const{nodeId:o,jobId:n,dir:a}=await w(e);if(n===void 0)throw new i(400,"invalid_request","a job id is required");if(e.principal.class!=="broker"||e.principal.node!==o)throw new i(403,"permission_error","only this node\u2019s broker may record its job");const d=e.body,r=k(a,n);if(typeof d?.command!="string"||d.job_dir!==r.dir||d.log_path!==r.jobLog)throw new i(400,"invalid_request",`job.background requires command, job_dir ${r.dir} and log_path ${r.jobLog}`);if(!m(r.root,r.jobBg))throw new i(404,"job_not_found",`job ${n} of ${o} is not backgrounded`);const s=d.command;return{status:201,body:{id:(await J(o,n,{command:s,jobDir:r.dir,logPath:r.jobLog})).id}}}l(W,"handleBackground");const _o=[{method:"POST",pattern:"/v1/nodes/:id/jobs/:jobId/background",handler:W},{method:"POST",pattern:"/v1/nodes/:id/jobs/start",handler:x},{method:"GET",pattern:"/v1/nodes/:id/jobs",handler:K},{method:"DELETE",pattern:"/v1/nodes/:id/jobs/:jobId",handler:Q}];export{_o as bashJobRoutes};
@@ -1,4 +1,8 @@
1
1
  import type { NodeRow } from '../../core/canvas/index.js';
2
+ /** The silence message due for a job silent for `silentMs`, given the threshold last announced: the
3
+ * largest of `base`, 2×`base`, 4×`base`, then every 4×`base` (15, 30, 60 min, then hourly) that the
4
+ * silence has reached and that was not announced yet. Null when none is due. */
5
+ export declare function dueSilenceThresholdMs(silentMs: number, announcedMs: number, base: number): number | null;
2
6
  export interface BashDeadlineContext {
3
7
  rows: NodeRow[];
4
8
  }
@@ -17,6 +21,10 @@ export declare class BashDeadlineReconciler {
17
21
  /** An exit written before this daemon started is history, not a job to adopt. */
18
22
  private readonly startedAt;
19
23
  run(now: number, ctx: BashDeadlineContext): Promise<void>;
24
+ /** Tell the owner about a live background job that has shown no activity (see the supervisor's
25
+ * activity sampler) for 15 minutes, again at 30 and 60, then hourly. Any activity restarts the
26
+ * schedule; a job marked as an expected wait is skipped. Messages only: the job is never stopped. */
27
+ private warnSilent;
20
28
  /** A running job whose supervisor wrote job.exit has exited: `finishJob` publishes `exited`
21
29
  * once (the row leaves `running`). A job being stopped (job.stop) is ended by its killer. */
22
30
  private publishExits;
@@ -1,3 +1,3 @@
1
- var y=Object.defineProperty;var p=(h,t)=>y(h,"name",{value:t,configurable:!0});import{existsSync as n,readFileSync as m,readdirSync as _,statSync as w}from"node:fs";import{join as s}from"node:path";import{bashJobPaths as u,bashJobsDir as x,activeBackgroundBashJobs as E,expiredAutoBackgroundBashJobs as S,isBashJobProcessConfirmedGone as B,readJobPgid as N,readJobPgidIdentity as g,stopBackgroundBashJob as v}from"../../core/bash-jobs.js";import{killBashJobObject as J,recordBashJobObject as A}from"../../core/spaces/stop.js";import{createFileBeneath as I}from"../../core/spaces/open-beneath.js";import{withCanvasWrite as d}from"../../core/canvas/db.js";import{finishJob as j}from"../../core/graph/jobs.js";import{getById as l}from"../../core/graph/objects.js";import{isSafeNodeId as f}from"../../core/canvas/paths.js";import{contextDir as P}from"../../core/canvas/node-agent-paths.js";import{emitEvent as c}from"../../core/events/emit.js";import{operationIdContext as b}from"../../core/events/operation-id.js";import{isProfilePaused as k}from"../../core/profiles/manifest.js";const C=5*1e3;class q{static{p(this,"BashDeadlineReconciler")}lastScanAt=Number.NEGATIVE_INFINITY;startedAt=Date.now();async run(t,r){if(await this.publishExits(),!(t-this.lastScanAt<C)){this.lastScanAt=t;for(const e of r.rows){if(e.status==="dead"||k(e.profile_id))continue;const a=await P(e.node_id);let i;try{await this.adoptUnrecorded(e.node_id,a),await this.settleVanished(a),i=S(a,t)}catch(o){b.fresh(()=>{c({level:"error",event:"bash_deadline.scan_failed",...f(e.node_id)?{node_id:e.node_id}:{},error:o})});continue}for(const o of i)await this.cancel(e.node_id,a,o.jobId)}}}async publishExits(){try{await d(async t=>{const r=await t.prepare(`SELECT j.object, j.job_dir FROM jobs j JOIN objects o ON o.id = j.object
2
- WHERE j.status = 'running' AND o.deleted_at IS NULL`).all();for(const{object:e,job_dir:a}of r){const i=s(a,"job.exit");if(!n(i)||n(s(a,"job.stop")))continue;const o=Number(m(i,"utf8").trim());Number.isSafeInteger(o)&&await j(t,await l(t,e),{exitCode:o})}})}catch(t){b.fresh(()=>c({level:"error",event:"bash_completion.delivery_failed",error:t}))}}async adoptUnrecorded(t,r){let e;try{e=_(x(r))}catch{return}await d(async a=>{for(const i of e){if(await l(a,i)!==null)continue;const o=u(r,i);!n(o.jobBg)||!n(o.cmdSh)||n(o.jobExit)&&w(o.jobExit).mtimeMs<this.startedAt||await A(t,i,{command:m(o.cmdSh,"utf8"),jobDir:o.dir,logPath:o.jobLog})}})}async settleVanished(t){for(const{jobId:r}of E(t)){const e=u(t,r);n(e.jobExit)||n(s(e.dir,"job.stop"))||B(N(t,r),g(t,r))&&await d(async a=>{const i=await l(a,r);if(!(i===null||i.type!=="job")&&!(n(e.jobExit)||n(s(e.dir,"job.stop")))){await j(a,i,{killedBy:null,reason:"process disappeared without an exit record"});try{I(e.root,e.jobExit,`-1
3
- `)}catch(o){if(o.code!=="EEXIST")throw o}}})}}async cancel(t,r,e){(await v(r,e,!1,t)).kind==="stopped"&&await b.fresh(async()=>{try{c({level:"info",event:"bash_deadline.canceled",...f(t)?{node_id:t}:{},fields:{job_id:e}}),await J(e,async()=>null,"deadline")}catch(i){c({level:"error",event:"bash_deadline.notice_failed",...f(t)?{node_id:t}:{},error:i,fields:{job_id:e}})}})}}export{q as BashDeadlineReconciler};
1
+ var E=Object.defineProperty;var m=(s,t)=>E(s,"name",{value:t,configurable:!0});import{existsSync as a,readFileSync as S,readdirSync as x,statSync as B}from"node:fs";import{join as l}from"node:path";import{bashJobPaths as j,bashJobsDir as J,activeBackgroundBashJobs as v,expiredAutoBackgroundBashJobs as g,formatBashElapsed as M,isJobQuietOk as N,readJobActivity as I,readJobSilence as P,writeJobSilence as T,isBashJobProcessConfirmedGone as k,readJobPgid as C,readJobPgidIdentity as L,stopBackgroundBashJob as D}from"../../core/bash-jobs.js";import{killBashJobObject as O,recordBashJobObject as F}from"../../core/spaces/stop.js";import{createFileBeneath as R}from"../../core/spaces/open-beneath.js";import{withCanvasWrite as f}from"../../core/canvas/db.js";import{finishJob as A,jobRow as V}from"../../core/graph/jobs.js";import{publish as G}from"../../core/graph/events.js";import{envBashSilenceMs as U}from"../../shared/env.js";import{getById as h}from"../../core/graph/objects.js";import{isSafeNodeId as u}from"../../core/canvas/paths.js";import{contextDir as W}from"../../core/canvas/node-agent-paths.js";import{emitEvent as c}from"../../core/events/emit.js";import{operationIdContext as b}from"../../core/events/operation-id.js";import{isProfilePaused as X}from"../../core/profiles/manifest.js";const Y=300*1e3;function H(s,t,o){const e=s<o?0:s<2*o?o:s<4*o?2*o:4*o*Math.floor(s/(4*o));return e>t?e:null}m(H,"dueSilenceThresholdMs");const Q=5*1e3;class ft{static{m(this,"BashDeadlineReconciler")}lastScanAt=Number.NEGATIVE_INFINITY;startedAt=Date.now();async run(t,o){if(await this.publishExits(),!(t-this.lastScanAt<Q)){this.lastScanAt=t;for(const e of o.rows){if(e.status==="dead"||X(e.profile_id))continue;const r=await W(e.node_id);let i;try{await this.adoptUnrecorded(e.node_id,r),await this.settleVanished(r),i=g(r,t)}catch(n){b.fresh(()=>{c({level:"error",event:"bash_deadline.scan_failed",...u(e.node_id)?{node_id:e.node_id}:{},error:n})});continue}for(const n of i)await this.cancel(e.node_id,r,n.jobId);try{await this.warnSilent(r,t)}catch(n){b.fresh(()=>{c({level:"error",event:"bash_silence.scan_failed",...u(e.node_id)?{node_id:e.node_id}:{},error:n})})}}}}async warnSilent(t,o){const e=U();for(const{jobId:r}of v(t)){if(N(t,r))continue;const i=I(t,r);if(i===void 0||o-i.sampledAtMs>Y)continue;const n=o-i.lastActivityMs,y=P(t,r),_=H(n,y?.lastActivityMs===i.lastActivityMs?y.thresholdMs:0,e);if(_===null)continue;const w=j(t,r);await f(async p=>{const d=await h(p,r);d===null||d.type!=="job"||(await V(p,d))?.status!=="running"||await G(p,{event:"silent",object:d,actor:null,attrs:{"silent-for":M(n),files:i.files.join(", "),"log-path":w.jobLog}})}),T(w,i.lastActivityMs,_)}}async publishExits(){try{await f(async t=>{const o=await t.prepare(`SELECT j.object, j.job_dir FROM jobs j JOIN objects o ON o.id = j.object
2
+ WHERE j.status = 'running' AND o.deleted_at IS NULL`).all();for(const{object:e,job_dir:r}of o){const i=l(r,"job.exit");if(!a(i)||a(l(r,"job.stop")))continue;const n=Number(S(i,"utf8").trim());Number.isSafeInteger(n)&&await A(t,await h(t,e),{exitCode:n})}})}catch(t){b.fresh(()=>c({level:"error",event:"bash_completion.delivery_failed",error:t}))}}async adoptUnrecorded(t,o){let e;try{e=x(J(o))}catch{return}await f(async r=>{for(const i of e){if(await h(r,i)!==null)continue;const n=j(o,i);!a(n.jobBg)||!a(n.cmdSh)||a(n.jobExit)&&B(n.jobExit).mtimeMs<this.startedAt||await F(t,i,{command:S(n.cmdSh,"utf8"),jobDir:n.dir,logPath:n.jobLog})}})}async settleVanished(t){for(const{jobId:o}of v(t)){const e=j(t,o);a(e.jobExit)||a(l(e.dir,"job.stop"))||k(C(t,o),L(t,o))&&await f(async r=>{const i=await h(r,o);if(!(i===null||i.type!=="job")&&!(a(e.jobExit)||a(l(e.dir,"job.stop")))){await A(r,i,{killedBy:null,reason:"process disappeared without an exit record"});try{R(e.root,e.jobExit,`-1
3
+ `)}catch(n){if(n.code!=="EEXIST")throw n}}})}}async cancel(t,o,e){(await D(o,e,!1,t)).kind==="stopped"&&await b.fresh(async()=>{try{c({level:"info",event:"bash_deadline.canceled",...u(t)?{node_id:t}:{},fields:{job_id:e}}),await O(e,async()=>null,"deadline")}catch(i){c({level:"error",event:"bash_deadline.notice_failed",...u(t)?{node_id:t}:{},error:i,fields:{job_id:e}})}})}}export{ft as BashDeadlineReconciler,H as dueSilenceThresholdMs};
@@ -124,6 +124,10 @@ export declare function envTestUnattendedParkMs(): number | undefined;
124
124
  * above the configured knob a deployment sets to tune how long an eligible
125
125
  * resident idles before its parking turn. */
126
126
  export declare function envUnattendedParkMs(): number | undefined;
127
+ /** How long a background bash job must show no activity before its owner is first told
128
+ * (`CRTR_BASH_SILENCE_MS`, milliseconds; default 15 min). Later messages come at twice, four times,
129
+ * then every four times that. */
130
+ export declare function envBashSilenceMs(): number;
127
131
  /** Test-only park-summary grace-period override
128
132
  * (`CRTR_TEST_PARK_SUMMARY_GRACE_MS`); no production default. */
129
133
  export declare function envTestParkSummaryGraceMs(): number | undefined;
@@ -1,2 +1,2 @@
1
1
  var p=Object.defineProperty;var n=(e,r)=>p(e,"name",{value:r,configurable:!0});import{lstatSync as f,readFileSync as c,readdirSync as T}from"node:fs";import{join as i}from"node:path";import{covers as _}from"@north-light/identity";function W(){return process.env.CRTR_NODE_ID}n(W,"envNodeId");function d(e){for(const r of["broker-launch.json","cron-launch.json"]){const t=i(e,r);if(f(t,{throwIfNoEntry:!1})?.isFile())return t}}n(d,"launchSnapshotFile");function E(){if(process.platform==="linux")try{const e="/run/crtr/nodes",r=new Set(c("/proc/self/mountinfo","utf8").split(`
2
- `).map(o=>o.split(" ")[4])),t=T(e,{withFileTypes:!0}).filter(o=>o.isDirectory()&&/^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$/.test(o.name)&&r.has(i(e,o.name))&&d(i(e,o.name))!==void 0);return t.length===1?t[0].name:void 0}catch{return}}n(E,"sandboxCliNodeId");function F(){return E()!==void 0}n(F,"isSandboxedNode");function h(){return process.env.CRTR_GRANTEE}n(h,"envGrantee");const v="CRTR_INBOX_BETWEEN_TURNS";function H(){return process.env[v]==="1"}n(H,"envInboxBetweenTurns");const C="CRTR_SCOPES_FILE";function K(){const e=process.env[C];if(e!==void 0&&e!==""){const t=JSON.parse(c(e,"utf8"));if(!Array.isArray(t)||t.some(o=>typeof o!="string"))throw new Error(`invalid scopes file ${e}`);return t}const r=process.env.CRTR_SCOPES;return r===void 0?null:r===""?[]:r.split(",")}n(K,"envScopes");function G(e,r){return e==null?!0:a(e,r)}n(G,"scopeAllowed");function a(e,r){return e.includes(r)?(_(r,r),!0):e.some(t=>_(t,r))}n(a,"coveredByAny");function b(){return process.env.CRTR_EXECUTION_ID}n(b,"envExecutionId");function k(){return process.env.CRTR_PROFILE_ID}n(k,"envProfileId");function y(){return process.env.CRTR_NODE_CWD}n(y,"envNodeCwd");function w(){return process.env.CRTR_MODEL_INTENT}n(w,"envModelIntent");function g(){return process.env.CRTR_MODEL_EXACT==="1"}n(g,"envModelExact");function V(){return process.env.CRTR_HOME}n(V,"envHomeOverride");function X(){return process.env.CRTR_RUNTIME_HOME}n(X,"envRuntimeHomeOverride");function s(e,r){if(e===void 0)return r;const t=Number(e);return Number.isFinite(t)&&t>0?t:r}n(s,"parsePositiveMs");const A=5*6e4;function j(){return s(process.env.CRTR_STREAM_WATCHDOG_MS,A)}n(j,"envStreamWatchdogMs");const S=800;function Y(){return s(process.env.CRTR_WATCHER_TICK_MS,S)}n(Y,"envWatcherTickMs");const N=6e4;function $(){return s(process.env.CRTR_WATCHER_BACKSTOP_MS,N)}n($,"envWatcherBackstopMs");const M=1e3;function z(){return s(process.env.CRTR_WATCHER_DEBOUNCE_MS,M)}n(z,"envWatcherDebounceMs");const x=6e4;function Z(){return s(process.env.CRTR_RECAP_IDLE_MS,x)}n(Z,"envRecapIdleMs");function J(){const e=process.env.CRTR_RECAP_MODEL;return e!==void 0&&e.trim()!==""?e.trim():void 0}n(J,"envRecapModelOverride");const D=300*1e3;function q(){return s(process.env.CRTR_BASH_VALVE_MS,D)}n(q,"envBashValveMs");const O=60*1e3;function Q(){return s(process.env.CRTR_BASH_AUTO_BG_DEADLINE_MS,O)}n(Q,"envBashAutoBgDeadlineMs");function ee(){const e=process.env.CRTR_PIDFILE;return e!==void 0&&e!==""?e:void 0}n(ee,"envPidfileOverride");const m="@earendil-works/pi-coding-agent";function ne(){return process.env.CRTR_BROKER_ENGINE??m}n(ne,"envBrokerEngine");function re(){return process.env.CRTR_PI_BINARY}n(re,"envPiBinaryOverride");function te(){return process.env.CRTR_NO_DAEMON_AUTOSTART==="1"}n(te,"envNoDaemonAutostart");function oe(){const e=process.env.CRTR_DOCUMENT_PORT;if(e===void 0||!/^\d+$/.test(e))return;const r=Number(e);return r<=65535?r:void 0}n(oe,"envDocumentPort");function se(){return process.env.CRTRD_TCP}n(se,"envCrtrdTcp");function ue(){const e=process.env.CRTRD_TOKEN;return e!==void 0&&e!==""?e:void 0}n(ue,"envCrtrdToken");function ie(){return process.env.CRTR_NO_EXPORTS==="1"}n(ie,"envNoExports");function ce(){return process.env.CRTR_DEBUG==="1"}n(ce,"envDebug");function R(e){if(e===void 0||e==="")return;const r=Number(e);return Number.isSafeInteger(r)&&r>=1?r:void 0}n(R,"parsePositiveInteger");function _e(){return R(process.env.CRTR_MAX_LIVE_BROKERS)}n(_e,"envMaxLiveBrokers");function Re(){return R(process.env.CRTR_WARN_LIVE_BROKERS)}n(Re,"envWarnLiveBrokers");function u(e){if(e===void 0)return;const r=Number(e);return Number.isFinite(r)&&r>0?r:void 0}n(u,"parsePositiveMsNoDefault");function pe(){return u(process.env.CRTR_TEST_NODE_SOCKET_WINDOW_MS)}n(pe,"envTestNodeSocketWindowMs");function fe(){return u(process.env.CRTR_TEST_UNATTENDED_PARK_MS)}n(fe,"envTestUnattendedParkMs");function Te(){return u(process.env.CRTR_UNATTENDED_PARK_MS)}n(Te,"envUnattendedParkMs");function I(){return u(process.env.CRTR_TEST_PARK_SUMMARY_GRACE_MS)}n(I,"envTestParkSummaryGraceMs");const l=5*6e4;function de(){return I()??l}n(de,"parkSummaryGraceMs");export{v as INBOX_BETWEEN_TURNS_ENV,C as SCOPES_FILE_ENV,a as coveredByAny,Q as envBashAutoBgDeadlineMs,q as envBashValveMs,ne as envBrokerEngine,se as envCrtrdTcp,ue as envCrtrdToken,ce as envDebug,oe as envDocumentPort,b as envExecutionId,h as envGrantee,V as envHomeOverride,H as envInboxBetweenTurns,_e as envMaxLiveBrokers,g as envModelExact,w as envModelIntent,te as envNoDaemonAutostart,ie as envNoExports,y as envNodeCwd,W as envNodeId,re as envPiBinaryOverride,ee as envPidfileOverride,k as envProfileId,Z as envRecapIdleMs,J as envRecapModelOverride,X as envRuntimeHomeOverride,K as envScopes,j as envStreamWatchdogMs,pe as envTestNodeSocketWindowMs,I as envTestParkSummaryGraceMs,fe as envTestUnattendedParkMs,Te as envUnattendedParkMs,Re as envWarnLiveBrokers,$ as envWatcherBackstopMs,z as envWatcherDebounceMs,Y as envWatcherTickMs,F as isSandboxedNode,d as launchSnapshotFile,de as parkSummaryGraceMs,E as sandboxCliNodeId,G as scopeAllowed};
2
+ `).map(o=>o.split(" ")[4])),t=T(e,{withFileTypes:!0}).filter(o=>o.isDirectory()&&/^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$/.test(o.name)&&r.has(i(e,o.name))&&d(i(e,o.name))!==void 0);return t.length===1?t[0].name:void 0}catch{return}}n(E,"sandboxCliNodeId");function F(){return E()!==void 0}n(F,"isSandboxedNode");function h(){return process.env.CRTR_GRANTEE}n(h,"envGrantee");const v="CRTR_INBOX_BETWEEN_TURNS";function H(){return process.env[v]==="1"}n(H,"envInboxBetweenTurns");const C="CRTR_SCOPES_FILE";function K(){const e=process.env[C];if(e!==void 0&&e!==""){const t=JSON.parse(c(e,"utf8"));if(!Array.isArray(t)||t.some(o=>typeof o!="string"))throw new Error(`invalid scopes file ${e}`);return t}const r=process.env.CRTR_SCOPES;return r===void 0?null:r===""?[]:r.split(",")}n(K,"envScopes");function G(e,r){return e==null?!0:a(e,r)}n(G,"scopeAllowed");function a(e,r){return e.includes(r)?(_(r,r),!0):e.some(t=>_(t,r))}n(a,"coveredByAny");function b(){return process.env.CRTR_EXECUTION_ID}n(b,"envExecutionId");function k(){return process.env.CRTR_PROFILE_ID}n(k,"envProfileId");function y(){return process.env.CRTR_NODE_CWD}n(y,"envNodeCwd");function w(){return process.env.CRTR_MODEL_INTENT}n(w,"envModelIntent");function g(){return process.env.CRTR_MODEL_EXACT==="1"}n(g,"envModelExact");function V(){return process.env.CRTR_HOME}n(V,"envHomeOverride");function X(){return process.env.CRTR_RUNTIME_HOME}n(X,"envRuntimeHomeOverride");function s(e,r){if(e===void 0)return r;const t=Number(e);return Number.isFinite(t)&&t>0?t:r}n(s,"parsePositiveMs");const S=5*6e4;function j(){return s(process.env.CRTR_STREAM_WATCHDOG_MS,S)}n(j,"envStreamWatchdogMs");const A=800;function Y(){return s(process.env.CRTR_WATCHER_TICK_MS,A)}n(Y,"envWatcherTickMs");const M=6e4;function $(){return s(process.env.CRTR_WATCHER_BACKSTOP_MS,M)}n($,"envWatcherBackstopMs");const N=1e3;function z(){return s(process.env.CRTR_WATCHER_DEBOUNCE_MS,N)}n(z,"envWatcherDebounceMs");const x=6e4;function Z(){return s(process.env.CRTR_RECAP_IDLE_MS,x)}n(Z,"envRecapIdleMs");function J(){const e=process.env.CRTR_RECAP_MODEL;return e!==void 0&&e.trim()!==""?e.trim():void 0}n(J,"envRecapModelOverride");const D=300*1e3;function q(){return s(process.env.CRTR_BASH_VALVE_MS,D)}n(q,"envBashValveMs");const O=60*1e3;function Q(){return s(process.env.CRTR_BASH_AUTO_BG_DEADLINE_MS,O)}n(Q,"envBashAutoBgDeadlineMs");function ee(){const e=process.env.CRTR_PIDFILE;return e!==void 0&&e!==""?e:void 0}n(ee,"envPidfileOverride");const I="@earendil-works/pi-coding-agent";function ne(){return process.env.CRTR_BROKER_ENGINE??I}n(ne,"envBrokerEngine");function re(){return process.env.CRTR_PI_BINARY}n(re,"envPiBinaryOverride");function te(){return process.env.CRTR_NO_DAEMON_AUTOSTART==="1"}n(te,"envNoDaemonAutostart");function oe(){const e=process.env.CRTR_DOCUMENT_PORT;if(e===void 0||!/^\d+$/.test(e))return;const r=Number(e);return r<=65535?r:void 0}n(oe,"envDocumentPort");function se(){return process.env.CRTRD_TCP}n(se,"envCrtrdTcp");function ue(){const e=process.env.CRTRD_TOKEN;return e!==void 0&&e!==""?e:void 0}n(ue,"envCrtrdToken");function ie(){return process.env.CRTR_NO_EXPORTS==="1"}n(ie,"envNoExports");function ce(){return process.env.CRTR_DEBUG==="1"}n(ce,"envDebug");function R(e){if(e===void 0||e==="")return;const r=Number(e);return Number.isSafeInteger(r)&&r>=1?r:void 0}n(R,"parsePositiveInteger");function _e(){return R(process.env.CRTR_MAX_LIVE_BROKERS)}n(_e,"envMaxLiveBrokers");function Re(){return R(process.env.CRTR_WARN_LIVE_BROKERS)}n(Re,"envWarnLiveBrokers");function u(e){if(e===void 0)return;const r=Number(e);return Number.isFinite(r)&&r>0?r:void 0}n(u,"parsePositiveMsNoDefault");function pe(){return u(process.env.CRTR_TEST_NODE_SOCKET_WINDOW_MS)}n(pe,"envTestNodeSocketWindowMs");function fe(){return u(process.env.CRTR_TEST_UNATTENDED_PARK_MS)}n(fe,"envTestUnattendedParkMs");function Te(){return u(process.env.CRTR_UNATTENDED_PARK_MS)}n(Te,"envUnattendedParkMs");function de(){return u(process.env.CRTR_BASH_SILENCE_MS)??15*6e4}n(de,"envBashSilenceMs");function l(){return u(process.env.CRTR_TEST_PARK_SUMMARY_GRACE_MS)}n(l,"envTestParkSummaryGraceMs");const m=5*6e4;function Ee(){return l()??m}n(Ee,"parkSummaryGraceMs");export{v as INBOX_BETWEEN_TURNS_ENV,C as SCOPES_FILE_ENV,a as coveredByAny,Q as envBashAutoBgDeadlineMs,de as envBashSilenceMs,q as envBashValveMs,ne as envBrokerEngine,se as envCrtrdTcp,ue as envCrtrdToken,ce as envDebug,oe as envDocumentPort,b as envExecutionId,h as envGrantee,V as envHomeOverride,H as envInboxBetweenTurns,_e as envMaxLiveBrokers,g as envModelExact,w as envModelIntent,te as envNoDaemonAutostart,ie as envNoExports,y as envNodeCwd,W as envNodeId,re as envPiBinaryOverride,ee as envPidfileOverride,k as envProfileId,Z as envRecapIdleMs,J as envRecapModelOverride,X as envRuntimeHomeOverride,K as envScopes,j as envStreamWatchdogMs,pe as envTestNodeSocketWindowMs,l as envTestParkSummaryGraceMs,fe as envTestUnattendedParkMs,Te as envUnattendedParkMs,Re as envWarnLiveBrokers,$ as envWatcherBackstopMs,z as envWatcherDebounceMs,Y as envWatcherTickMs,F as isSandboxedNode,d as launchSnapshotFile,Ee as parkSummaryGraceMs,E as sandboxCliNodeId,G as scopeAllowed};
@@ -1,10 +1,10 @@
1
- var w=Object.defineProperty;var i=(e,t)=>w(e,"name",{value:t,configurable:!0});import{formatInboxRefInstruction as $}from"./generated-context.js";const f=12,l=1e3,y=1e3;function k(e){return(e===void 0?null:/^([a-z0-9-]+)\/reports\/[^/]+$/.exec(e))?.[1]}i(k,"reportRefNodeId");function x(e){let t=e,r=!1;const o=t.split(`
2
- `);return o.length>f&&(t=o.slice(0,f).join(`
3
- `),r=!0),t.length>l&&(t=t.slice(0,l),r=!0),{text:t.trimEnd(),clipped:r}}i(x,"clipBody");function j(e){const t=typeof e.data?.body=="string"?String(e.data.body).trim():"";return t===""||t===e.label?"":t}i(j,"inlineBody");function v(e){const t=e.data?.push;return typeof t=="object"&&t!==null&&typeof t.event=="string"?t:null}i(v,"pushOf");function u(e){const t=e.owner_handle??e.owner;return t==null?e.name:`${t}/${e.name}`}i(u,"objectRef");function _(e){return e.type==="document"?`[[${u(e)}]]`:e.type==="job"?`job ${e.id} (\`${e.name}\`)`:e.type==="node"?`node ${e.name} (${e.id})${e.machine?` on ${e.machine}`:""}`:`${e.type} ${e.name}`}i(_,"objectText");function R(e,t){return t.actor===null?"the runtime":e.from_name===void 0||e.from_name===t.actor?t.actor:`${e.from_name} (${t.actor})`}i(R,"actorText");function m(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}i(m,"list");function A(e,t){const r=_(t.object),o=R(e,t),n=t.attrs,a=t.object.type==="document"?` Read it with \`crtr canvas read ${u(t.object)}\`.`:"";switch(t.event){case"created":return t.object.type==="node"?`${o} created ${r}${typeof n.kind=="string"?`, kind ${n.kind}`:""}.`:`${o} created ${r}.${a}`;case"read":return`${o} read ${r}.`;case"watched":return`${o} started watching ${r}.`;case"deleted":return`${o} deleted ${r}.`;case"edited":{const c=m(n.authors),s=m(n.rationales),d=typeof n.from_revision=="number"&&typeof n.revision=="number"&&n.revision-n.from_revision>1?`revisions ${n.from_revision+1}\u2013${n.revision}`:typeof n.revision=="number"?`revision ${n.revision}`:"a new revision",g=c.length===0?o:c.join(", "),b=s.length===0?"":` Rationale: ${s.join("; ")}.`,p=n.needs_merge===!0?" Two edits were made from the same revision; read it and edit it to merge them.":"",h=` You get this because you read or wrote it; if it no longer concerns your work, stop with \`crtr canvas unwatch ${u(t.object)}\`.`;return`${g} edited ${r} (${d}).${b}${p}${a}${h}`}case"messaged":return`${o} messaged ${r}.`;case"sent":return`${o} sent a message as ${r}.`;case"configured":return`${o} changed the settings of ${r}${typeof n.changed=="string"?`: ${n.changed}`:""}.`;case"exited":return`${r[0].toUpperCase()}${r.slice(1)} exited with code ${String(n["exit-code"])}. Log: ${String(n["log-path"])}`;case"killed":{const c=t.actor===null?"":` by ${o}`,s=typeof n.reason=="string"?` (${n.reason})`:"",d=n.reason==="deadline"?` It was canceled at its deadline; claim it with \`crtr node bash extend ${t.object.id} --for <duration>\` next time.`:"";return`${r[0].toUpperCase()}${r.slice(1)} was killed${c}${s}.${d} Log: ${String(n["log-path"])}`}default:return e.label}}i(A,"renderPush");function E(e,t){if(t!==null&&t.length<y&&e.ref!==void 0)return`${t.trimEnd()}
1
+ var w=Object.defineProperty;var i=(e,t)=>w(e,"name",{value:t,configurable:!0});import{formatInboxRefInstruction as l}from"./generated-context.js";const $=12,u=1e3,y=1e3;function A(e){return(e===void 0?null:/^([a-z0-9-]+)\/reports\/[^/]+$/.exec(e))?.[1]}i(A,"reportRefNodeId");function j(e){let t=e,r=!1;const o=t.split(`
2
+ `);return o.length>$&&(t=o.slice(0,$).join(`
3
+ `),r=!0),t.length>u&&(t=t.slice(0,u),r=!0),{text:t.trimEnd(),clipped:r}}i(j,"clipBody");function x(e){const t=typeof e.data?.body=="string"?String(e.data.body).trim():"";return t===""||t===e.label?"":t}i(x,"inlineBody");function v(e){const t=e.data?.push;return typeof t=="object"&&t!==null&&typeof t.event=="string"?t:null}i(v,"pushOf");function f(e){const t=e.owner_handle??e.owner;return t==null?e.name:`${t}/${e.name}`}i(f,"objectRef");function _(e){return e.type==="document"?`[[${f(e)}]]`:e.type==="job"?`job ${e.id} (\`${e.name}\`)`:e.type==="node"?`node ${e.name} (${e.id})${e.machine?` on ${e.machine}`:""}`:`${e.type} ${e.name}`}i(_,"objectText");function I(e,t){return t.actor===null?"the runtime":e.from_name===void 0||e.from_name===t.actor?t.actor:`${e.from_name} (${t.actor})`}i(I,"actorText");function m(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}i(m,"list");function R(e,t){const r=_(t.object),o=I(e,t),n=t.attrs,a=t.object.type==="document"?` Read it with \`crtr canvas read ${f(t.object)}\`.`:"";switch(t.event){case"created":return t.object.type==="node"?`${o} created ${r}${typeof n.kind=="string"?`, kind ${n.kind}`:""}.`:`${o} created ${r}.${a}`;case"read":return`${o} read ${r}.`;case"watched":return`${o} started watching ${r}.`;case"deleted":return`${o} deleted ${r}.`;case"edited":{const s=m(n.authors),c=m(n.rationales),d=typeof n.from_revision=="number"&&typeof n.revision=="number"&&n.revision-n.from_revision>1?`revisions ${n.from_revision+1}\u2013${n.revision}`:typeof n.revision=="number"?`revision ${n.revision}`:"a new revision",g=s.length===0?o:s.join(", "),h=c.length===0?"":` Rationale: ${c.join("; ")}.`,b=n.needs_merge===!0?" Two edits were made from the same revision; read it and edit it to merge them.":"",p=` You get this because you read or wrote it; if it no longer concerns your work, stop with \`crtr canvas unwatch ${f(t.object)}\`.`;return`${g} edited ${r} (${d}).${h}${b}${a}${p}`}case"messaged":return`${o} messaged ${r}.`;case"sent":return`${o} sent a message as ${r}.`;case"configured":return`${o} changed the settings of ${r}${typeof n.changed=="string"?`: ${n.changed}`:""}.`;case"exited":return`${r[0].toUpperCase()}${r.slice(1)} exited with code ${String(n["exit-code"])}. Log: ${String(n["log-path"])}`;case"silent":{const s=typeof n.files=="string"?n.files:"";return`${r[0].toUpperCase()}${r.slice(1)} has been silent for ${String(n["silent-for"])}: its processes used almost no CPU and none of the files they hold open for writing changed. It may be hung. Watched: ${s===""?"the job log only":s}. Inspect those files; stop it with \`crtr node bash kill ${t.object.id}\`; or, if it is meant to sit idle, stop these messages with \`crtr node bash quiet ${t.object.id}\`.`}case"killed":{const s=t.actor===null?"":` by ${o}`,c=typeof n.reason=="string"?` (${n.reason})`:"",d=n.reason==="deadline"?` It was canceled at its deadline; claim it with \`crtr node bash extend ${t.object.id} --for <duration>\` next time.`:"";return`${r[0].toUpperCase()}${r.slice(1)} was killed${s}${c}.${d} Log: ${String(n["log-path"])}`}default:return e.label}}i(R,"renderPush");function C(e,t){if(t!==null&&t.length<y&&e.ref!==void 0)return`${t.trimEnd()}
4
4
 
5
- ${$(e.ref)}`;const r=j(e);if(r===""){const a=v(e);return a!==null&&e.ref===void 0?A(e,a):e.ref===void 0?e.label:`${e.label}
5
+ ${l(e.ref)}`;const r=x(e);if(r===""){const a=v(e);return a!==null&&e.ref===void 0?R(e,a):e.ref===void 0?e.label:`${e.label}
6
6
 
7
- ${$(e.ref)}`}const{text:o,clipped:n}=x(r);return e.ref!==void 0?`${o}
7
+ ${l(e.ref)}`}const{text:o,clipped:n}=j(r);return e.ref!==void 0?`${o}
8
8
 
9
- ${$(e.ref)}`:n?`${o}
10
- \u2026 (body clipped)`:o}i(E,"renderEntryBody");export{y as INLINE_REPORT_MAX_CHARS,x as clipBody,j as inlineBody,E as renderEntryBody,k as reportRefNodeId};
9
+ ${l(e.ref)}`:n?`${o}
10
+ \u2026 (body clipped)`:o}i(C,"renderEntryBody");export{y as INLINE_REPORT_MAX_CHARS,j as clipBody,x as inlineBody,C as renderEntryBody,A as reportRefNodeId};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.556",
3
+ "version": "0.3.558",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -141,7 +141,7 @@
141
141
  },
142
142
  "license": "UNLICENSED",
143
143
  "dependencies": {
144
- "@north-light/identity": "0.3.556",
144
+ "@north-light/identity": "0.3.558",
145
145
  "@earendil-works/pi-agent-core": "1.1.0",
146
146
  "@earendil-works/pi-ai": "1.1.0",
147
147
  "@earendil-works/pi-coding-agent": "1.1.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/identity",
3
- "version": "0.3.556",
3
+ "version": "0.3.558",
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.556",
3
+ "version": "0.3.558",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/cli",
9
- "version": "0.3.556",
9
+ "version": "0.3.558",
10
10
  "hasInstallScript": true,
11
11
  "license": "UNLICENSED",
12
12
  "workspaces": [
@@ -24,7 +24,7 @@
24
24
  "@milkdown/preset-gfm": "^7.22.3",
25
25
  "@milkdown/prose": "^7.22.3",
26
26
  "@milkdown/utils": "^7.22.3",
27
- "@north-light/identity": "0.3.556",
27
+ "@north-light/identity": "0.3.558",
28
28
  "cron-parser": "^5.6.0",
29
29
  "esbuild": "^0.27.7",
30
30
  "jose": "^6.2.12",
@@ -12455,17 +12455,17 @@
12455
12455
  },
12456
12456
  "packages/crouter-api": {
12457
12457
  "name": "@north-light/api",
12458
- "version": "0.3.556",
12458
+ "version": "0.3.558",
12459
12459
  "license": "UNLICENSED"
12460
12460
  },
12461
12461
  "packages/crouter-env-docker": {
12462
12462
  "name": "@north-light/env-docker",
12463
- "version": "0.3.556",
12463
+ "version": "0.3.558",
12464
12464
  "license": "UNLICENSED"
12465
12465
  },
12466
12466
  "packages/crouter-identity": {
12467
12467
  "name": "@north-light/identity",
12468
- "version": "0.3.556",
12468
+ "version": "0.3.558",
12469
12469
  "license": "UNLICENSED",
12470
12470
  "dependencies": {
12471
12471
  "jose": "^6.2.1"
@@ -12473,21 +12473,21 @@
12473
12473
  },
12474
12474
  "packages/crouter-plugin": {
12475
12475
  "name": "@north-light/plugin",
12476
- "version": "0.3.556",
12476
+ "version": "0.3.558",
12477
12477
  "license": "UNLICENSED",
12478
12478
  "dependencies": {
12479
- "@north-light/api": "0.3.556",
12480
- "@north-light/identity": "0.3.556"
12479
+ "@north-light/api": "0.3.558",
12480
+ "@north-light/identity": "0.3.558"
12481
12481
  }
12482
12482
  },
12483
12483
  "packages/crouter-sdk": {
12484
12484
  "name": "@north-light/sdk",
12485
- "version": "0.3.556",
12485
+ "version": "0.3.558",
12486
12486
  "license": "UNLICENSED",
12487
12487
  "dependencies": {
12488
- "@north-light/api": "0.3.556",
12489
- "@north-light/identity": "0.3.556",
12490
- "@north-light/plugin": "0.3.556",
12488
+ "@north-light/api": "0.3.558",
12489
+ "@north-light/identity": "0.3.558",
12490
+ "@north-light/plugin": "0.3.558",
12491
12491
  "jose": "^6.2.1"
12492
12492
  },
12493
12493
  "bin": {