@north-light/cli 0.3.580 → 0.3.582
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.
- package/dist/api/client.d.ts +6 -1
- package/dist/api/client.js +3 -3
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/execution-start.d.ts +14 -0
- package/dist/api/dto/health.d.ts +22 -0
- package/dist/api/dto/imports.d.ts +142 -0
- package/dist/api/dto/imports.js +0 -0
- package/dist/api/error-codes.d.ts +5 -0
- package/dist/api/error-codes.js +1 -1
- package/dist/api/errors.js +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +2 -0
- package/dist/api/routes.js +1 -1
- package/dist/build-root.d.ts +11 -4
- package/dist/build-root.js +1 -1
- package/dist/cli.js +7 -7
- package/dist/clients/attach/session/connection.d.ts +3 -1
- package/dist/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/viewer.js +529 -529
- package/dist/commands/api-client.d.ts +12 -4
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/sys/daemon.js +1 -1
- package/dist/commands/sys/desktop.d.ts +5 -0
- package/dist/commands/sys/desktop.js +1 -0
- package/dist/commands/sys/import/move.d.ts +55 -0
- package/dist/commands/sys/import/move.js +8 -0
- package/dist/commands/sys/import/resume.d.ts +1 -0
- package/dist/commands/sys/import/resume.js +1 -0
- package/dist/commands/sys/import/start.d.ts +4 -0
- package/dist/commands/sys/import/start.js +1 -0
- package/dist/commands/sys/join.d.ts +2 -0
- package/dist/commands/sys/join.js +1 -1
- package/dist/commands/sys/machine/rotate.d.ts +1 -0
- package/dist/commands/sys/machine/rotate.js +1 -0
- package/dist/commands/sys/signin.d.ts +7 -0
- package/dist/commands/sys/signin.js +2 -0
- package/dist/commands/sys.js +1 -1
- package/dist/core/blobs/r2.d.ts +4 -0
- package/dist/core/blobs/r2.js +7 -4
- package/dist/core/canvas/daemon-owner.d.ts +1 -1
- package/dist/core/canvas/executions.d.ts +1 -1
- package/dist/core/canvas/node-tokens.d.ts +2 -0
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/pid.d.ts +6 -0
- package/dist/core/canvas/pid.js +5 -5
- package/dist/core/command-plugins/compose.js +1 -1
- package/dist/core/command.d.ts +17 -8
- package/dist/core/command.js +9 -9
- package/dist/core/directory/issuer.d.ts +3 -0
- package/dist/core/directory/issuer.js +1 -1
- package/dist/core/directory/person-credential.d.ts +61 -0
- package/dist/core/directory/person-credential.js +1 -0
- package/dist/core/directory/reach.d.ts +3 -0
- package/dist/core/directory/reach.js +1 -0
- package/dist/core/grants/mirror.d.ts +3 -0
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/graph/bodies-boot-copy.d.ts +16 -2
- package/dist/core/graph/bodies-boot-copy.js +1 -1
- package/dist/core/graph/bodies.d.ts +13 -4
- package/dist/core/graph/bodies.js +1 -1
- package/dist/core/graph/deletion.d.ts +4 -1
- package/dist/core/graph/deletion.js +3 -3
- package/dist/core/graph/documents.d.ts +4 -0
- package/dist/core/graph/documents.js +9 -9
- package/dist/core/graph/reader.js +2 -2
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/repo-sync/ref-format.d.ts +7 -2
- package/dist/core/graph/repo-sync/ref-format.js +2 -2
- package/dist/core/import/bundle/blob-keys.d.ts +10 -0
- package/dist/core/import/bundle/blob-keys.js +1 -0
- package/dist/core/import/bundle/layout.d.ts +90 -0
- package/dist/core/import/bundle/layout.js +5 -0
- package/dist/core/import/export/archive.d.ts +11 -0
- package/dist/core/import/export/archive.js +1 -0
- package/dist/core/import/export/cloud.d.ts +23 -0
- package/dist/core/import/export/cloud.js +1 -0
- package/dist/core/import/export/dump.d.ts +34 -0
- package/dist/core/import/export/dump.js +3 -0
- package/dist/core/import/export/files.d.ts +22 -0
- package/dist/core/import/export/files.js +1 -0
- package/dist/core/import/export/inline.d.ts +3 -0
- package/dist/core/import/export/inline.js +1 -0
- package/dist/core/import/export/source.d.ts +2 -0
- package/dist/core/import/export/source.js +1 -0
- package/dist/core/import/export/stores.d.ts +9 -0
- package/dist/core/import/export/stores.js +1 -0
- package/dist/core/import/load/bind.d.ts +19 -0
- package/dist/core/import/load/bind.js +15 -0
- package/dist/core/import/load/blobs.d.ts +10 -0
- package/dist/core/import/load/blobs.js +1 -0
- package/dist/core/import/load/catalog.d.ts +32 -0
- package/dist/core/import/load/catalog.js +9 -0
- package/dist/core/import/load/copy.d.ts +26 -0
- package/dist/core/import/load/copy.js +6 -0
- package/dist/core/import/load/path-map.d.ts +7 -0
- package/dist/core/import/load/path-map.js +1 -0
- package/dist/core/import/load/prepare.d.ts +37 -0
- package/dist/core/import/load/prepare.js +10 -0
- package/dist/core/import/load/rewrite.d.ts +39 -0
- package/dist/core/import/load/rewrite.js +13 -0
- package/dist/core/import/load/rollback.d.ts +3 -0
- package/dist/core/import/load/rollback.js +6 -0
- package/dist/core/import/load/run.d.ts +22 -0
- package/dist/core/import/load/run.js +3 -0
- package/dist/core/import/load/stage.d.ts +15 -0
- package/dist/core/import/load/stage.js +1 -0
- package/dist/core/import/load/stores.d.ts +24 -0
- package/dist/core/import/load/stores.js +2 -0
- package/dist/core/import/load/verify.d.ts +4 -0
- package/dist/core/import/load/verify.js +12 -0
- package/dist/core/io.js +4 -4
- package/dist/core/northlight/previews.d.ts +22 -0
- package/dist/core/northlight/previews.js +1 -0
- package/dist/core/providers/call.js +1 -1
- package/dist/core/providers/device.js +1 -1
- package/dist/core/providers/files.d.ts +2 -1
- package/dist/core/providers/files.js +1 -1
- package/dist/core/runtime/broker/cli-relay.js +1 -1
- package/dist/core/runtime/broker/model-adapter.js +3 -3
- package/dist/core/runtime/broker-ownership.d.ts +1 -0
- package/dist/core/runtime/broker-ownership.js +1 -0
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/first-run-offer.d.ts +7 -2
- package/dist/core/runtime/first-run-offer.js +10 -2
- package/dist/core/runtime/front-door.js +4 -4
- package/dist/core/runtime/revive.d.ts +5 -2
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/runner/blaxel/runner.js +3 -3
- package/dist/core/runtime/runner/index.d.ts +1 -0
- package/dist/core/runtime/runner/index.js +1 -1
- package/dist/core/runtime/runner/machine/call.d.ts +8 -0
- package/dist/core/runtime/runner/machine/call.js +3 -0
- package/dist/core/runtime/runner/machine/environment.d.ts +1 -0
- package/dist/core/runtime/runner/machine/environment.js +1 -0
- package/dist/core/runtime/runner/machine/executor.d.ts +29 -0
- package/dist/core/runtime/runner/machine/executor.js +1 -0
- package/dist/core/runtime/runner/machine/machine-executor.test.d.ts +1 -0
- package/dist/core/runtime/runner/machine/machine-executor.test.js +4 -0
- package/dist/core/runtime/runner/machine/ops.d.ts +127 -0
- package/dist/core/runtime/runner/machine/ops.js +1 -0
- package/dist/core/runtime/runner/machine/runner.d.ts +12 -0
- package/dist/core/runtime/runner/machine/runner.js +1 -0
- package/dist/core/runtime/runner/types.d.ts +7 -1
- package/dist/core/runtime/warm-pool.d.ts +2 -0
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/secrets/env-rows.d.ts +1 -0
- package/dist/core/secrets/env-rows.js +1 -1
- package/dist/core/storage/purge.d.ts +6 -0
- package/dist/core/storage/purge.js +4 -0
- package/dist/core/subscription-state.d.ts +1 -0
- package/dist/core/subscription-state.js +1 -1
- package/dist/daemon/api/bridge.js +3 -3
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/execution-start.js +2 -2
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/imports.d.ts +2 -0
- package/dist/daemon/api/handlers/imports.js +1 -0
- package/dist/daemon/api/handlers/machine-credential.d.ts +2 -0
- package/dist/daemon/api/handlers/machine-credential.js +1 -0
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/import-auth.d.ts +6 -0
- package/dist/daemon/api/import-auth.js +1 -0
- package/dist/daemon/api/operations.d.ts +2 -2
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/router.d.ts +7 -1
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/boot-migrations.js +1 -1
- package/dist/daemon/broker-signals/bus.d.ts +3 -2
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/cron/armed-context.d.ts +1 -0
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/closed.d.ts +31 -0
- package/dist/daemon/cron/closed.js +1 -0
- package/dist/daemon/cron/ended.js +2 -2
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/machine-exec.d.ts +11 -0
- package/dist/daemon/cron/machine-exec.js +1 -0
- package/dist/daemon/cron/machine-fire.d.ts +26 -0
- package/dist/daemon/cron/machine-fire.js +1 -0
- package/dist/daemon/cron/recurrence.d.ts +14 -0
- package/dist/daemon/cron/recurrence.js +1 -0
- package/dist/daemon/cron/run-token.d.ts +7 -0
- package/dist/daemon/cron/run-token.js +1 -0
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.d.ts +3 -3
- package/dist/daemon/crtrd.js +14 -14
- package/dist/daemon/drain.d.ts +25 -0
- package/dist/daemon/drain.js +9 -0
- package/dist/daemon/due-sources.d.ts +1 -1
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.js +8 -8
- package/dist/daemon/fleet.js +5 -5
- package/dist/daemon/import-dump-run.d.ts +1 -0
- package/dist/daemon/import-dump-run.js +5 -0
- package/dist/daemon/machine-daemon.d.ts +10 -0
- package/dist/daemon/machine-daemon.js +1 -0
- package/dist/daemon/machine-link/client.d.ts +29 -0
- package/dist/daemon/machine-link/client.js +1 -0
- package/dist/daemon/machine-link/config.d.ts +45 -0
- package/dist/daemon/machine-link/config.js +3 -0
- package/dist/daemon/machine-link/credential.d.ts +7 -0
- package/dist/daemon/machine-link/credential.js +2 -0
- package/dist/daemon/machine-link/forward.d.ts +16 -0
- package/dist/daemon/machine-link/forward.js +1 -0
- package/dist/daemon/machine-link/frames.d.ts +49 -0
- package/dist/daemon/machine-link/frames.js +1 -0
- package/dist/daemon/machine-link/holder.d.ts +73 -0
- package/dist/daemon/machine-link/holder.js +9 -0
- package/dist/daemon/machine-link/move-notify.d.ts +4 -0
- package/dist/daemon/machine-link/move-notify.js +1 -0
- package/dist/daemon/manage.d.ts +19 -3
- package/dist/daemon/manage.js +3 -3
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/daemon/reconcilers/import-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/import-lane.js +1 -0
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +3 -0
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/purge-due-work.d.ts +13 -0
- package/dist/daemon/reconcilers/purge-due-work.js +1 -0
- package/dist/daemon/reconcilers/row-claim.d.ts +1 -0
- package/dist/daemon/reconcilers/row-claim.js +2 -2
- package/dist/daemon/runs/observer.js +3 -3
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/scripts/sandbox-start.mjs +185 -2
package/dist/daemon/manage.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`).at(-1)??"";return JSON.parse(
|
|
3
|
-
${r}`),this.name="DaemonExitedBeforeReadyError",this.stderrTail=r}}class
|
|
1
|
+
var X=Object.defineProperty;var o=(e,t)=>X(e,"name",{value:t,configurable:!0});import{spawn as B,execFileSync as q}from"node:child_process";import{createRequire as V}from"node:module";import{dirname as k,join as D}from"node:path";import{fileURLToPath as Q,pathToFileURL as I}from"node:url";import{existsSync as H,lstatSync as Z,mkdirSync as ee,openSync as U,closeSync as j,fstatSync as K,readSync as te}from"node:fs";import{crtrHome as g}from"../core/canvas/paths.js";import{listProcessTable as re}from"../core/canvas/pid.js";import{bindDaemonEventSource as ne,eventSource as oe}from"../core/events/source.js";import{hostExecPath as O}from"../core/runtime/branded-host.js";import{isDaemonRunning as ae,readPidfile as E,isPidAlive as f}from"./pidfile.js";import{DAEMON_STARTUP_WINDOW_MS as G}from"./startup-policy.js";import{exclusiveLockOwnerPid as ie}from"../core/exclusive-lock.js";import{onDiskMigrationLockPath as se}from"../core/canvas/paths.js";import{envNoDaemonAutostart as ce}from"../shared/env.js";import{awaitJoinLockRelease as ue,joinInProgress as le,joinInProgressError as de,joinLockHolder as pe}from"../core/directory/join-lock.js";import{waitForDaemonAvailability as fe}from"../api/index.js";import{localClient as me}from"../api/node-transport.js";const he=["CRTR_NODE_ID","CRTR_KIND","CRTR_MODE","CRTR_LIFECYCLE","CRTR_NODE_CWD","CRTR_CONTEXT_DIR","CRTR_CYCLES","CRTR_PROFILE_ID","CRTR_PARENT_NODE_ID","CRTR_FRONT_DOOR","TMUX","TMUX_PANE","CRTR_BROKER_ENGINE","CRTR_PI_BINARY","NODE_OPTIONS"];function M(){const e={...process.env};for(const t of he)delete e[t];return e}o(M,"sanitizedDaemonEnv");function we(){for(let e=k(Q(import.meta.url));;e=k(e)){if(H(D(e,"bin","runtime-generation-manifest.mjs")))return e;if(k(e)===e)throw new Error(`cannot locate the crouter generation root from ${import.meta.url}`)}}o(we,"generationRoot");async function A(){const e=we(),t=I(D(e,"bin","runtime-generation-manifest.mjs")).href,{runtimeHome:r}=await import(t);try{Z(D(r(),"selected"))}catch(s){if(s.code!=="ENOENT")throw s;return["--conditions","crtr-src","--import",I(V(import.meta.url).resolve("tsx/esm")).href,D(e,"src","daemon","crtrd-cli.ts")]}const n=I(D(e,"bin","runtime-selector.mjs")).href,{tryResolveRuntime:a}=await import(n),c=a("daemon");if(!c.ok)throw new Error(`cannot resolve the selected runtime generation's daemon entry: ${c.error}`);return[c.runtime.entryPath]}o(A,"resolveDaemonLaunch");function _e(e,t){return e.includes(` --canvas-home ${t} `)||e.endsWith(` --canvas-home ${t}`)}o(_e,"daemonCommandDeclaresCanvasHome");function De(){const e=re();if(e===null)return[];const t=g(),r=[];for(const{pid:n,command:a}of e)a.includes("daemon/crtrd")&&_e(a,t)&&n!==process.pid&&r.push(n);return r}o(De,"findDaemonPids");function Ee(e){const t=De().filter(n=>n!==e);for(const n of t)try{process.kill(n,"SIGTERM")}catch{}if(t.length===0)return t;const r=Date.now()+2e3;for(;Date.now()<r&&t.some(n=>f(n));)q("sleep",["0.1"]);for(const n of t)if(f(n))try{process.kill(n,"SIGKILL")}catch{}return t}o(Ee,"sweepStrayDaemons");async function Ve(){const e=process.execve;if(e===void 0)throw new Error(`this Node.js ${process.version} runtime cannot replace PID 1 with the successor daemon`);const t=O(),r=await A();return e(t,[t,...r,"--canvas-home",g()],M())}o(Ve,"execDaemon");async function R(e){const t=await A(),r=B(O(),[...t,...e],{stdio:["ignore","pipe","pipe"],env:M()});let n="",a="";r.stdout.setEncoding("utf8").on("data",u=>{n+=u}),r.stderr.setEncoding("utf8").on("data",u=>{a+=u});const c=await new Promise((u,m)=>{r.once("error",m),r.once("close",p=>u(p))});if(c!==0)throw new Error(a.trim()||`the ${e[0]} process exited with code ${c}`);const s=n.trim().split(`
|
|
2
|
+
`).at(-1)??"";return JSON.parse(s)}o(R,"runDaemonEntry");function Qe(){return R(["export-sqlite"])}o(Qe,"runDaemonExportSqlite");function Ze(e,t){return R(["import-dump",e,t])}o(Ze,"runDaemonImportDump");function et(e){return R(["import-dump",e,"bodies"])}o(et,"runDaemonBodiesDump");function tt(){return R(["import-dump","","install-id"])}o(tt,"runDaemonInstallId");const xe=3*6e4,z=2e4,N=10,P=1e3;async function L(e=P){const t=Math.min(e,P);return me({autostart:!1,timeoutMs:t}).probeHealthz(t)}o(L,"probeDaemonHealth");function ye(e){const t=e instanceof Error?e.message:String(e);if(typeof e!="object"||e===null)return t;const r=e.code,n=e.cause,a=typeof r=="string"?r:n?.code;return typeof a=="string"&&!t.includes(a)?`${t}: ${a}`:t}o(ye,"probeErrorMessage");async function J(e=P){const t=await L(e);if(t.startup_phase==="blocked"){const r=E()??process.pid;throw new v(r,t.startup_blocked??"daemon startup is blocked")}if(!t.ok)throw new Error(t.startup_blocked??"crtrd health check reported not ready")}o(J,"probeDaemonServing");async function rt(){try{return await J(),!0}catch{return!1}}o(rt,"isDaemonServing");function $(e){return new Promise(t=>{setTimeout(t,e)})}o($,"sleepMs");class C extends Error{static{o(this,"DaemonExitedBeforeReadyError")}stderrTail;constructor(t,r){super(r===""?t:`${t}
|
|
3
|
+
${r}`),this.name="DaemonExitedBeforeReadyError",this.stderrTail=r}}class v extends Error{static{o(this,"DaemonStartupBlockedError")}constructor(t,r){super(`daemon ${t} is running but normal startup is blocked: ${r}`),this.name="DaemonStartupBlockedError"}}class F extends Error{static{o(this,"DaemonNotPreparedError")}constructor(t,r){super(r===void 0?`daemon ${t} is serving but did not report the prepared startup phase`:`daemon ${t} reported startup phase ${r}, not prepared`),this.name="DaemonNotPreparedError"}}async function ge(e,t=G,r={},n="ready"){const a=r.readPidfile??E,c=r.isPidAlive??f,s=r.childExited,u=r.isDaemonServing,m=r.probeDaemonServing??(async w=>{if(u!==void 0){if(await u())return;throw new Error("crtrd health check reported not ready")}await J(w)}),p=r.probeDaemonHealth??L,x=r.sleepMs??$,y=r.now??Date.now;let i=null,l=null;return await fe({windowMs:t,pollIntervalMs:N,now:y,sleep:x,retry:o(w=>w!==l,"retry"),probe:o(async w=>{const h=a();if(h===null||!c(h)){const d=s?.();throw d!=null&&(d.signal!==null?l=new C(`daemon ${e} exited before becoming ready (by ${d.signal})`,r.childStderrTail?.()??""):d.code!==0&&(l=new C(`daemon ${e} exited before becoming ready (with exit code ${d.code??"?"})`,r.childStderrTail?.()??"")),l!==null)?l:new Error(`daemon ${e} has no live pidfile owner`)}if(n==="ready"){try{await m(w)}catch(d){throw d instanceof v&&(l=d),d}i=h;return}const _=await p(w);if(_.startup_phase==="prepared"){i=h;return}throw _.startup_phase==="blocked"?(l=new v(h,_.startup_blocked??"on-disk migration is blocked"),l):_.startup_phase==="ready"?(l=new F(h,_.startup_phase),l):new Error(`daemon ${h} is ${_.startup_phase??"not reporting a startup phase"}; waiting for prepared`)},"probe")}),i===e?null:i}o(ge,"verifyDaemonStartup");async function Se(e,t=z,r={}){const n=r.readPidfile??E,a=r.isPidAlive??f,c=r.sleepMs??$,s=r.now??Date.now,u=s()+t;for(;s()<=u;){if(!a(e)&&n()!==e)return;await c(N)}throw new Error(`daemon ${e} did not exit and release its pidfile within ${t}ms`)}o(Se,"waitForDaemonExit");const Re=2e3,ve=5e3;async function Y(e,t=z,r={}){const n=r.isPidAlive??f,a=r.sleepMs??$,c=r.now??Date.now;try{process.kill(e,"SIGTERM")}catch{}try{return await Se(e,t,r),"terminated"}catch{}try{process.kill(e,"SIGKILL")}catch{}const s=c()+Re;for(;c()<=s;){if(!n(e))return"killed";await a(N)}throw new Error(`daemon ${e} survived both SIGTERM and SIGKILL`)}o(Y,"stopDaemonProcess");async function nt(){const e=E(),t=e!==null&&f(e),r=t&&await Y(e)==="killed",n=Ee(null);return{stopped:t||n.length>0,...t?{pid:e}:{},strays_killed:n,force_killed:r}}o(nt,"stopAllDaemons");function Te(e,t,r=2048){let n;try{n=U(e,"r");const{size:a}=K(n),c=Math.max(t,a-r),s=a-c;if(s<=0)return"";const u=Buffer.alloc(s);return te(n,u,0,s,c),u.toString("utf8").trim()}catch{return""}finally{if(n!==void 0)try{j(n)}catch{}}}o(Te,"readLogTailFrom");async function be(e={}){if(process.platform==="linux"&&H("/run/crtr/launcher.sock")&&!f(E()??-1))throw new Error("crtrd is managed by the root launcher; it cannot self-daemonize");const t=e.targetPhase??"ready",r=E();if(r!==null&&f(r))try{const i=await L();if(t==="prepared"){if(i.startup_phase==="prepared")return{started:!1,existing_pid:r,startup_phase:i.startup_phase};throw new F(r,i.startup_phase)}return i.ok?{started:!1,existing_pid:r,...i.startup_phase===void 0?{}:{startup_phase:i.startup_phase}}:{started:!1,existing_pid:r,running:!0,serving:!1,probe_error:i.startup_blocked??"crtrd health check reported not ready",...i.startup_phase===void 0?{}:{startup_phase:i.startup_phase}}}catch(i){if(i instanceof F)throw i;return{started:!1,existing_pid:r,running:!0,serving:!1,probe_error:ye(i)}}ee(g(),{recursive:!0});const n=await A();e.waitForJoinLock===!0&&await ue(xe);const a=pe();if(a!==null&&a!==process.pid&&e.ignoreJoinLock!==!0)throw de(a);const c=D(g(),"crtrd.err"),s=U(c,"a"),u=(()=>{try{return K(s).size}catch{return 0}})();oe()===void 0&&ne();const m=B(O(),[...n,"--canvas-home",g(),...t==="prepared"?["--prepare"]:[]],{detached:!0,stdio:["ignore",s,s],env:M()});j(s);const p=m.pid;if(p===void 0)throw new Error("daemon spawn did not return a pid");let x=null;m.once("exit",(i,l)=>{x={code:i,signal:l}}),m.unref();let y;try{y=await ge(p,G,{childExited:o(()=>x,"childExited"),childStderrTail:o(()=>Te(c,u),"childStderrTail")},t)}catch(i){const l=ie(se())===p;if(x===null&&!l&&!(i instanceof v))try{await Y(p,ve)}catch{}throw i}return y!==null?{started:!1,existing_pid:y,startup_phase:t}:{started:!0,pid:p,startup_phase:t}}o(be,"spawnDaemon");function ke(){return ce()||process.argv.includes("--no-autostart")}o(ke,"autostartDisabled");const Ie=5e3,Oe=6e4;let W=!1,S,T=0,b=0;function Me(e){return Math.min(Ie*2**(e-1),Oe)}o(Me,"autostartBackoffMs");function Ae(){S=void 0,T=0,b=0}o(Ae,"resetDaemonAutostart");function ot(){return S}o(ot,"daemonAutostartStartupFailure");function at(e={}){const t=e.isDaemonRunning??ae,r=e.spawnDaemon??be,n=e.now??Date.now;if(!ke()&&!le()&&!W&&!(n()<b)){if(t()){Ae();return}S=void 0,W=!0,r().then(()=>{S=void 0,T=0,b=0},a=>{a instanceof C&&(S=a.message),T+=1,b=n()+Me(T)}).finally(()=>{W=!1})}}o(at,"ensureDaemon");export{he as DAEMON_ENV_STRIP_KEYS,C as DaemonExitedBeforeReadyError,F as DaemonNotPreparedError,v as DaemonStartupBlockedError,ke as autostartDisabled,ot as daemonAutostartStartupFailure,_e as daemonCommandDeclaresCanvasHome,at as ensureDaemon,Ve as execDaemon,De as findDaemonPids,rt as isDaemonServing,L as probeDaemonHealth,J as probeDaemonServing,ye as probeErrorMessage,Ae as resetDaemonAutostart,et as runDaemonBodiesDump,Qe as runDaemonExportSqlite,Ze as runDaemonImportDump,tt as runDaemonInstallId,M as sanitizedDaemonEnv,be as spawnDaemon,nt as stopAllDaemons,Y as stopDaemonProcess,Ee as sweepStrayDaemons,ge as verifyDaemonStartup,Se as waitForDaemonExit};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var c=Object.defineProperty;var t=(i,e)=>c(i,"name",{value:e,configurable:!0});import{emitEvent as o}from"../../core/events/emit.js";import{operationIdContext as n}from"../../core/events/operation-id.js";import{sweepOrphanCronFolders as l}from"../cron/folders.js";import{reapRebuiltCronExecutions as s}from"../cron/run-socket.js";import{recoverStaleCronLeases as f,runDueCrons as p}from"../cron-run.js";import{isDrained as m}from"../drain.js";import{runThrottledLane as d}from"./throttled-lane.js";class g{static{t(this,"CronLaneReconciler")}async run(e,a){await n.fresh(async()=>{try{await f(e,{register:t(r=>a.lifecycle.registerDetached(r),"register")})}catch(r){o({level:"error",event:"cron.lease_recovery.failed",error:r})}});try{await s()}catch(r){o({level:"error",event:"cron.execution.reap_failed",error:r})}try{await d("cron-folder-sweep","",e,6e4,6e4,async()=>{await l()})}catch(r){o({level:"error",event:"cron.folder.sweep_failed",error:r})}if(a.lifecycle.acceptsDetachedWork()&&!await m())try{await p(e,{register:t(r=>a.lifecycle.registerDetached(r),"register")})}catch(r){o({level:"error",event:"cron.run.failed",error:r})}}}export{g as CronLaneReconciler};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var g=Object.defineProperty;var p=(e,t)=>g(e,"name",{value:t,configurable:!0});import{randomUUID as D}from"node:crypto";import{claimPushDelivery as h,duePushDeliveries as j,messageBodyForDelivery as N,pushDeliveryClaimIsCurrent as O,settleDelivery as d}from"../../core/canvas/deliveries.js";import{deliveryBackoffMs as f}from"../../core/canvas/delivery-contract.js";import{openDb as c}from"../../core/canvas/db.js";import{pushLineFor as u}from"../../core/graph/custom.js";import{postReceiverUrl as b}from"../../core/graph/receiver-url.js";import{emitEvent as l}from"../../core/events/emit.js";import{operationIdContext as m}from"../../core/events/operation-id.js";import{runDelivery as w,DELIVERY_TIMEOUT_MS as E}from"../delivery/run-delivery.js";const v=D();async function o(e,t,a){await d(e.deliveryId,e.attempts,t,{state:"permanent_failed",failure:{kind:"spawn_error",message:a}},Date.now())}p(o,"failed");async function
|
|
1
|
+
var g=Object.defineProperty;var p=(e,t)=>g(e,"name",{value:t,configurable:!0});import{randomUUID as D}from"node:crypto";import{claimPushDelivery as h,duePushDeliveries as j,messageBodyForDelivery as N,pushDeliveryClaimIsCurrent as O,settleDelivery as d}from"../../core/canvas/deliveries.js";import{deliveryBackoffMs as f}from"../../core/canvas/delivery-contract.js";import{openDb as c}from"../../core/canvas/db.js";import{pushLineFor as u}from"../../core/graph/custom.js";import{postReceiverUrl as b}from"../../core/graph/receiver-url.js";import{emitEvent as l}from"../../core/events/emit.js";import{operationIdContext as m}from"../../core/events/operation-id.js";import{runDelivery as w,DELIVERY_TIMEOUT_MS as E}from"../delivery/run-delivery.js";import{isDrained as T}from"../drain.js";const v=D();async function o(e,t,a){await d(e.deliveryId,e.attempts,t,{state:"permanent_failed",failure:{kind:"spawn_error",message:a}},Date.now())}p(o,"failed");async function A(e,t){const a=await(await c()).prepare(`SELECT o.type, o.name, c.receiver_json, c.payload_json, m.object_id, i.external_id AS app,
|
|
2
2
|
d.message_id, owner.type AS owner_type, parent.external_id AS parent_app
|
|
3
3
|
FROM deliveries d JOIN objects o ON o.id = d.destination_id
|
|
4
4
|
JOIN custom_objects c ON c.object = o.id JOIN messages m ON m.message_id = d.message_id
|
|
5
5
|
LEFT JOIN objects owner ON owner.id = o.owner
|
|
6
6
|
LEFT JOIN identities i ON i.object = o.owner AND i.scheme = 'app'
|
|
7
7
|
LEFT JOIN identities parent ON parent.object = owner.owner AND parent.scheme = 'app'
|
|
8
|
-
WHERE d.delivery_id = ?`).get(e.deliveryId);if(!a||!a.receiver_json){await o(e,t,`delivery ${e.deliveryId} has no supported receiver`);return}const i=JSON.parse(a.receiver_json);if(!await O(e,t)){await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now());return}if(typeof i=="object"&&typeof i.url=="string"&&a.type!=="action"){const n=await u(await c(),e.deliveryId);if(!n){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}try{const r=await b(i.url,JSON.stringify(n),{"Content-Type":"application/json","X-Crtr-Delivery":e.deliveryId,"X-Crtr-Event":a.message_id},E);r>=200&&r<300?await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now()):r>=300&&r<400?await o(e,t,`url receiver returned HTTP ${r}; redirects are not followed \u2014 register the final URL`):r>=400&&r<500&&r!==408&&r!==429?await o(e,t,`url receiver returned HTTP ${r}`):await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:`url receiver returned HTTP ${r}`}},Date.now())}catch(r){await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:String(r)}},Date.now())}return}if(typeof i!="object"||!Array.isArray(i.argv)||typeof i.cwd!="string"){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}if(a.type==="action"){if(typeof i.name!="string"||!a.object_id){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}const n=await N(e.deliveryId);if(n===null){await o(e,t,`delivery ${e.deliveryId} has no message body`);return}const{push:r,...y}=n,I={...y,action:{name:i.name,payload:a.payload_json===null?null:JSON.parse(a.payload_json)}};await w({argv:i.argv,cwd:i.cwd,document:I,attempt:e.attempts,nodeId:a.object_id,...a.app??a.parent_app?{app:a.app??a.parent_app}:{}},async _=>{await d(e.deliveryId,e.attempts,t,_,Date.now())});return}const s=await u(await c(),e.deliveryId);if(!s){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}await w({argv:i.argv,cwd:i.cwd,document:s,attempt:e.attempts,app:a.app??a.parent_app??"app:terminal",custom:{deliveryId:e.deliveryId,messageId:a.message_id}},async n=>{await d(e.deliveryId,e.attempts,t,n,Date.now())})}p(
|
|
8
|
+
WHERE d.delivery_id = ?`).get(e.deliveryId);if(!a||!a.receiver_json){await o(e,t,`delivery ${e.deliveryId} has no supported receiver`);return}const i=JSON.parse(a.receiver_json);if(!await O(e,t)){await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now());return}if(typeof i=="object"&&typeof i.url=="string"&&a.type!=="action"){const n=await u(await c(),e.deliveryId);if(!n){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}try{const r=await b(i.url,JSON.stringify(n),{"Content-Type":"application/json","X-Crtr-Delivery":e.deliveryId,"X-Crtr-Event":a.message_id},E);r>=200&&r<300?await d(e.deliveryId,e.attempts,t,{state:"acknowledged"},Date.now()):r>=300&&r<400?await o(e,t,`url receiver returned HTTP ${r}; redirects are not followed \u2014 register the final URL`):r>=400&&r<500&&r!==408&&r!==429?await o(e,t,`url receiver returned HTTP ${r}`):await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:`url receiver returned HTTP ${r}`}},Date.now())}catch(r){await d(e.deliveryId,e.attempts,t,{state:"pending",nextAttemptAt:Date.now()+f(e.attempts),failure:{kind:"spawn_error",message:String(r)}},Date.now())}return}if(typeof i!="object"||!Array.isArray(i.argv)||typeof i.cwd!="string"){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}if(a.type==="action"){if(typeof i.name!="string"||!a.object_id){await o(e,t,`delivery ${e.deliveryId} has an invalid argv receiver`);return}const n=await N(e.deliveryId);if(n===null){await o(e,t,`delivery ${e.deliveryId} has no message body`);return}const{push:r,...y}=n,I={...y,action:{name:i.name,payload:a.payload_json===null?null:JSON.parse(a.payload_json)}};await w({argv:i.argv,cwd:i.cwd,document:I,attempt:e.attempts,nodeId:a.object_id,...a.app??a.parent_app?{app:a.app??a.parent_app}:{}},async _=>{await d(e.deliveryId,e.attempts,t,_,Date.now())});return}const s=await u(await c(),e.deliveryId);if(!s){await o(e,t,`delivery ${e.deliveryId} has no event document`);return}await w({argv:i.argv,cwd:i.cwd,document:s,attempt:e.attempts,app:a.app??a.parent_app??"app:terminal",custom:{deliveryId:e.deliveryId,messageId:a.message_id}},async n=>{await d(e.deliveryId,e.attempts,t,n,Date.now())})}p(A,"deliverExternal");class H{static{p(this,"DeliveryLaneReconciler")}async run(t,a){if(!a.lifecycle.acceptsDetachedWork()||await T())return;let i;try{i=await j(t)}catch(s){m.fresh(()=>l({level:"error",event:"delivery.scan_failed",error:s}));return}for(const s of i)try{const n=await h(s.deliveryId,t,v);if(n===null)continue;a.lifecycle.registerDetached(A(n,v).catch(r=>{m.fresh(()=>l({level:"error",event:"delivery.failed",error:r,fields:{delivery_id:n.deliveryId}}))}))}catch(n){m.fresh(()=>l({level:"error",event:"delivery.claim_failed",error:n,fields:{delivery_id:s.deliveryId}}))}}}export{H as DeliveryLaneReconciler,v as deliveryDaemonInstanceId};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DetachedWorkLifecycle } from './broker-supervision.js';
|
|
2
|
+
export declare const IMPORT_LEASE_MS: number;
|
|
3
|
+
export declare class ImportLaneReconciler {
|
|
4
|
+
run(now: number, ctx: {
|
|
5
|
+
lifecycle: DetachedWorkLifecycle;
|
|
6
|
+
}): void;
|
|
7
|
+
/** One pass over the runs due now. Exposed for tests. */
|
|
8
|
+
pass(now: number): Promise<number>;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var p=Object.defineProperty;var n=(i,e)=>p(i,"name",{value:e,configurable:!0});import{openDb as m}from"../../core/canvas/db.js";import{emitEvent as l}from"../../core/events/emit.js";import{operationIdContext as c}from"../../core/events/operation-id.js";import{processRun as f}from"../../core/import/load/run.js";import{ClaimLostError as d,withRowClaim as _}from"./row-claim.js";const R=2*6e4;class S{static{n(this,"ImportLaneReconciler")}run(e,o){if(!o.lifecycle.acceptsDetachedWork())return;const a=c.fresh(()=>this.pass(e).then(()=>{})).catch(t=>{c.fresh(()=>l({level:"error",event:"import.lane.failed",error:t}))});o.lifecycle.registerDetached(a)}async pass(e){const a=await(await m()).prepare("SELECT * FROM import_runs WHERE (state = 'loading' OR state = 'committed') AND (claimed_by IS NULL OR lease_expires_at IS NULL OR lease_expires_at <= ?) ORDER BY created_at").all(new Date(e).toISOString());let t=0;for(const s of a)try{await _("import_runs",s.run_id,R,r=>f(s,r))&&(t+=1)}catch(r){if(!(r instanceof d))throw r}return t}}export{R as IMPORT_LEASE_MS,S as ImportLaneReconciler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var N=Object.defineProperty;var s=(i,e)=>N(i,"name",{value:e,configurable:!0});import{clearFrozen as f,getNode as g,getRow as D}from"../../../core/canvas/index.js";import{openDb as c}from"../../../core/canvas/db.js";import{fullName as z}from"../../../core/canvas/labels.js";import{isSafeNodeId as d}from"../../../core/canvas/paths.js";import{emitEvent as _}from"../../../core/events/emit.js";import{operationIdContext as L}from"../../../core/events/operation-id.js";import{acknowledgedNodeMailCount as T}from"../../../core/canvas/deliveries.js";import{publishNotice as C}from"../../../core/runtime/close.js";import{transition as u}from"../../../core/runtime/lifecycle.js";import{isStartRefusal as y}from"../../../core/runtime/start-check.js";import{EnvironmentImagePending as A}from"./remote-wake.js";import{asNodePerson as M}from"./node-person.js";import{MachineLaunchUncertainError as b,MachineOfflineError as m}from"../../../core/runtime/runner/machine/ops.js";import{commitReopenResident as I}from"../../../core/runtime/reopen.js";import{reviveNode as w}from"../../../core/runtime/revive.js";import{hasPendingWake as k}from"../live-obligation.js";import{readInterruptedTurn as O}from"../../../core/canvas/recovery.js";import{mapAsync as P}from"../../../core/async-array.js";const h=6,U=10*6e4,x=2e4;async function H(i){const e=await(await c()).prepare("SELECT idle_release_attempts, idle_release_last_attempt_at, idle_release_acked_count FROM nodes WHERE node_id = ?").get(i);return{attempts:Number(e?.idle_release_attempts??0),acknowledgedCount:Number(e?.idle_release_acked_count??0),lastAttempt:e?.idle_release_last_attempt_at==null?void 0:Date.parse(e.idle_release_last_attempt_at)}}s(H,"readEpisode");async function F(i,e,a,t,r){const n=await(await c()).prepare("UPDATE nodes SET idle_release_attempts = ?, idle_release_last_attempt_at = ?, idle_release_acked_count = ? WHERE node_id = ? AND idle_release_attempts = ?").run(a,new Date(r).toISOString(),t,i,e);return Number(n.changes)===1}s(F,"claimAttempt");async function W(i,e){await(await c()).prepare("UPDATE nodes SET idle_release_attempts = ?, idle_release_last_attempt_at = ?, idle_release_acked_count = ? WHERE node_id = ?").run(e.attempts,e.lastAttempt===void 0?null:new Date(e.lastAttempt).toISOString(),e.acknowledgedCount,i)}s(W,"writeEpisode");function $(i,e){if(e)return 2;const a=i.launched_at;if(a==null)return 1;const t=i.last_settled_at;return t==null?2:Date.parse(t)>Date.parse(a)?1:2}s($,"thawTier");function B(i,e){const a=i.row.frozen_at,t=e.row.frozen_at;return a==null?t==null?0:1:t==null?-1:Date.parse(a)-Date.parse(t)}s(B,"compareThaw");class le{static{s(this,"FreezeLaneReconciler")}async endEpisode(e){await(await c()).prepare("UPDATE nodes SET idle_release_attempts = 0, idle_release_last_attempt_at = NULL, idle_release_acked_count = 0 WHERE node_id = ? AND (idle_release_attempts <> 0 OR idle_release_last_attempt_at IS NOT NULL OR idle_release_acked_count <> 0)").run(e)}async run(e,a){const t=await P(a.candidates,async n=>({...n,tier:$(n.row,await k(n.row.node_id))}));t.sort(B);const r={stalled:0,waitingOnMail:0};for(const n of t)await L.fresh(()=>M(n.row,()=>this.enact(e,n,a.fleet)))==="frozen"&&(n.tier===1?r.stalled+=1:r.waitingOnMail+=1);return r}async enact(e,a,t){const r=a.row.node_id;try{return a.enact==="thaw"?await this.enactThaw(a.row):a.enact==="reopen"?await this.enactReopen(a.row):a.enact==="idle-release"?await this.enactIdleRelease(e,a.row):(await t.applyDeadRowPolicy(r),await t.has(r)?"launched":(await D(r))?.frozen_at!=null?"frozen":"skipped")}catch(n){return _({level:"error",event:"node.lifecycle.enact_failed",...d(r)?{node_id:r}:{},error:n,fields:{...d(r)?{}:{affected_node_id:r},enact:a.enact}}),"skipped"}}async enactReopen(e){await I(e.node_id);try{return(await w(e.node_id,{resume:!0,capacity:"freeze"})).outcome==="frozen"?"frozen":"launched"}catch(a){if(y(a)||a instanceof A||a instanceof m)return await this.settleRefusedStart(e.node_id,a,"reopen");throw a}}async settleRefusedStart(e,a,t){return a instanceof b||await u(e,"release"),await f(e),_({level:"warn",event:"node.start.refused",node_id:e,error:a,fields:{enact:t}}),"skipped"}async enactThaw(e){const a=(await O(e.node_id))?.interrupted===!0;if(!a&&e.lifecycle==="resident"&&(await g(e.node_id))?.pi_session_id!=null&&!await k(e.node_id))return await u(e.node_id,"release"),await f(e.node_id),"skipped";try{return(await w(e.node_id,{resume:!0,capacity:"freeze",recovery:!0,...a?{wakeReason:"runtime-restart-abort"}:{}})).outcome==="frozen"?"frozen":"launched"}catch(t){if(y(t)||t instanceof A||t instanceof m)return await this.settleRefusedStart(e.node_id,t,"thaw");const r=await g(e.node_id);throw r!==null&&(r.status==="active"||r.status==="idle")&&(await u(e.node_id,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:t instanceof Error?t.message:String(t)}}}),await f(e.node_id)),t}}async enactIdleRelease(e,a){const t=a.node_id,r=await T(t),n=await H(t),l=n.attempts===0||n.acknowledgedCount!==r,o=l?0:n.attempts;if(o>=h)return await this.endEpisode(t),_({level:"warn",event:"broker.idle_release.exhausted",...d(t)?{node_id:t}:{},fields:{...d(t)?{}:{affected_node_id:t},attempts:o,max_attempts:h}}),await u(t,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",respawn_failures:o}}}),await C(t,"notice.crash",`Child crashed \u2014 ${z(a)} (${t}) failed to relaunch after ${o} attempts while trying to deliver a pending inbox message (no delivery progress across any attempt), and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${t}\`.`,{reason:"child-crashed",child:t}),"skipped";const E=l?void 0:n.lastAttempt,S=Math.min(x*2**o,U);if(E!==void 0&&e-E<S||!await F(t,n.attempts,o+1,r,e))return"skipped";const v=s(()=>W(t,{attempts:l?0:o,lastAttempt:l?void 0:n.lastAttempt,acknowledgedCount:r}),"giveBack");let R;try{R=await w(t,{resume:!0,capacity:"freeze"})}catch(p){if(!(p instanceof m))throw p;return await v(),await this.settleRefusedStart(t,p,"idle-release")}return R.outcome==="frozen"?(await v(),"frozen"):(_({level:"info",event:"broker.revive.idle_release",...d(t)?{node_id:t}:{},attempt:o+1,fields:{...d(t)?{}:{affected_node_id:t},attempts:o+1,max_attempts:h}}),"launched")}}export{le as FreezeLaneReconciler,B as compareThaw,$ as thawTier};
|
|
@@ -7,6 +7,9 @@ export declare const LAUNCH_DEADLINE_MS: number;
|
|
|
7
7
|
export declare const LAUNCH_LOST_GRACE_MS = 120000;
|
|
8
8
|
/** The release the control plane runs, which is the release a wake names. */
|
|
9
9
|
export declare const acceptedRelease: () => string;
|
|
10
|
+
/** The machine environment the node's profile points at when this process is a cloud role (the machine is another host, reached
|
|
11
|
+
* through the remote machine runner), else null: a Mac's own crtrd runs its machine environment's nodes as processes. */
|
|
12
|
+
export declare function remoteMachineEnvironmentOf(profileId: string | null): Promise<string | null>;
|
|
10
13
|
/** Step 2: the `funding bill` check. A refusal writes `nodes.spend_refusal` and one refused `sandbox` row per node, limit and month,
|
|
11
14
|
* then throws `402 cap_exhausted`; no execution row is written and no runner is called. A pass clears `spend_refusal`. */
|
|
12
15
|
export declare function checkBilledWake(meta: NodeMeta): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var f=Object.defineProperty;var a=(e,
|
|
1
|
+
var f=Object.defineProperty;var a=(e,t)=>f(e,"name",{value:t,configurable:!0});import{liveExecutionForNode as m,endExecution as l,recordExecutionAwake as p,endLaunchingExecution as s,requestExecutionStop as w}from"../../../core/canvas/executions.js";import{openDb as h}from"../../../core/canvas/db.js";import{isCloudRole as _}from"../../../core/canvas/person-state.js";import{emitEvent as u}from"../../../core/events/emit.js";import{findRefusal as x,refusalError as E,refusedMark as g,writeCharge as v}from"../../../core/ledger/index.js";import{transition as c}from"../../../core/runtime/lifecycle.js";import{runnerForExecution as d}from"../../../core/runtime/runner/index.js";import{machineEnvironmentOfProfile as b}from"../../../core/runtime/runner/machine/environment.js";import{startCandidateOf as k}from"../../../core/runtime/start-check.js";import{settleSandboxBeforeWake as y}from"../ledger-sandbox.js";import{crtrVersion as I}from"../../../shared/crtr-version.js";import{resolveEnvironmentImage as S}from"../recipe-image.js";const L=45*6e4,A=12e4,D=a(()=>I(),"acceptedRelease");async function G(e){return e===null||!_()?null:await b(e)}a(G,"remoteMachineEnvironmentOf");async function q(e){const t=await k(e);if(t===null)return;const n={scope:"call",payer:t.payer,funding:"bill",sub:t.sub,grantee:t.grantee,provider:"blaxel"},r=await x(n),o=await h();if(r===null){await o.prepare("UPDATE nodes SET spend_refusal = NULL WHERE node_id = ? AND spend_refusal IS NOT NULL").run(e.node_id);return}throw await o.prepare("UPDATE nodes SET spend_refusal = ? WHERE node_id = ?").run(JSON.stringify({limit:r.limit.id,usd:r.usd,reset_at:r.reset_at,at:new Date().toISOString()}),e.node_id),await v({id:`refused:sandbox:${e.node_id}:${r.limit.id}:${r.month}`,kind:"sandbox",what:"wake",usd:null,payer:n.payer,funding:"bill",sub:n.sub,grantee:n.grantee,node:e.node_id,run:e.run_id??null,provider:"blaxel",refused:g(r)}),E(r)}a(q,"checkBilledWake");class J extends Error{static{a(this,"EnvironmentImagePending")}environmentId;imageError;constructor(t,n){super(`environment ${t} has no built image yet${n===null?"":` (${n})`}; the wake waits for the build.`),this.environmentId=t,this.imageError=n,this.name="EnvironmentImagePending"}}async function V(e){return await S(e)}a(V,"imageForWake");async function j(e){return e.release!==D()&&await w(e.nodeId,{afterTurn:!1,reason:"release"}),await d(e.runner).wake(e)==="no_broker"?(await l(e.executionId,{reason:"lost"}),"lost"):(await y(e.executionId,Date.now()),await p(e.executionId),"woken")}a(j,"wakeResident");async function z(e){const t=await d(e.runner).status(e);if(t.state!=="gone"&&t.state!=="failed")return!1;const n=await l(e.executionId,{reason:"lost"});return n&&u({level:"warn",event:"execution.lost",node_id:e.nodeId}),n}a(z,"endRemoteExecutionIfGone");async function K(e,t){const n=await m(e);if(n===null||n.state!=="launching"||n.runner==="process")return;const r=d(n.runner),o=t-Date.parse(n.startedAt),i=await r.status(n);if(i.state!=="unknown"){if(i.state==="running"){if(o<=L||!await s(n.executionId,{reason:"launch_timeout"}))return;await r.stop(n,{reason:"launch_timeout"}),await c(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:"the sandbox launch did not report within the launch deadline"}}}),u({level:"warn",event:"execution.launch_timeout",node_id:e});return}if(i.state==="failed"){if(!await s(n.executionId,{reason:"launch_failed"}))return;await c(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:`the sandbox start script failed: ${i.reason}`}}});return}if(o>A){if(!await s(n.executionId,{reason:"launch_lost"}))return;u({level:"warn",event:"execution.launch_lost",node_id:e})}}}a(K,"recoverLaunching");export{J as EnvironmentImagePending,L as LAUNCH_DEADLINE_MS,A as LAUNCH_LOST_GRACE_MS,D as acceptedRelease,q as checkBilledWake,z as endRemoteExecutionIfGone,V as imageForWake,K as recoverLaunching,G as remoteMachineEnvironmentOf,j as wakeResident};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var b=Object.defineProperty;var o=(r,
|
|
1
|
+
var b=Object.defineProperty;var o=(r,i)=>b(r,"name",{value:i,configurable:!0});import{clearFrozen as P,getNode as g}from"../../../core/canvas/index.js";import{isSafeNodeId as z}from"../../../core/canvas/paths.js";import{recordedPidLiveness as L}from"../../../core/canvas/pid.js";import{endExecution as v,hasAbsorbedProfilePauseStop as N,hasObservedExit as x,latestExecutionForNode as M,liveExecutionForNode as c}from"../../../core/canvas/executions.js";import{emitEvent as w}from"../../../core/events/emit.js";import{operationIdContext as D}from"../../../core/events/operation-id.js";import{readInterruptedTurn as F}from"../../../core/canvas/recovery.js";import{isProfilePaused as d}from"../../../core/profiles/manifest.js";import{isRecoveryHeld as I}from"../../../core/runtime/recovery-hold.js";import{hasUnseenWakeMail as p}from"../../../core/canvas/deliveries.js";import{hasIdleReleaseIntent as A,isParkedResident as C}from"../../../core/runtime/lifecycle.js";import{classifyDeadNode as S}from"../../fleet.js";import{applyParkEvent as T,hasPendingWake as U,parkEvent as W}from"../live-obligation.js";import{FreezeLaneReconciler as B}from"./freeze-lane.js";import{isInBackoff as E}from"./respawn-policy.js";import{asNodePerson as G,NodePersonUnresolvedError as k}from"./node-person.js";import{handleTerminatingRow as H}from"./terminating.js";import{wantsExecution as O}from"./wants-execution.js";import{enactRequestedStops as q}from"./requested-stops.js";import{endRemoteExecutionIfGone as j,recoverLaunching as J,wakeResident as K}from"./remote-wake.js";import{isDrained as Q}from"../../drain.js";function V(r){return r.status==="done"||r.status==="canceled"||r.status==="dead"}o(V,"isTerminal");const X=12e4;function Y(r,i){const e=Math.max(...[r.created,r.launched_at].map(n=>n==null?0:Date.parse(n)||0));return e>0&&i-e<X}o(Y,"isLaunchInFlight");async function R(r){const i=await c(r);return i!==null&&i.state==="running"&&i.pid!=null&&L(i.pid,i.processIdentity)==="dead"?i:null}o(R,"executionWithDeadPid");class we{static{o(this,"NodeLifecycleReconciler")}freezeLane=new B;async run(i,e){const n=[];await q(i);for(const s of e.rows)await D.fresh(async()=>{try{await G(s,()=>this.classifyRow(i,s,e,n))}catch(t){const l=s.node_id;w({level:t instanceof k?"warn":"error",event:t instanceof k?"node.lifecycle.person_unresolved":"node.lifecycle.classify_failed",...z(l)?{node_id:l}:{fields:{affected_node_id:l}},error:t})}});return await Q()?{stalled:0,waitingOnMail:0}:this.freezeLane.run(i,{fleet:e.fleet,candidates:n})}async classifyRow(i,e,n,s){const t=e.node_id;if(V(e)){if(H(e,await n.fleet.has(t)))return;if(C(e)&&!await n.fleet.has(t)&&!d(e.profile_id)&&!await I(t)&&!E(e,i)&&await p(t)){s.push({row:e,enact:"reopen"});return}if(e.pi_pid!=null){const a=await R(t);a!==null&&await v(a.executionId,{reason:"observed-dead"})}e.frozen_at!=null&&(e.final_report!=null||e.status==="dead"?await P(t):s.push({row:e,enact:"thaw"}));return}if(await n.fleet.has(t)){const a=await c(t);if(a?.runner!==void 0&&a.runner!=="process"&&a.state==="running"&&!d(e.profile_id)&&await p(t)){if(await K(a)==="lost")return}else a?.runner!==void 0&&a.runner!=="process"&&a.state==="running"&&await j(a);if(await n.fleet.has(t)){d(e.profile_id)?await n.fleet.interruptForProfilePause(t):await this.thawMark(e);return}}if(await J(t,i),d(e.profile_id)){await this.freezeLane.endEpisode(t);return}if(await I(t))return;const l=e.pi_pid==null?await M(t):null,f=l!==null&&x(l),m=l!==null&&!f&&N(l),h=e.pi_pid!=null?await R(t):null,_=f||m||h!==null;if(_&&!await n.fleet.hasProfilePauseInterruption(t)){const a=h??l;a!==null&&await v(a.executionId,{reason:"observed-dead"});const y=await c(t);if(y!==null&&y.executionId!==a?.executionId)return}if(!await O(e)){await this.thawMark(e),await this.settleParked(e);return}if(E(e,i))return;if(e.status==="idle"&&A(e)&&await p(t)){s.push({row:e,enact:"idle-release"});return}if(e.pi_pid==null&&(!f||e.frozen_at!=null)&&!m){if(e.respawn_not_before!=null){s.push({row:e,enact:"policy"});return}if(e.frozen_at!=null){s.push({row:e,enact:"thaw"});return}if(await n.fleet.isClaimed(t)||Y(e,i))return;w({level:"warn",event:"node.lifecycle.stranded_launch",node_id:t}),s.push({row:e,enact:"thaw"});return}if(!_)return;const u=S(await g(t),(await F(t))?.interrupted===!0,await U(t));if(u==="respawn-fresh"||u==="respawn-cycle"||u==="respawn-resume"){s.push({row:e,enact:"policy"});return}await n.fleet.applyDeadRowPolicy(t),await this.thawMark(e)}async thawMark(i){i.frozen_at!=null&&await P(i.node_id)}async settleParked(i){if(i.status!=="idle")return;await this.freezeLane.endEpisode(i.node_id);const e=await W(i.node_id,i.lifecycle);e!=="release"&&await T(i.node_id,e)}}export{X as LAUNCH_GRACE_MS,we as NodeLifecycleReconciler,Y as isLaunchInFlight};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DetachedWorkLifecycle } from './broker-supervision.js';
|
|
2
|
+
import { type LanePass } from './throttled-lane.js';
|
|
3
|
+
export declare const PURGE_DUE_WORK_INTERVAL_MS: number;
|
|
4
|
+
/** Rows purged per pass; the rest wait for the next pass. */
|
|
5
|
+
export declare const PURGE_BUDGET = 1000;
|
|
6
|
+
export interface PurgeDueWorkContext {
|
|
7
|
+
lifecycle: DetachedWorkLifecycle;
|
|
8
|
+
}
|
|
9
|
+
export declare class PurgeDueWorkReconciler {
|
|
10
|
+
run(now: number, ctx: PurgeDueWorkContext): void;
|
|
11
|
+
/** One pass. Exposed for tests. */
|
|
12
|
+
pass(now: number, lane?: Pick<LanePass, 'holds'>): Promise<number>;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Object.defineProperty;var c=(s,e)=>a(s,"name",{value:e,configurable:!0});import{emitEvent as n}from"../../core/events/emit.js";import{operationIdContext as i}from"../../core/events/operation-id.js";import{purgeSoftDeleted as d}from"../../core/storage/purge.js";import{runThrottledLane as p}from"./throttled-lane.js";const u=10*6e4,l=1e3,f=5*6e4;class D{static{c(this,"PurgeDueWorkReconciler")}run(e,t){if(!t.lifecycle.acceptsDetachedWork())return;const r=i.fresh(()=>p("purge-due-work","",e,u,f,async o=>{await this.pass(e,o)})).then(()=>{}).catch(o=>{i.fresh(()=>n({level:"error",event:"purge.due_work.failed",error:o}))});t.lifecycle.registerDetached(r)}async pass(e,t){const r=await d(e,l,t?.holds);return r>0&&n({level:"info",event:"purge.due_work.settled",outcome:"succeeded",fields:{purged:r}}),r}}export{l as PURGE_BUDGET,u as PURGE_DUE_WORK_INTERVAL_MS,D as PurgeDueWorkReconciler};
|
|
@@ -3,6 +3,7 @@ declare const CLAIMABLE: {
|
|
|
3
3
|
readonly nodes: "node_id";
|
|
4
4
|
readonly structured_requests: "request_id";
|
|
5
5
|
readonly human_requests: "request_id";
|
|
6
|
+
readonly import_runs: "run_id";
|
|
6
7
|
};
|
|
7
8
|
export type ClaimableTable = keyof typeof CLAIMABLE;
|
|
8
9
|
export declare class ClaimLostError extends Error {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var E=Object.defineProperty;var i=(e,r)=>E(e,"name",{value:r,configurable:!0});import{randomUUID as
|
|
2
|
-
WHERE ${a} = ? AND (claimed_by IS NULL OR lease_expires_at IS NULL OR lease_expires_at <= ?)`).run(n,new Date(Date.now()+t).toISOString(),r,
|
|
1
|
+
var E=Object.defineProperty;var i=(e,r)=>E(e,"name",{value:r,configurable:!0});import{randomUUID as d}from"node:crypto";import{openDb as _}from"../../core/canvas/db.js";const D={nodes:"node_id",structured_requests:"request_id",human_requests:"request_id",import_runs:"run_id"};class w extends Error{static{i(this,"ClaimLostError")}constructor(r,t){super(`row claim lost: ${r} ${t} is no longer held by this process`)}}async function L(e,r,t,u){const a=D[e],n=d(),o=await _(),p=new Date().toISOString();if((await o.prepare(`UPDATE ${e} SET claimed_by = ?, lease_expires_at = ?
|
|
2
|
+
WHERE ${a} = ? AND (claimed_by IS NULL OR lease_expires_at IS NULL OR lease_expires_at <= ?)`).run(n,new Date(Date.now()+t).toISOString(),r,p)).changes!==1)return!1;let s=!1;const c=setInterval(()=>{o.prepare(`UPDATE ${e} SET lease_expires_at = ? WHERE ${a} = ? AND claimed_by = ? AND lease_expires_at > ?`).run(new Date(Date.now()+t).toISOString(),r,n,new Date().toISOString()).then(l=>{l.changes!==1&&(s=!0)},()=>{s=!0})},Math.max(1,Math.floor(t/3)));c.unref();const m={async assertOwned(){if(s)throw new w(e,r);if(await(await _()).prepare(`SELECT 1 AS held FROM ${e} WHERE ${a} = ? AND claimed_by = ? AND lease_expires_at > ? FOR UPDATE`).get(r,n,new Date().toISOString())===void 0)throw s=!0,new w(e,r)}};try{await u(m)}finally{clearInterval(c),await o.prepare(`UPDATE ${e} SET claimed_by = NULL, lease_expires_at = NULL WHERE ${a} = ? AND claimed_by = ?`).run(r,n)}return!0}i(L,"withRowClaim");export{w as ClaimLostError,L as withRowClaim};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
WHERE node_id = ? AND EXISTS (SELECT 1 FROM reconciler_leases WHERE lane = ? AND key = ? AND owner = ? AND expires_at > ?)`).run(...e===null||
|
|
1
|
+
var M=Object.defineProperty;var l=(t,e)=>M(t,"name",{value:e,configurable:!0});import{randomUUID as y}from"node:crypto";import{openDb as d,withCanvasWrite as C}from"../../core/canvas/db.js";import{claimReconcilerLease as F,releaseReconcilerLease as O,renewReconcilerLease as x}from"../../core/canvas/reconciler-leases.js";import{getNode as R}from"../../core/canvas/canvas.js";import{BrokerClient as H,SocketTransport as D}from"../../core/broker-client/client.js";import{liveExecutionForNode as N}from"../../core/canvas/executions.js";import{runnerForExecution as W}from"../../core/runtime/runner/index.js";import{connectWssView as q}from"../../core/runtime/view-socket.js";import{openMachineView as U}from"../machine-link/forward.js";import{ViewLinkTransport as A}from"./view-transport.js";import{emitRunEvent as g,emitRunSettlement as T,emitRunStatus as j}from"../../core/runs/events.js";import{cancelOpenQuestions as J}from"../../core/runs/questions.js";import{emitEvent as c}from"../../core/events/emit.js";import{toRunOutcomeDTO as P}from"../api/map.js";import{readOutputResult as V}from"../../core/runtime/output-result.js";const B=JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),p=new Map,h="run-observer",E=1e4,Y=250;async function m(t,e,i){return await C(async n=>await n.prepare("SELECT 1 AS held FROM reconciler_leases WHERE lane = ? AND key = ? AND owner = ? AND expires_at > ? FOR SHARE").get(h,t,e,new Date().toISOString())===void 0?{held:!1}:{held:!0,value:await i()})}l(m,"whileHoldingLease");class v{static{l(this,"RunObserver")}nodeId;runId;owner;client;timer;status;piPid=null;outcomeRevision;openAssistant=!1;assistantStartSequence=0;block=null;thinking="";output="";pendingThinking="";pendingOutput="";flushTimer;closed=!1;lastRenewAt=Date.now();released=Promise.resolve();polling;frames=Promise.resolve();constructor(e,i,n,s,r){this.nodeId=e,this.runId=i,this.owner=n,this.status=s,this.outcomeRevision=r,this.timer=setInterval(()=>{this.pollOrClose()},250),this.timer.unref(),p.set(e,this)}static async start(e,i,n){const s=await d(),r=await s.prepare("SELECT body_json FROM run_events WHERE node_id = ? AND type = ? ORDER BY sequence_number DESC LIMIT 1").get(e,e===i?"node.settled":"child.settled"),a=await s.prepare("SELECT body_json FROM run_events WHERE node_id = ? AND type = 'node.status.changed' ORDER BY sequence_number DESC LIMIT 1").get(e),o=new v(e,i,n,a?JSON.parse(a.body_json).status:void 0,r?JSON.parse(r.body_json).outcome.revision:void 0);return await o.writeStream(null,null),await o.poll(),o}async pollOrClose(){try{await this.poll()}catch(e){this.close(),c({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:e})}}poll(){return this.polling===void 0&&(this.polling=this.pollOnce().finally(()=>{this.polling=void 0})),this.polling}async holdLease(){return Date.now()-this.lastRenewAt<E/3?!0:await x(h,this.nodeId,this.owner,E)?(this.lastRenewAt=Date.now(),!0):!1}async writeStream(e,i,n=!1){return(await(await d()).prepare(`UPDATE nodes SET ${n?"":`stream_message_seq = ${e===null?"NULL":"(SELECT event_cursor FROM nodes WHERE node_id = ?)"},`} stream_block = ?
|
|
2
|
+
WHERE node_id = ? AND EXISTS (SELECT 1 FROM reconciler_leases WHERE lane = ? AND key = ? AND owner = ? AND expires_at > ?)`).run(...e===null||n?[]:[this.runId],i===null?null:JSON.stringify(i),this.nodeId,h,this.nodeId,this.owner,new Date().toISOString())).changes===1}async pollOnce(){if(this.closed)return;if(!await this.holdLease()){this.close();return}const e=await R(this.nodeId);if(!e||e.run_id!==this.runId||!await I(this.runId)){this.close();return}this.piPid=e.pi_pid??null;const i=e.pi_pid===null?"dormant":e.status;if(this.status!==i){if(!(await m(this.nodeId,this.owner,()=>j(this.runId,this.nodeId,i,e.intent??null))).held){this.close();return}this.status=i}const n=await P(e);if(n&&n.revision!==this.outcomeRevision&&Date.now()-Date.parse(n.settled_at)<720*60*6e4){if(this.nodeId===this.runId){const a=await(await d()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(this.runId,this.runId);for(const o of a)await k(o.node_id,this.runId),await p.get(o.node_id)?.poll()}this.outcomeRevision=n.revision;const s=this.nodeId===this.runId&&n.kind==="result"?await V(this.nodeId):void 0;if(!(await m(this.nodeId,this.owner,()=>this.nodeId===this.runId?T(this.runId,this.nodeId,"node.settled",{outcome:n,usage:JSON.parse(e.usage_json??B),...s===void 0?{}:{result:s}}):T(this.runId,this.nodeId,"child.settled",{child_node_id:this.nodeId,outcome:n}))).held){this.close();return}if(e.grantee&&e.grantee!=="app:terminal"){const a=this.nodeId===this.runId?{run_id:this.runId}:{node_id:this.nodeId};J(a,this.nodeId===this.runId?"the run settled":"the asking node was closed").catch(o=>c({level:"error",event:"daemon.runs.question_cancel_failed",node_id:this.nodeId,error:o}))}}e.pi_pid===null?this.close():await this.connect()}async settlePoll(){await this.polling?.catch(()=>{}),await this.frames,await this.released}async viewAdmitted(){const e=await N(this.nodeId);return!(e?.runner==="blaxel"&&e.idleAt!==null)}async dropView(){const e=this.client;e&&(this.client=void 0,await this.frames,await this.flushDeltas(),this.discardDeltas(),this.openAssistant=!1,this.block=null,await this.writeStream(null,null),e.close())}async connect(){if(this.closed)return;if(!await this.viewAdmitted()){await this.dropView();return}if(this.client)return;const e=await $(this.nodeId),i=await this.viewAdmitted();if(this.client||this.closed||!i){e.destroy();return}const n=new H(this.nodeId,{transport:e});this.client=n,n.on("connect",()=>n.send({type:"hello",role:"observer",client_id:y(),attends:!1}));const s=l(async r=>{if(!(this.closed||this.client!==n)){if(r.type==="message_start"&&r.message.role==="assistant"){if(this.discardDeltas(),this.openAssistant=!0,this.block=null,this.thinking="",this.output="",!await this.writeStream("run-cursor",null)){this.close();return}this.assistantStartSequence=Number((await(await d()).prepare("SELECT stream_message_seq FROM nodes WHERE node_id = ?").get(this.nodeId)).stream_message_seq)}if(r.type==="message_update"&&r.message.role==="assistant"&&this.openAssistant){const a=r.message.content;if(!Array.isArray(a))return;const o=a.at(-1);if(o&&typeof o=="object"&&"type"in o&&(o.type==="toolCall"?this.block={kind:"tool_call",name:"name"in o&&typeof o.name=="string"?o.name:""}:(o.type==="text"||o.type==="thinking")&&(this.block={kind:o.type})),!await this.writeStream(null,this.block,!0)){this.close();return}const f=a.filter(u=>u?.type==="thinking").map(u=>u.thinking).join(""),_=a.filter(u=>u?.type==="text").map(u=>u.text).join(""),L=f.startsWith(this.thinking)?f.slice(this.thinking.length):f,b=_.startsWith(this.output)?_.slice(this.output.length):_;this.thinking=f,this.output=_,this.pendingThinking+=L,this.pendingOutput+=b,(this.pendingThinking||this.pendingOutput)&&!this.flushTimer&&(this.flushTimer=setTimeout(()=>{this.flushDeltas().catch(u=>c({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:u}))},Y),this.flushTimer.unref())}r.type==="message_end"&&r.message.role==="assistant"&&(await this.flushDeltas(),this.openAssistant=!1,this.block=null,await this.writeStream(null,null))}},"handleFrame");n.on("frame",r=>{this.frames=this.frames.then(()=>s(r)).catch(a=>{this.close(),c({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:a})})}),n.on("error",()=>{}),n.on("close",()=>{this.client===n&&(this.client=void 0,this.discardDeltas(),this.openAssistant=!1,this.block=null,this.released=this.released.then(async()=>{await this.writeStream(null,null)}).catch(()=>{}))}),n.connect()}async flushDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0;const e=this.pendingThinking,i=this.pendingOutput;if(this.pendingThinking="",this.pendingOutput="",!this.openAssistant||!e&&!i)return;(await m(this.nodeId,this.owner,async()=>{if(await(await d()).prepare("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}e&&await g(this.runId,this.nodeId,"node.thinking.delta",{delta:e}),i&&await g(this.runId,this.nodeId,"node.output_text.delta",{delta:i})})).held||this.close()}discardDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0,this.pendingThinking="",this.pendingOutput=""}close(){if(this.closed)return;this.closed=!0,this.discardDeltas(),clearInterval(this.timer),p.delete(this.nodeId),this.released=this.released.then(async()=>{await this.writeStream(null,null),await O(h,this.nodeId,this.owner)}).then(()=>{}).catch(i=>{c({level:"error",event:"daemon.runs.observer_release_failed",node_id:this.nodeId,error:i})});const e=this.client;this.client=void 0,e?.close()}}async function $(t){const e=await N(t);if(e===null)return new D(t,{recordsViewerFaults:!1});const i=await W(e.runner).viewerAddress(e);return i.kind==="machine"?new A(t,()=>U(i.environmentId,t)):i.kind==="unix"?new D(t,{recordsViewerFaults:!1}):new A(t,()=>q(i.url,i.headers))}l($,"viewTransport");async function he(t){const e=await(await d()).prepare("SELECT stream_message_seq FROM node_rows WHERE node_id = ? AND pi_pid IS NOT NULL").get(t);return e?.stream_message_seq==null?null:Number(e.stream_message_seq)}l(he,"openAssistantMessageStartSequence");async function pe(t){const e=await(await d()).prepare("SELECT stream_message_seq, stream_block FROM node_rows WHERE node_id = ? AND pi_pid IS NOT NULL").get(t);return e?.stream_message_seq==null||e.stream_block===null?null:JSON.parse(e.stream_block)}l(pe,"openAssistantBlock");async function fe(){const t=[...p.values()];for(const e of t)e.close();await Promise.all(t.map(e=>e.settlePoll())),await Promise.all([...w.values()].map(e=>e.catch(()=>{})))}l(fe,"closeRunObserversForTests");async function I(t){return await(await d()).prepare("SELECT 1 FROM nodes WHERE node_id = ? AND run_id = ? AND event_cursor IS NOT NULL").get(t,t)!==void 0}l(I,"runRootExists");const w=new Map;async function k(t,e){const i=w.get(t);if(i)return i;if(p.has(t))return;const n=G(t,e).finally(()=>w.delete(t));return w.set(t,n),n}l(k,"ensureRunObserver");async function G(t,e){if(!await I(e))return;const i=y();if(await F(h,t,i,E)!==void 0)try{if(t!==e){const n=await R(t);if(!await(await d()).prepare("SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'child.started' LIMIT 1").get(e,t)&&n&&Date.now()-Date.parse(n.created)<720*60*6e4&&!(await m(t,i,()=>g(e,t,"child.started",{child_node_id:t,kind:n.kind}))).held)return}await v.start(t,e,i)}catch(n){throw await O(h,t,i).catch(()=>{}),n}}l(G,"startRunObserver");async function _e(){const t=new Date(Date.now()-2592e6).toISOString(),e=await(await d()).prepare(`SELECT n.node_id, n.run_id, n.pi_pid, COALESCE(n.outcome_revision, 1) AS revision, e.body_json
|
|
3
3
|
FROM node_rows n
|
|
4
4
|
LEFT JOIN run_events e ON n.pi_pid IS NULL AND e.run_id = n.run_id AND e.node_id = n.node_id
|
|
5
5
|
AND e.type = CASE WHEN n.node_id = n.run_id THEN 'node.settled' ELSE 'child.settled' END
|
|
6
|
-
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 > ? AND n.outcome_reason != 'parked'))`).all(t),i=new Map;for(const
|
|
6
|
+
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 > ? AND n.outcome_reason != 'parked'))`).all(t),i=new Map;for(const s of e){const r=i.get(s.node_id)??{node_id:s.node_id,run_id:s.run_id,reported:!1};s.body_json!==null&&JSON.parse(s.body_json).outcome?.revision===s.revision&&(r.reported=!0),i.set(s.node_id,r)}const n=[...i.values()].filter(s=>!s.reported);for(const s of n)try{await k(s.node_id,s.run_id),S.delete(s.node_id)}catch(r){Q(s.node_id,r)}}l(_e,"pollRunObservers");const S=new Map;function Q(t,e){const i=e instanceof Error?e.message:String(e);S.get(t)!==i&&(S.set(t,i),c({level:"error",event:"daemon.runs.observer_failed",node_id:t,error:e}))}l(Q,"reportObserverFailure");export{fe as closeRunObserversForTests,k as ensureRunObserver,pe as openAssistantBlock,he as openAssistantMessageStartSequence,_e as pollRunObservers};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.582",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
},
|
|
146
146
|
"license": "UNLICENSED",
|
|
147
147
|
"dependencies": {
|
|
148
|
-
"@north-light/identity": "0.3.
|
|
148
|
+
"@north-light/identity": "0.3.582",
|
|
149
149
|
"@earendil-works/chord": "1.1.0",
|
|
150
150
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
151
151
|
"@earendil-works/pi-ai": "1.1.0",
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.582",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/cli",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.582",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"workspaces": [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@milkdown/preset-gfm": "^7.22.3",
|
|
29
29
|
"@milkdown/prose": "^7.22.3",
|
|
30
30
|
"@milkdown/utils": "^7.22.3",
|
|
31
|
-
"@north-light/identity": "0.3.
|
|
31
|
+
"@north-light/identity": "0.3.582",
|
|
32
32
|
"cron-parser": "^5.6.0",
|
|
33
33
|
"esbuild": "^0.27.7",
|
|
34
34
|
"jose": "^6.2.12",
|
|
@@ -11956,17 +11956,17 @@
|
|
|
11956
11956
|
},
|
|
11957
11957
|
"packages/crouter-api": {
|
|
11958
11958
|
"name": "@north-light/api",
|
|
11959
|
-
"version": "0.3.
|
|
11959
|
+
"version": "0.3.582",
|
|
11960
11960
|
"license": "UNLICENSED"
|
|
11961
11961
|
},
|
|
11962
11962
|
"packages/crouter-env-docker": {
|
|
11963
11963
|
"name": "@north-light/env-docker",
|
|
11964
|
-
"version": "0.3.
|
|
11964
|
+
"version": "0.3.582",
|
|
11965
11965
|
"license": "UNLICENSED"
|
|
11966
11966
|
},
|
|
11967
11967
|
"packages/crouter-identity": {
|
|
11968
11968
|
"name": "@north-light/identity",
|
|
11969
|
-
"version": "0.3.
|
|
11969
|
+
"version": "0.3.582",
|
|
11970
11970
|
"license": "UNLICENSED",
|
|
11971
11971
|
"dependencies": {
|
|
11972
11972
|
"jose": "^6.2.1"
|
|
@@ -11974,21 +11974,21 @@
|
|
|
11974
11974
|
},
|
|
11975
11975
|
"packages/crouter-plugin": {
|
|
11976
11976
|
"name": "@north-light/plugin",
|
|
11977
|
-
"version": "0.3.
|
|
11977
|
+
"version": "0.3.582",
|
|
11978
11978
|
"license": "UNLICENSED",
|
|
11979
11979
|
"dependencies": {
|
|
11980
|
-
"@north-light/api": "0.3.
|
|
11981
|
-
"@north-light/identity": "0.3.
|
|
11980
|
+
"@north-light/api": "0.3.582",
|
|
11981
|
+
"@north-light/identity": "0.3.582"
|
|
11982
11982
|
}
|
|
11983
11983
|
},
|
|
11984
11984
|
"packages/crouter-sdk": {
|
|
11985
11985
|
"name": "@north-light/sdk",
|
|
11986
|
-
"version": "0.3.
|
|
11986
|
+
"version": "0.3.582",
|
|
11987
11987
|
"license": "UNLICENSED",
|
|
11988
11988
|
"dependencies": {
|
|
11989
|
-
"@north-light/api": "0.3.
|
|
11990
|
-
"@north-light/identity": "0.3.
|
|
11991
|
-
"@north-light/plugin": "0.3.
|
|
11989
|
+
"@north-light/api": "0.3.582",
|
|
11990
|
+
"@north-light/identity": "0.3.582",
|
|
11991
|
+
"@north-light/plugin": "0.3.582",
|
|
11992
11992
|
"jose": "^6.2.1"
|
|
11993
11993
|
},
|
|
11994
11994
|
"bin": {
|