@lmctl-ai/lmctl 0.2.205 → 0.2.207

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/lmbee.js CHANGED
@@ -63,7 +63,7 @@ Signed in as ${f.user_id}
63
63
  Appkey saved to ${p.appkeyPath} (0600)
64
64
  `),0}catch(u){return t.stderr.write(`error: ${u instanceof Error?u.message:String(u)}
65
65
  `),1}finally{a.close()}}var tv=jt(()=>{KS()});import{spawn as D1}from"node:child_process";import{openSync as M1,mkdirSync as P1,writeFileSync as U1}from"node:fs";import{homedir as F1}from"node:os";import{join as zd}from"node:path";import{mkdirSync as V1,readFileSync as qA,renameSync as J1,writeFileSync as z1}from"node:fs";import{homedir as jA}from"node:os";import{dirname as Q1,join as Qd}from"node:path";var B1=Object.freeze({free:1e6,test:1e7});var Qr=class extends Error{code="APPKEY_NOT_FOUND";constructor(t="no lmctl appkey found; run `lmchat login` on a machine with a browser, or copy ~/.config/lmctl/appkey.json here, or set LMCTL_APPKEY"){super(t),this.name="AppkeyNotFoundError"}},lr=class extends Error{code="APPKEY_VALIDATION_ERROR";status;constructor(t,r={}){super(t),this.name="AppkeyValidationError",this.status=r.status,this.cause=r.cause}},Ms=class extends Error{code="APPKEY_INVALID";source;constructor(t){super(`${t} resolved an invalid lmctl appkey`),this.name="AppkeyInvalidError",this.source=t}},Ps=class extends Error{code="AUTH_API_ERROR";status;constructor(t,r={}){super(t),this.name="AuthApiError",this.status=r.status,this.cause=r.cause}};var HA="https://lmctl.ai/auth",BA=1e4;function Za(e){return e.length>0&&!e.includes(`
66
- `)}function ve(e={}){let t=e.env??process.env,r=e.fs??{readFileSync:(c,l)=>qA(c,l)},n=e.homedir??jA,o=t.LMCTL_APPKEY?.trim();if(o&&Za(o))return{appkey:o,source:"env:LMCTL_APPKEY",envelope:null};let s=t.LMCTL_APPKEY_FILE?.trim();if(s){let c=Xd(r,s,"env:LMCTL_APPKEY_FILE");if(c)return c}let i=WA(t,n),a=Xd(r,i,"file:default");if(a)return a;throw new Qr}async function em(e,t={}){let r=await JA("/whoami",{method:"GET",headers:{authorization:`Bearer ${e}`}},t,lr);if(r.status===401)return{valid:!1};if(r.status!==200)throw new lr(`appkey validation failed with status ${r.status}`,{status:r.status});let n=await YA(r,"validate appkey response",lr);return{valid:!0,userId:Zd(n,"user_id","validate appkey response",lr),label:Zd(n,"label","validate appkey response",lr)}}function Xd(e,t,r){let n;try{n=e.readFileSync(t,"utf8")}catch{return null}let o=n.trim();if(o.length===0)return null;if(o.startsWith("{")){let s;try{s=JSON.parse(o)}catch{s=void 0}if(s&&typeof s=="object"){let i=s;return typeof i.appkey=="string"&&Za(i.appkey.trim())?{appkey:i.appkey.trim(),source:r,envelope:i}:null}}return Za(o)?{appkey:o,source:r,envelope:null}:null}function WA(e,t){let r=e.XDG_CONFIG_HOME?.trim()||Qd(t(),".config");return Qd(r,"lmctl","appkey.json")}function GA(e){let t=e.env??process.env;return(e.authBaseUrl?.trim()||t.LMCTL_AUTH_BASE_URL?.trim()||HA).replace(/\/+$/,"")}function VA(e,t){if(e.fetchImpl)return e.fetchImpl;if(typeof globalThis.fetch=="function")return(r,n)=>globalThis.fetch(r,n);throw new t("global fetch is unavailable; pass fetchImpl explicitly")}async function JA(e,t,r,n){return await zA(e,t,r,n,r.timeoutMs)}async function zA(e,t,r,n,o,s){let i=VA(r,n),a=`${GA(r)}${e}`,c=o??BA,l={...t},u=new AbortController;l.signal=u.signal;let d=setTimeout(()=>{u.abort()},c);try{return await i(a,l)}catch(m){throw u.signal.aborted?s?s():new n(`auth request timed out for ${e} after ${c}ms`,{cause:m}):m instanceof n?m:new n(`auth request failed for ${e}`,{cause:m})}finally{clearTimeout(d)}}async function YA(e,t,r){let n;try{n=await e.json()}catch(o){throw new r(`${t} was not valid JSON`,{cause:o,status:e.status})}if(!n||typeof n!="object"||Array.isArray(n))throw new r(`${t} must be a JSON object`,{status:e.status});return n}function Zd(e,t,r,n){let o=e[t];if(typeof o!="string"||o.length===0)throw new n(`${r} missing string field ${t}`);return o}function Ye(e){return async(...t)=>{throw new Error(`lmmail-client fake: ${e} not stubbed`)}}var ej={listMailboxes:Ye("listMailboxes"),createMailbox:Ye("createMailbox"),deleteMailbox:Ye("deleteMailbox"),sendMessage:Ye("sendMessage"),listMessages:Ye("listMessages"),getRecentMessages:Ye("getRecentMessages"),getMessage:Ye("getMessage"),getMessageMetadata:Ye("getMessageMetadata"),getThread:Ye("getThread"),download:Ye("download"),deleteMessage:Ye("deleteMessage"),registerSite:Ye("registerSite"),resolveSite:Ye("resolveSite"),listSites:Ye("listSites"),setSiteName:Ye("setSiteName"),deleteSiteName:Ye("deleteSiteName"),deleteSite:Ye("deleteSite")};var Bt=class extends Error{status;code;responseBody;constructor(t,r,n,o){super(`${t}: HTTP ${r}${o?` ${o}`:n?` ${n}`:""}`),this.name="LmmailHttpError",this.status=r,this.code=o,this.responseBody=n}};function _t(e){let t=e.apiUrl.replace(/\/+$/,"");if(!t)throw new Error("lmmail API URL is required");if(!e.appkey)throw new Error("lmmail appkey is required");let r=e.fetch??fetch,n={authorization:`Bearer ${e.appkey}`};async function o(A={}){return(await T(`${t}/mailboxes${A.withCounts?"?with_counts=1":""}`,{headers:n},"list mailboxes failed")).mailboxes}async function s(A,I={}){let x=await r(`${t}/mailboxes`,{method:"POST",headers:{...n,"content-type":"application/json"},body:JSON.stringify({mailbox_name:A})});if(x.status===409){let H=await x.text().catch(()=>"");if(I.tolerate409!==!1&&om(H)==="mailbox_exists")return;throw nm("create mailbox failed",x.status,H)}await R(x,"create mailbox failed")}async function i(A){return T(`${t}/mailboxes/${encodeURIComponent(A)}`,{method:"DELETE",headers:n},"delete mailbox failed")}async function a(A){let I=A.attachments??[],x=await T(`${t}/mailboxes/${encodeURIComponent(A.mailbox)}/messages`,{method:"POST",headers:{...n,"content-type":"application/json"},body:JSON.stringify({...A.subject===void 0?{}:{subject:A.subject},body:tm(A.body),attachments:I.map(tm)})},"allocate message failed"),H=[{target:x.body,bytes:A.body.bytes},...x.attachments.map((C,w)=>({target:C,bytes:I[w].bytes}))];for(let{target:C,bytes:w}of H){let b=new FormData;for(let[P,J]of Object.entries(C.fields))b.append(P,J);b.append("file",new Blob([new Uint8Array(w)],{type:C.content_type}),C.name);let N=await r(C.upload_url,{method:"POST",body:b});await R(N,`upload failed for ${C.name}`)}return await T(KA(t,x.finalize_url),{method:"POST",headers:n},"finalize message failed"),x.seq}async function c(A,I={}){let x=new URLSearchParams;if(I.status&&x.set("status",I.status),I.after!==void 0&&x.set("after",String(I.after)),I.wait_s!==void 0){if(!Number.isInteger(I.wait_s)||I.wait_s<0||I.wait_s>20)throw new Error("wait_s must be an integer from 0 through 20");x.set("wait_s",String(I.wait_s))}let H=x.size>0?`?${x.toString()}`:"",C=await T(`${t}/mailboxes/${encodeURIComponent(A)}/messages${H}`,{headers:n},"list messages failed");return{messages:C.messages,next_after:C.next_after}}async function l(A={}){let I=new URLSearchParams;if(A.limit!==void 0){if(!Number.isInteger(A.limit)||A.limit<1||A.limit>50)throw new Error("limit must be an integer from 1 through 50");I.set("limit",String(A.limit))}let x=I.size>0?`?${I.toString()}`:"";return T(`${t}/messages/recent${x}`,{headers:n},"get recent messages failed")}async function u(A,I){return T(`${t}/mailboxes/${encodeURIComponent(A)}/messages/${I}`,{headers:n},"get message failed")}async function d(A,I){let x=await u(A,I);return{...x,body:rm(x.body),attachments:x.attachments.map(rm)}}async function m(A,I){return T(`${t}/mailboxes/${encodeURIComponent(A)}/messages/${I}/thread`,{headers:n},"get thread failed")}async function f(A){let I=await r(A);return await R(I,"download failed"),new Uint8Array(await I.arrayBuffer())}async function p(A,I){await T(`${t}/mailboxes/${encodeURIComponent(A)}/messages/${I}`,{method:"DELETE",headers:n},"delete message failed")}async function h(A,I,x){return await T(`${t}/sites`,{method:"POST",headers:{...n,"content-type":"application/json"},body:JSON.stringify({site_name:A,site_uuid:I,mailbox:x})},"register site failed")}async function g(A){return await T(`${t}/sites/${encodeURIComponent(A)}`,{headers:n},"resolve site failed")}async function _(A={}){let I=new URLSearchParams;if(A.cursor!==void 0&&I.set("cursor",A.cursor),A.limit!==void 0){if(!Number.isInteger(A.limit)||A.limit<1||A.limit>50)throw new Error("limit must be an integer from 1 through 50");I.set("limit",String(A.limit))}let x=I.size>0?`?${I.toString()}`:"";return T(`${t}/sites${x}`,{headers:n},"list sites failed")}async function E(A,I){return T(`${t}/sites/name`,{method:"PUT",headers:{...n,"content-type":"application/json"},body:JSON.stringify({site:A,name:I})},"set site name failed")}async function y(A){return T(`${t}/sites/name`,{method:"DELETE",headers:{...n,"content-type":"application/json"},body:JSON.stringify({site:A})},"delete site name failed")}async function S(A){await T(`${t}/sites/${encodeURIComponent(A)}`,{method:"DELETE",headers:n},"delete site failed")}async function T(A,I,x){let H=await r(A,I);await R(H,x);try{return await H.json()}catch(C){throw new Error(`${x}: invalid JSON response: ${QA(C)}`)}}async function R(A,I){if(A.ok)return;let x=await A.text().catch(()=>"");throw nm(I,A.status,x)}return{listMailboxes:o,createMailbox:s,deleteMailbox:i,sendMessage:a,listMessages:c,getRecentMessages:l,getMessage:u,getMessageMetadata:d,getThread:m,download:f,deleteMessage:p,registerSite:h,resolveSite:g,listSites:_,setSiteName:E,deleteSiteName:y,deleteSite:S}}function tm(e){return{name:e.name,size:e.bytes.byteLength,content_type:e.contentType}}function rm(e){return{name:e.name,size:e.size,content_type:e.content_type}}function nm(e,t,r){return new Bt(e,t,r,om(r))}function om(e){try{let t=JSON.parse(e);return typeof t.error=="string"?t.error:void 0}catch{return}}function KA(e,t){return/^https?:\/\//i.test(t)?t:`${e}${t.startsWith("/")?"":"/"}${t}`}function QA(e){return e instanceof Error?e.message:String(e)}import{execFile as $$}from"node:child_process";import{existsSync as k$}from"node:fs";import{join as x$}from"node:path";import{promisify as R$}from"node:util";import{existsSync as sm}from"node:fs";import{createRequire as XA}from"node:module";import{dirname as ZA}from"node:path";var ec=null;function e$(){return ec===null&&(ec=XA(import.meta.url)("node:sqlite").DatabaseSync),ec}var t$={1:"SQLITE_ERROR",2:"SQLITE_INTERNAL",3:"SQLITE_PERM",4:"SQLITE_ABORT",5:"SQLITE_BUSY",6:"SQLITE_LOCKED",7:"SQLITE_NOMEM",8:"SQLITE_READONLY",9:"SQLITE_INTERRUPT",10:"SQLITE_IOERR",11:"SQLITE_CORRUPT",12:"SQLITE_NOTFOUND",13:"SQLITE_FULL",14:"SQLITE_CANTOPEN",15:"SQLITE_PROTOCOL",16:"SQLITE_EMPTY",17:"SQLITE_SCHEMA",18:"SQLITE_TOOBIG",19:"SQLITE_CONSTRAINT",20:"SQLITE_MISMATCH",21:"SQLITE_MISUSE",22:"SQLITE_NOLFS",23:"SQLITE_AUTH",24:"SQLITE_FORMAT",25:"SQLITE_RANGE",26:"SQLITE_NOTADB",27:"SQLITE_NOTICE",28:"SQLITE_WARNING"},r$={261:"SQLITE_BUSY_RECOVERY",517:"SQLITE_BUSY_SNAPSHOT",773:"SQLITE_BUSY_TIMEOUT",262:"SQLITE_LOCKED_SHAREDCACHE",518:"SQLITE_LOCKED_VTAB",264:"SQLITE_READONLY_RECOVERY",520:"SQLITE_READONLY_CANTLOCK",776:"SQLITE_READONLY_ROLLBACK",1032:"SQLITE_READONLY_DBMOVED",1288:"SQLITE_READONLY_CANTINIT",1544:"SQLITE_READONLY_DIRECTORY",270:"SQLITE_CANTOPEN_NOTEMPDIR",526:"SQLITE_CANTOPEN_ISDIR",782:"SQLITE_CANTOPEN_FULLPATH",1038:"SQLITE_CANTOPEN_CONVPATH",1294:"SQLITE_CANTOPEN_DIRTYWAL",1550:"SQLITE_CANTOPEN_SYMLINK",275:"SQLITE_CONSTRAINT_CHECK",531:"SQLITE_CONSTRAINT_COMMITHOOK",787:"SQLITE_CONSTRAINT_FOREIGNKEY",1043:"SQLITE_CONSTRAINT_FUNCTION",1299:"SQLITE_CONSTRAINT_NOTNULL",1555:"SQLITE_CONSTRAINT_PRIMARYKEY",1811:"SQLITE_CONSTRAINT_TRIGGER",2067:"SQLITE_CONSTRAINT_UNIQUE",2323:"SQLITE_CONSTRAINT_VTAB",2579:"SQLITE_CONSTRAINT_ROWID",2835:"SQLITE_CONSTRAINT_PINNED",3091:"SQLITE_CONSTRAINT_DATATYPE"};function n$(e){return r$[e]??t$[e&255]??`SQLITE_UNKNOWN_${e}`}var o$="SQLite3 can only bind numbers, strings, bigints, buffers, and null";function Wt(e){if(e!==null&&typeof e=="object"){let t=e;if(typeof t.errcode=="number")throw t.code=n$(t.errcode),e;if(t.code==="ERR_INVALID_ARG_TYPE"&&/cannot be bound/.test(String(t.message)))throw new TypeError(o$);if(t.code==="ERR_INVALID_STATE"&&/database is not open/.test(String(t.message)))throw new TypeError("The database connection is not open")}throw e}function s$(){let e="unable to open database file";return Object.assign(new Error(e),{code:"SQLITE_CANTOPEN",errcode:14,errstr:e})}function im(e){return e instanceof Uint8Array&&!Buffer.isBuffer(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e}function i$(e){if(e==null)return e;if(Array.isArray(e))return e.map(im);if(typeof e=="object"){let t={};for(let[r,n]of Object.entries(e))t[r]=im(n);return t}return e}function a$(e){if(e===null||typeof e!="object"||Array.isArray(e)||e instanceof Uint8Array)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Us(e){return e.map((t,r)=>{if(t===void 0)return null;if(r===0&&a$(t)){let n={};for(let[o,s]of Object.entries(t))n[o]=s===void 0?null:s;return n}return t})}var tc=class{handle;pluckMode=!1;arrayMode=!1;constructor(t){this.handle=t,this.handle.setAllowBareNamedParameters(!0),this.handle.setAllowUnknownNamedParameters(!0)}get source(){return this.handle.sourceSQL}run(...t){try{let r=this.handle.run(...Us(t));return{changes:Number(r.changes),lastInsertRowid:Number(r.lastInsertRowid)}}catch(r){Wt(r)}}get(...t){try{return this.project(this.handle.get(...Us(t)))}catch(r){Wt(r)}}all(...t){try{return this.handle.all(...Us(t)).map(r=>this.project(r))}catch(r){Wt(r)}}*iterate(...t){let r;try{r=this.handle.iterate(...Us(t))}catch(n){Wt(n)}for(;;){let n;try{n=r.next()}catch(o){Wt(o)}if(n.done)return;yield this.project(n.value)}}raw(t=!0){return this.arrayMode=t,this.handle.setReturnArrays(t||this.pluckMode),this}pluck(t=!0){return this.pluckMode=t,this.handle.setReturnArrays(t||this.arrayMode),this}project(t){let r=i$(t);return this.pluckMode&&Array.isArray(r)?r[0]:r}},rc=class{name;memory;readonly;handle;savepointId=0;constructor(t,r={}){let n=t===":memory:"||t==="";if(r.readonly===!0&&n)throw new TypeError("In-memory/temporary databases cannot be readonly");if(!n&&!sm(ZA(t)))throw new TypeError("Cannot open database because the directory does not exist");if(r.fileMustExist===!0&&!n&&!sm(t))throw s$();this.name=t,this.memory=n,this.readonly=r.readonly===!0;try{this.handle=new(e$())(t,{readOnly:this.readonly,timeout:r.timeout??5e3,enableForeignKeyConstraints:r.foreignKeys??!0})}catch(o){Wt(o)}}get open(){return this.handle.isOpen}get inTransaction(){return this.handle.isTransaction}prepare(t){try{return new tc(this.handle.prepare(t))}catch(r){Wt(r)}}exec(t){try{return this.handle.exec(t),this}catch(r){Wt(r)}}pragma(t,r){let n=this.prepare(`PRAGMA ${t}`);return r?.simple===!0?n.pluck().get():n.all()}transaction(t){let r=o=>(...s)=>this.runTransaction(o,t,s),n=r("BEGIN");return n.default=r("BEGIN"),n.deferred=r("BEGIN DEFERRED"),n.immediate=r("BEGIN IMMEDIATE"),n.exclusive=r("BEGIN EXCLUSIVE"),n}serialize(){try{let t=this.handle.serialize();return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}catch(t){Wt(t)}}close(){if(!this.handle.isOpen)return this;try{return this.handle.close(),this}catch(t){Wt(t)}}runTransaction(t,r,n){if(!this.inTransaction){this.exec(t);try{let s=r(...n);return this.exec("COMMIT"),s}catch(s){if(this.inTransaction)try{this.exec("ROLLBACK")}catch(i){if(!c$(i))throw i}throw s}}let o=`lmbee_sp_${this.savepointId+=1}`;this.exec(`SAVEPOINT ${o}`);try{let s=r(...n);return this.exec(`RELEASE ${o}`),s}catch(s){if(this.inTransaction)try{this.exec(`ROLLBACK TO ${o}`),this.exec(`RELEASE ${o}`)}catch(i){if(!l$(i))throw i}throw s}}};function c$(e){return e instanceof Error&&/cannot rollback - no transaction is active/i.test(e.message)}function l$(e){return e instanceof Error&&/no such savepoint:/i.test(e.message)}var wt=rc;import{existsSync as oc,lstatSync as u$,mkdirSync as d$,readFileSync as dm,realpathSync as am}from"node:fs";import{basename as m$,dirname as sc,isAbsolute as f$,join as p$,relative as h$,resolve as cm}from"node:path";import{fileURLToPath as g$}from"node:url";var mm=p$(sc(g$(import.meta.url)),"schema.sql");function No(e){if(e!==void 0&&e!=="")return e;let t=process.env.LMBEE_DB;if(t)return t;throw new Error("No lmbee database selected: pass an explicit database path or set LMBEE_DB to the intended existing database. The retired ~/.lmbee/state.db default is no longer used.")}function _$(e){if(e.startsWith("~"))throw new Error(`Refusing to open the lmbee database at "${e}": lmbee does not expand "~" in database paths, so this would be created as a literal directory named "~" under the current working directory. Use an absolute path instead (for example ~/.lmbee/state.db). Note for systemd units: Environment= expands neither "~" nor "$HOME", so write the absolute path literally there too.`)}function w$(e,t){if(!(e===":memory:"||oc(e)))throw new Error(`Refusing to create the lmbee database at "${e}": ${t} points at non-existent "${e}", and a typo is indistinguishable from a fresh install. To provision a new database here, \`touch "${e}"\` first, then retry, or point ${t} at an existing database.`)}function y$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(queue)").all();if(r.length===0)return;let n=new Set(r.map(s=>s.name));n.has("subject_id")||e.exec("ALTER TABLE queue ADD COLUMN subject_id TEXT"),n.has("dedupe_key")||e.exec("ALTER TABLE queue ADD COLUMN dedupe_key TEXT"),e.prepare(`SELECT name FROM pragma_index_list('queue') WHERE "unique" = 1 AND partial = 0`).all().some(s=>{let i=e.prepare("SELECT name FROM pragma_index_info(?) ORDER BY seqno").all(s.name);return i.length===1&&i[0].name==="dedupe_key"})||e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_queue_dedupe_key ON queue(dedupe_key)"),n.has("delivered_via_escalation")||e.exec("ALTER TABLE queue ADD COLUMN delivered_via_escalation INTEGER NOT NULL DEFAULT 0"),n.has("escalation_claimed_ts")||e.exec("ALTER TABLE queue ADD COLUMN escalation_claimed_ts TEXT"),n.has("escalation_claim_token")||e.exec("ALTER TABLE queue ADD COLUMN escalation_claim_token TEXT"),n.has("escalation_only")||e.exec("ALTER TABLE queue ADD COLUMN escalation_only INTEGER NOT NULL DEFAULT 0"),n.has("admission_fingerprint")||e.exec("ALTER TABLE queue ADD COLUMN admission_fingerprint TEXT"),n.has("expects_response")||e.exec("ALTER TABLE queue ADD COLUMN expects_response INTEGER NOT NULL DEFAULT 0"),n.has("to_alias")||e.exec("ALTER TABLE queue ADD COLUMN to_alias TEXT"),n.has("retracted_ts")||e.exec("ALTER TABLE queue ADD COLUMN retracted_ts TEXT"),n.has("retracted_reason")||e.exec("ALTER TABLE queue ADD COLUMN retracted_reason TEXT"),n.has("retraction_notice")||e.exec("ALTER TABLE queue ADD COLUMN retraction_notice INTEGER NOT NULL DEFAULT 0"),n.has("in_reply_to")||e.exec("ALTER TABLE queue ADD COLUMN in_reply_to INTEGER"),n.has("operator_priority")||e.exec("ALTER TABLE queue ADD COLUMN operator_priority INTEGER NOT NULL DEFAULT 0"),n.has("merged_into_id")||e.exec("ALTER TABLE queue ADD COLUMN merged_into_id INTEGER")}).immediate()}function E$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(team_progress)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("last_miniplayer_reply_hash")||e.exec("ALTER TABLE team_progress ADD COLUMN last_miniplayer_reply_hash TEXT"),n.has("blocked_surfaced_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN blocked_surfaced_ts TEXT"),n.has("last_escalation_attempt_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN last_escalation_attempt_ts TEXT"),n.has("escalation_attempt_count")||e.exec("ALTER TABLE team_progress ADD COLUMN escalation_attempt_count INTEGER NOT NULL DEFAULT 0"),n.has("fault_surfaced_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN fault_surfaced_ts TEXT"),n.has("epic_closed_surfaced_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN epic_closed_surfaced_ts TEXT"),n.has("quota_exhausted_last_seen_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN quota_exhausted_last_seen_ts TEXT"),n.has("quota_exhausted_message")||e.exec("ALTER TABLE team_progress ADD COLUMN quota_exhausted_message TEXT"),n.has("miniplayer_verdict_label")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_label TEXT"),n.has("miniplayer_verdict_reason")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_reason TEXT"),n.has("miniplayer_verdict_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_ts TEXT"),n.has("miniplayer_verdict_input_hash")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_input_hash TEXT"),n.has("miniplayer_verdict_structural_hash")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_structural_hash TEXT"),n.has("holder_watch_pid")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_pid INTEGER"),n.has("holder_watch_started_at")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_started_at TEXT"),n.has("holder_watch_cpu_ticks")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_cpu_ticks INTEGER"),n.has("holder_watch_observed_at")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_observed_at TEXT"),n.has("holder_watch_low_cpu_streak")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_low_cpu_streak INTEGER"),n.has("hung_holder_flagged_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN hung_holder_flagged_ts TEXT"),n.has("hung_holder_reason")||e.exec("ALTER TABLE team_progress ADD COLUMN hung_holder_reason TEXT"),n.has("last_cli_activity_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN last_cli_activity_ts TEXT")}).immediate()}function b$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(cron_jobs)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("last_fire_error")||e.exec("ALTER TABLE cron_jobs ADD COLUMN last_fire_error TEXT"),n.has("running_systemd_unit")||e.exec("ALTER TABLE cron_jobs ADD COLUMN running_systemd_unit TEXT"),n.has("timezone")||e.exec("ALTER TABLE cron_jobs ADD COLUMN timezone TEXT"),n.has("provider")||e.exec("ALTER TABLE cron_jobs ADD COLUMN provider TEXT"),n.has("model")||e.exec("ALTER TABLE cron_jobs ADD COLUMN model TEXT"),n.has("working_directory")||e.exec("ALTER TABLE cron_jobs ADD COLUMN working_directory TEXT"),n.has("escalation_owner")||e.exec("ALTER TABLE cron_jobs ADD COLUMN escalation_owner TEXT"),n.has("session_teamfile")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_teamfile TEXT"),n.has("session_alias")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_alias TEXT"),n.has("session_seeded_at")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_seeded_at TEXT"),n.has("session_generation")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_generation INTEGER NOT NULL DEFAULT 0")}).immediate()}function T$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(entities)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("delivered_ts")||e.exec("ALTER TABLE entities ADD COLUMN delivered_ts TEXT"),n.has("review_time")||e.exec("ALTER TABLE entities ADD COLUMN review_time TEXT"),n.has("needs_review")||e.exec("ALTER TABLE entities ADD COLUMN needs_review INTEGER NOT NULL DEFAULT 0 CHECK(needs_review IN (0,1))"),n.has("review_reason")||e.exec("ALTER TABLE entities ADD COLUMN review_reason TEXT"),n.has("review_input_hash")||e.exec("ALTER TABLE entities ADD COLUMN review_input_hash TEXT"),n.has("hold_until")||e.exec("ALTER TABLE entities ADD COLUMN hold_until TEXT"),n.has("hold_reason")||e.exec("ALTER TABLE entities ADD COLUMN hold_reason TEXT"),n.has("blocked_on")||e.exec("ALTER TABLE entities ADD COLUMN blocked_on TEXT")}).immediate()}function S$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(mail_ledger)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("ack_sent_ts")||e.exec("ALTER TABLE mail_ledger ADD COLUMN ack_sent_ts TEXT"),n.has("delivery_error")||e.exec("ALTER TABLE mail_ledger ADD COLUMN delivery_error TEXT"),n.has("delivery_error_ts")||e.exec("ALTER TABLE mail_ledger ADD COLUMN delivery_error_ts TEXT")}).immediate()}function ic(e){let t=process.env.LMBEE_TEST_DB_ROOT;if(!t||e===":memory:")return;let r=[],n=cm(e);for(;u$(n,{throwIfNoEntry:!1})===void 0;){r.unshift(m$(n));let i=sc(n);if(i===n)throw new Error("Cannot resolve test database path");n=i}let o=cm(am(n),...r),s=h$(am(t),o);if(s===".."||s.startsWith("../")||s.startsWith("..\\")||f$(s))throw new Error(`Database path is outside the test database root: ${e}`)}function lm(e){let t=o=>e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(o)!==void 0,r=o=>e.prepare(`PRAGMA table_info(${o})`).all(),n;for(let o of["queue_responses","chat_tasks","chat_messages","chat_message_task_reassignments"])if(t(o)){n=`legacy table '${o}'`;break}if(n===void 0&&t("answers")){let o=new Set(r("answers").map(s=>s.name));o.has("request_queue_id")?n="legacy column 'answers.request_queue_id'":o.has("superseded_at")||(n="legacy 'answers' shape: missing column 'superseded_at'")}if(n===void 0&&t("queue")){let o=r("queue"),s=new Set(o.map(i=>i.name));s.has("team")?n="legacy column 'queue.team'":s.has("to_id")?o.some(i=>i.name==="from_id"&&i.notnull!==1)?n="legacy 'queue' shape: from_id is still nullable":s.has("restart_nudge_sent_ts")&&(n="legacy column 'queue.restart_nudge_sent_ts'"):n="legacy 'queue' shape: missing column 'to_id'"}if(n===void 0&&t("cron_jobs")){let o=e.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'cron_jobs'").get();(o===void 0||!o.sql.includes("'miniplayer'"))&&(n="legacy 'cron_jobs' CHECK constraint predates 'miniplayer'")}if(n===void 0&&t("cron_jobs")){let o=e.prepare("SELECT id, action_payload FROM cron_jobs WHERE action_kind = 'enqueue'").all();for(let s of o){let i;try{i=JSON.parse(s.action_payload)}catch{i=void 0}let a=typeof i=="object"&&i!==null?i.prompt:void 0;if(typeof a!="string"||a.trim().length===0){n=`legacy 'cron_jobs' enqueue payload (id ${s.id}) predates the 'prompt' vocabulary`;break}}}if(n===void 0&&t("team_progress")&&new Set(r("team_progress").map(s=>s.name)).has("last_scan_head")&&(n="legacy column 'team_progress.last_scan_head'"),n===void 0&&t("cron_runs")&&(new Set(r("cron_runs").map(s=>s.name)).has("execution_state")||(n="legacy 'cron_runs' shape: missing column 'execution_state'")),n===void 0&&t("rate_limit_policy_log")){let o=e.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'rate_limit_policy_log'").get();(o===void 0||!o.sql.includes("'confirmed_would_fire_policy_disabled'"))&&(n="legacy 'rate_limit_policy_log' CHECK constraint predates 'confirmed_would_fire_policy_disabled'")}if(n===void 0&&t("rate_limit_policy_arm")&&(new Set(r("rate_limit_policy_arm").map(s=>s.name)).has("armed_used_fraction")||(n="legacy 'rate_limit_policy_arm' shape: missing column 'armed_used_fraction'")),n!==void 0)throw new Error(`Refusing to open this lmbee state.db: abandoned pre-v14 lmbee schema shape (${n}). Per the operator's 2026-10-01 shared-database decision, lmbee now shares lmctl's state.db and every pre-existing lmbee-only database is abandoned -- there is no data migration, ever. Do not remove a shared lmctl database. Check LMBEE_DB and the database ownership; point lmbee at the intended compatible database. Preserve this file for operator review.`)}var Fs=62;function um(e){let t=e.pragma("user_version",{simple:!0});if(t<=Fs)return;let r;if(e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_meta'").get()!==void 0){let o=new Set(e.prepare("PRAGMA table_info(schema_meta)").all().map(s=>s.name));if(o.has("key")&&o.has("value")){let s=e.prepare("SELECT value FROM schema_meta WHERE key = 'min_reader_version'").get();typeof s?.value=="string"&&(r=s.value)}}let n;if(r===void 0)n="schema_meta.min_reader_version is absent";else if(!/^[1-9]\d*$/.test(r))n=`schema_meta.min_reader_version=${JSON.stringify(r)} is malformed (not a canonical decimal integer)`;else if(Number(r)>Fs)n=`schema_meta.min_reader_version=${r} declares a breaking floor above ${Fs}`;else return;throw new Error(`Refusing to open the shared state.db: it was migrated by a newer lmctl with breaking changes (user_version=${t} exceeds the newest lmctl schema version this lmbee build understands, ${Fs}, and ${n}). Upgrade lmbee to a build that understands the newer lmctl schema before opening this database again. lmbee never writes user_version or schema_meta, so the file is untouched.`)}var nc;function v$(){return nc===void 0&&(nc=[...dm(mm,"utf8").matchAll(/CREATE TABLE IF NOT EXISTS (\w+)/gi)].map(t=>t[1])),nc}function A$(e,t){let r=new Set(e.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map(o=>o.name)),n=v$().filter(o=>!r.has(o));if(n.length!==0)throw new Error(`Refusing a read-only open of "${t}": required lmbee schema is missing (no table${n.length===1?"":"s"}: ${n.join(", ")}), and a read-only handle cannot create it. Run any writable lmbee command (or start the daemon) once against this database to provision it, then retry.`)}function qs(e,t={}){let r=No(e);_$(r);let n=!e&&typeof process.env.LMBEE_DB=="string"&&process.env.LMBEE_DB!=="";if(n&&w$(r,"LMBEE_DB"),ic(r),t.readOnly&&r===":memory:")throw new Error("Refusing a read-only open of ':memory:': an in-memory database starts empty on every open, so the required lmbee schema can never be present and a read-only handle cannot create it.");if(t.readOnly&&r!==":memory:"){if(!oc(r))throw new Error(`Refusing a read-only open of "${r}": the file does not exist, so the required lmbee schema is missing. Run any writable lmbee command (or start the daemon) once against this database to provision it, then retry.`);let a=new wt(r,{readonly:!0,fileMustExist:!0});try{lm(a),um(a),a.pragma("busy_timeout = 5000"),A$(a,r)}catch(c){throw a.close(),c}return{path:r,db:a,close:()=>a.close()}}if(r!==":memory:"){let a=sc(r);oc(a)||d$(a,{recursive:!0})}let o=new wt(r,n?{fileMustExist:!0}:void 0);try{lm(o),um(o)}catch(a){throw o.close(),a}o.pragma("journal_mode = WAL"),o.pragma("busy_timeout = 5000");let s=dm(mm,"utf8"),i=o.transaction(()=>{y$(o),E$(o),S$(o),T$(o),b$(o),o.exec(s)});try{i.immediate()}catch(a){throw o.close(),a}return{path:r,db:o,close:()=>o.close()}}function qe(e,t){return e.prepare("SELECT * FROM team_state WHERE team = ?").get(t)??null}function fm(e,t){let r=qe(e,t);return r===null?{kind:"never-observed"}:{kind:"observed",value:r,observedAt:r.last_ts,changedAt:r.changed_ts}}function ur(e,t,r,n){let o=new Date(n).toISOString(),s=qe(e,t),i=s&&s.status===r?s.changed_ts:o;e.prepare(`INSERT INTO team_state(team, status, changed_ts, last_ts) VALUES (?, ?, ?, ?)
66
+ `)}function ve(e={}){let t=e.env??process.env,r=e.fs??{readFileSync:(c,l)=>qA(c,l)},n=e.homedir??jA,o=t.LMCTL_APPKEY?.trim();if(o&&Za(o))return{appkey:o,source:"env:LMCTL_APPKEY",envelope:null};let s=t.LMCTL_APPKEY_FILE?.trim();if(s){let c=Xd(r,s,"env:LMCTL_APPKEY_FILE");if(c)return c}let i=WA(t,n),a=Xd(r,i,"file:default");if(a)return a;throw new Qr}async function em(e,t={}){let r=await JA("/whoami",{method:"GET",headers:{authorization:`Bearer ${e}`}},t,lr);if(r.status===401)return{valid:!1};if(r.status!==200)throw new lr(`appkey validation failed with status ${r.status}`,{status:r.status});let n=await YA(r,"validate appkey response",lr);return{valid:!0,userId:Zd(n,"user_id","validate appkey response",lr),label:Zd(n,"label","validate appkey response",lr)}}function Xd(e,t,r){let n;try{n=e.readFileSync(t,"utf8")}catch{return null}let o=n.trim();if(o.length===0)return null;if(o.startsWith("{")){let s;try{s=JSON.parse(o)}catch{s=void 0}if(s&&typeof s=="object"){let i=s;return typeof i.appkey=="string"&&Za(i.appkey.trim())?{appkey:i.appkey.trim(),source:r,envelope:i}:null}}return Za(o)?{appkey:o,source:r,envelope:null}:null}function WA(e,t){let r=e.XDG_CONFIG_HOME?.trim()||Qd(t(),".config");return Qd(r,"lmctl","appkey.json")}function GA(e){let t=e.env??process.env;return(e.authBaseUrl?.trim()||t.LMCTL_AUTH_BASE_URL?.trim()||HA).replace(/\/+$/,"")}function VA(e,t){if(e.fetchImpl)return e.fetchImpl;if(typeof globalThis.fetch=="function")return(r,n)=>globalThis.fetch(r,n);throw new t("global fetch is unavailable; pass fetchImpl explicitly")}async function JA(e,t,r,n){return await zA(e,t,r,n,r.timeoutMs)}async function zA(e,t,r,n,o,s){let i=VA(r,n),a=`${GA(r)}${e}`,c=o??BA,l={...t},u=new AbortController;l.signal=u.signal;let d=setTimeout(()=>{u.abort()},c);try{return await i(a,l)}catch(m){throw u.signal.aborted?s?s():new n(`auth request timed out for ${e} after ${c}ms`,{cause:m}):m instanceof n?m:new n(`auth request failed for ${e}`,{cause:m})}finally{clearTimeout(d)}}async function YA(e,t,r){let n;try{n=await e.json()}catch(o){throw new r(`${t} was not valid JSON`,{cause:o,status:e.status})}if(!n||typeof n!="object"||Array.isArray(n))throw new r(`${t} must be a JSON object`,{status:e.status});return n}function Zd(e,t,r,n){let o=e[t];if(typeof o!="string"||o.length===0)throw new n(`${r} missing string field ${t}`);return o}function Ye(e){return async(...t)=>{throw new Error(`lmmail-client fake: ${e} not stubbed`)}}var ej={listMailboxes:Ye("listMailboxes"),createMailbox:Ye("createMailbox"),deleteMailbox:Ye("deleteMailbox"),sendMessage:Ye("sendMessage"),listMessages:Ye("listMessages"),getRecentMessages:Ye("getRecentMessages"),getMessage:Ye("getMessage"),getMessageMetadata:Ye("getMessageMetadata"),getThread:Ye("getThread"),download:Ye("download"),deleteMessage:Ye("deleteMessage"),registerSite:Ye("registerSite"),resolveSite:Ye("resolveSite"),listSites:Ye("listSites"),setSiteName:Ye("setSiteName"),deleteSiteName:Ye("deleteSiteName"),deleteSite:Ye("deleteSite")};var Bt=class extends Error{status;code;responseBody;constructor(t,r,n,o){super(`${t}: HTTP ${r}${o?` ${o}`:n?` ${n}`:""}`),this.name="LmmailHttpError",this.status=r,this.code=o,this.responseBody=n}};function _t(e){let t=e.apiUrl.replace(/\/+$/,"");if(!t)throw new Error("lmmail API URL is required");if(!e.appkey)throw new Error("lmmail appkey is required");let r=e.fetch??fetch,n={authorization:`Bearer ${e.appkey}`};async function o(A={}){return(await T(`${t}/mailboxes${A.withCounts?"?with_counts=1":""}`,{headers:n},"list mailboxes failed")).mailboxes}async function s(A,I={}){let x=await r(`${t}/mailboxes`,{method:"POST",headers:{...n,"content-type":"application/json"},body:JSON.stringify({mailbox_name:A})});if(x.status===409){let H=await x.text().catch(()=>"");if(I.tolerate409!==!1&&om(H)==="mailbox_exists")return;throw nm("create mailbox failed",x.status,H)}await R(x,"create mailbox failed")}async function i(A){return T(`${t}/mailboxes/${encodeURIComponent(A)}`,{method:"DELETE",headers:n},"delete mailbox failed")}async function a(A){let I=A.attachments??[],x=await T(`${t}/mailboxes/${encodeURIComponent(A.mailbox)}/messages`,{method:"POST",headers:{...n,"content-type":"application/json"},body:JSON.stringify({...A.subject===void 0?{}:{subject:A.subject},body:tm(A.body),attachments:I.map(tm)})},"allocate message failed"),H=[{target:x.body,bytes:A.body.bytes},...x.attachments.map((C,w)=>({target:C,bytes:I[w].bytes}))];for(let{target:C,bytes:w}of H){let b=new FormData;for(let[M,W]of Object.entries(C.fields))b.append(M,W);b.append("file",new Blob([new Uint8Array(w)],{type:C.content_type}),C.name);let N=await r(C.upload_url,{method:"POST",body:b});await R(N,`upload failed for ${C.name}`)}return await T(KA(t,x.finalize_url),{method:"POST",headers:n},"finalize message failed"),x.seq}async function c(A,I={}){let x=new URLSearchParams;if(I.status&&x.set("status",I.status),I.after!==void 0&&x.set("after",String(I.after)),I.wait_s!==void 0){if(!Number.isInteger(I.wait_s)||I.wait_s<0||I.wait_s>20)throw new Error("wait_s must be an integer from 0 through 20");x.set("wait_s",String(I.wait_s))}let H=x.size>0?`?${x.toString()}`:"",C=await T(`${t}/mailboxes/${encodeURIComponent(A)}/messages${H}`,{headers:n},"list messages failed");return{messages:C.messages,next_after:C.next_after}}async function l(A={}){let I=new URLSearchParams;if(A.limit!==void 0){if(!Number.isInteger(A.limit)||A.limit<1||A.limit>50)throw new Error("limit must be an integer from 1 through 50");I.set("limit",String(A.limit))}let x=I.size>0?`?${I.toString()}`:"";return T(`${t}/messages/recent${x}`,{headers:n},"get recent messages failed")}async function u(A,I){return T(`${t}/mailboxes/${encodeURIComponent(A)}/messages/${I}`,{headers:n},"get message failed")}async function d(A,I){let x=await u(A,I);return{...x,body:rm(x.body),attachments:x.attachments.map(rm)}}async function m(A,I){return T(`${t}/mailboxes/${encodeURIComponent(A)}/messages/${I}/thread`,{headers:n},"get thread failed")}async function f(A){let I=await r(A);return await R(I,"download failed"),new Uint8Array(await I.arrayBuffer())}async function p(A,I){await T(`${t}/mailboxes/${encodeURIComponent(A)}/messages/${I}`,{method:"DELETE",headers:n},"delete message failed")}async function h(A,I,x){return await T(`${t}/sites`,{method:"POST",headers:{...n,"content-type":"application/json"},body:JSON.stringify({site_name:A,site_uuid:I,mailbox:x})},"register site failed")}async function g(A){return await T(`${t}/sites/${encodeURIComponent(A)}`,{headers:n},"resolve site failed")}async function _(A={}){let I=new URLSearchParams;if(A.cursor!==void 0&&I.set("cursor",A.cursor),A.limit!==void 0){if(!Number.isInteger(A.limit)||A.limit<1||A.limit>50)throw new Error("limit must be an integer from 1 through 50");I.set("limit",String(A.limit))}let x=I.size>0?`?${I.toString()}`:"";return T(`${t}/sites${x}`,{headers:n},"list sites failed")}async function E(A,I){return T(`${t}/sites/name`,{method:"PUT",headers:{...n,"content-type":"application/json"},body:JSON.stringify({site:A,name:I})},"set site name failed")}async function y(A){return T(`${t}/sites/name`,{method:"DELETE",headers:{...n,"content-type":"application/json"},body:JSON.stringify({site:A})},"delete site name failed")}async function S(A){await T(`${t}/sites/${encodeURIComponent(A)}`,{method:"DELETE",headers:n},"delete site failed")}async function T(A,I,x){let H=await r(A,I);await R(H,x);try{return await H.json()}catch(C){throw new Error(`${x}: invalid JSON response: ${QA(C)}`)}}async function R(A,I){if(A.ok)return;let x=await A.text().catch(()=>"");throw nm(I,A.status,x)}return{listMailboxes:o,createMailbox:s,deleteMailbox:i,sendMessage:a,listMessages:c,getRecentMessages:l,getMessage:u,getMessageMetadata:d,getThread:m,download:f,deleteMessage:p,registerSite:h,resolveSite:g,listSites:_,setSiteName:E,deleteSiteName:y,deleteSite:S}}function tm(e){return{name:e.name,size:e.bytes.byteLength,content_type:e.contentType}}function rm(e){return{name:e.name,size:e.size,content_type:e.content_type}}function nm(e,t,r){return new Bt(e,t,r,om(r))}function om(e){try{let t=JSON.parse(e);return typeof t.error=="string"?t.error:void 0}catch{return}}function KA(e,t){return/^https?:\/\//i.test(t)?t:`${e}${t.startsWith("/")?"":"/"}${t}`}function QA(e){return e instanceof Error?e.message:String(e)}import{execFile as $$}from"node:child_process";import{existsSync as k$}from"node:fs";import{join as x$}from"node:path";import{promisify as R$}from"node:util";import{existsSync as sm}from"node:fs";import{createRequire as XA}from"node:module";import{dirname as ZA}from"node:path";var ec=null;function e$(){return ec===null&&(ec=XA(import.meta.url)("node:sqlite").DatabaseSync),ec}var t$={1:"SQLITE_ERROR",2:"SQLITE_INTERNAL",3:"SQLITE_PERM",4:"SQLITE_ABORT",5:"SQLITE_BUSY",6:"SQLITE_LOCKED",7:"SQLITE_NOMEM",8:"SQLITE_READONLY",9:"SQLITE_INTERRUPT",10:"SQLITE_IOERR",11:"SQLITE_CORRUPT",12:"SQLITE_NOTFOUND",13:"SQLITE_FULL",14:"SQLITE_CANTOPEN",15:"SQLITE_PROTOCOL",16:"SQLITE_EMPTY",17:"SQLITE_SCHEMA",18:"SQLITE_TOOBIG",19:"SQLITE_CONSTRAINT",20:"SQLITE_MISMATCH",21:"SQLITE_MISUSE",22:"SQLITE_NOLFS",23:"SQLITE_AUTH",24:"SQLITE_FORMAT",25:"SQLITE_RANGE",26:"SQLITE_NOTADB",27:"SQLITE_NOTICE",28:"SQLITE_WARNING"},r$={261:"SQLITE_BUSY_RECOVERY",517:"SQLITE_BUSY_SNAPSHOT",773:"SQLITE_BUSY_TIMEOUT",262:"SQLITE_LOCKED_SHAREDCACHE",518:"SQLITE_LOCKED_VTAB",264:"SQLITE_READONLY_RECOVERY",520:"SQLITE_READONLY_CANTLOCK",776:"SQLITE_READONLY_ROLLBACK",1032:"SQLITE_READONLY_DBMOVED",1288:"SQLITE_READONLY_CANTINIT",1544:"SQLITE_READONLY_DIRECTORY",270:"SQLITE_CANTOPEN_NOTEMPDIR",526:"SQLITE_CANTOPEN_ISDIR",782:"SQLITE_CANTOPEN_FULLPATH",1038:"SQLITE_CANTOPEN_CONVPATH",1294:"SQLITE_CANTOPEN_DIRTYWAL",1550:"SQLITE_CANTOPEN_SYMLINK",275:"SQLITE_CONSTRAINT_CHECK",531:"SQLITE_CONSTRAINT_COMMITHOOK",787:"SQLITE_CONSTRAINT_FOREIGNKEY",1043:"SQLITE_CONSTRAINT_FUNCTION",1299:"SQLITE_CONSTRAINT_NOTNULL",1555:"SQLITE_CONSTRAINT_PRIMARYKEY",1811:"SQLITE_CONSTRAINT_TRIGGER",2067:"SQLITE_CONSTRAINT_UNIQUE",2323:"SQLITE_CONSTRAINT_VTAB",2579:"SQLITE_CONSTRAINT_ROWID",2835:"SQLITE_CONSTRAINT_PINNED",3091:"SQLITE_CONSTRAINT_DATATYPE"};function n$(e){return r$[e]??t$[e&255]??`SQLITE_UNKNOWN_${e}`}var o$="SQLite3 can only bind numbers, strings, bigints, buffers, and null";function Wt(e){if(e!==null&&typeof e=="object"){let t=e;if(typeof t.errcode=="number")throw t.code=n$(t.errcode),e;if(t.code==="ERR_INVALID_ARG_TYPE"&&/cannot be bound/.test(String(t.message)))throw new TypeError(o$);if(t.code==="ERR_INVALID_STATE"&&/database is not open/.test(String(t.message)))throw new TypeError("The database connection is not open")}throw e}function s$(){let e="unable to open database file";return Object.assign(new Error(e),{code:"SQLITE_CANTOPEN",errcode:14,errstr:e})}function im(e){return e instanceof Uint8Array&&!Buffer.isBuffer(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e}function i$(e){if(e==null)return e;if(Array.isArray(e))return e.map(im);if(typeof e=="object"){let t={};for(let[r,n]of Object.entries(e))t[r]=im(n);return t}return e}function a$(e){if(e===null||typeof e!="object"||Array.isArray(e)||e instanceof Uint8Array)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Us(e){return e.map((t,r)=>{if(t===void 0)return null;if(r===0&&a$(t)){let n={};for(let[o,s]of Object.entries(t))n[o]=s===void 0?null:s;return n}return t})}var tc=class{handle;pluckMode=!1;arrayMode=!1;constructor(t){this.handle=t,this.handle.setAllowBareNamedParameters(!0),this.handle.setAllowUnknownNamedParameters(!0)}get source(){return this.handle.sourceSQL}run(...t){try{let r=this.handle.run(...Us(t));return{changes:Number(r.changes),lastInsertRowid:Number(r.lastInsertRowid)}}catch(r){Wt(r)}}get(...t){try{return this.project(this.handle.get(...Us(t)))}catch(r){Wt(r)}}all(...t){try{return this.handle.all(...Us(t)).map(r=>this.project(r))}catch(r){Wt(r)}}*iterate(...t){let r;try{r=this.handle.iterate(...Us(t))}catch(n){Wt(n)}for(;;){let n;try{n=r.next()}catch(o){Wt(o)}if(n.done)return;yield this.project(n.value)}}raw(t=!0){return this.arrayMode=t,this.handle.setReturnArrays(t||this.pluckMode),this}pluck(t=!0){return this.pluckMode=t,this.handle.setReturnArrays(t||this.arrayMode),this}project(t){let r=i$(t);return this.pluckMode&&Array.isArray(r)?r[0]:r}},rc=class{name;memory;readonly;handle;savepointId=0;constructor(t,r={}){let n=t===":memory:"||t==="";if(r.readonly===!0&&n)throw new TypeError("In-memory/temporary databases cannot be readonly");if(!n&&!sm(ZA(t)))throw new TypeError("Cannot open database because the directory does not exist");if(r.fileMustExist===!0&&!n&&!sm(t))throw s$();this.name=t,this.memory=n,this.readonly=r.readonly===!0;try{this.handle=new(e$())(t,{readOnly:this.readonly,timeout:r.timeout??5e3,enableForeignKeyConstraints:r.foreignKeys??!0})}catch(o){Wt(o)}}get open(){return this.handle.isOpen}get inTransaction(){return this.handle.isTransaction}prepare(t){try{return new tc(this.handle.prepare(t))}catch(r){Wt(r)}}exec(t){try{return this.handle.exec(t),this}catch(r){Wt(r)}}pragma(t,r){let n=this.prepare(`PRAGMA ${t}`);return r?.simple===!0?n.pluck().get():n.all()}transaction(t){let r=o=>(...s)=>this.runTransaction(o,t,s),n=r("BEGIN");return n.default=r("BEGIN"),n.deferred=r("BEGIN DEFERRED"),n.immediate=r("BEGIN IMMEDIATE"),n.exclusive=r("BEGIN EXCLUSIVE"),n}serialize(){try{let t=this.handle.serialize();return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}catch(t){Wt(t)}}close(){if(!this.handle.isOpen)return this;try{return this.handle.close(),this}catch(t){Wt(t)}}runTransaction(t,r,n){if(!this.inTransaction){this.exec(t);try{let s=r(...n);return this.exec("COMMIT"),s}catch(s){if(this.inTransaction)try{this.exec("ROLLBACK")}catch(i){if(!c$(i))throw i}throw s}}let o=`lmbee_sp_${this.savepointId+=1}`;this.exec(`SAVEPOINT ${o}`);try{let s=r(...n);return this.exec(`RELEASE ${o}`),s}catch(s){if(this.inTransaction)try{this.exec(`ROLLBACK TO ${o}`),this.exec(`RELEASE ${o}`)}catch(i){if(!l$(i))throw i}throw s}}};function c$(e){return e instanceof Error&&/cannot rollback - no transaction is active/i.test(e.message)}function l$(e){return e instanceof Error&&/no such savepoint:/i.test(e.message)}var wt=rc;import{existsSync as oc,lstatSync as u$,mkdirSync as d$,readFileSync as dm,realpathSync as am}from"node:fs";import{basename as m$,dirname as sc,isAbsolute as f$,join as p$,relative as h$,resolve as cm}from"node:path";import{fileURLToPath as g$}from"node:url";var mm=p$(sc(g$(import.meta.url)),"schema.sql");function No(e){if(e!==void 0&&e!=="")return e;let t=process.env.LMBEE_DB;if(t)return t;throw new Error("No lmbee database selected: pass an explicit database path or set LMBEE_DB to the intended existing database. The retired ~/.lmbee/state.db default is no longer used.")}function _$(e){if(e.startsWith("~"))throw new Error(`Refusing to open the lmbee database at "${e}": lmbee does not expand "~" in database paths, so this would be created as a literal directory named "~" under the current working directory. Use an absolute path instead (for example ~/.lmbee/state.db). Note for systemd units: Environment= expands neither "~" nor "$HOME", so write the absolute path literally there too.`)}function w$(e,t){if(!(e===":memory:"||oc(e)))throw new Error(`Refusing to create the lmbee database at "${e}": ${t} points at non-existent "${e}", and a typo is indistinguishable from a fresh install. To provision a new database here, \`touch "${e}"\` first, then retry, or point ${t} at an existing database.`)}function y$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(queue)").all();if(r.length===0)return;let n=new Set(r.map(s=>s.name));n.has("subject_id")||e.exec("ALTER TABLE queue ADD COLUMN subject_id TEXT"),n.has("dedupe_key")||e.exec("ALTER TABLE queue ADD COLUMN dedupe_key TEXT"),e.prepare(`SELECT name FROM pragma_index_list('queue') WHERE "unique" = 1 AND partial = 0`).all().some(s=>{let i=e.prepare("SELECT name FROM pragma_index_info(?) ORDER BY seqno").all(s.name);return i.length===1&&i[0].name==="dedupe_key"})||e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_queue_dedupe_key ON queue(dedupe_key)"),n.has("delivered_via_escalation")||e.exec("ALTER TABLE queue ADD COLUMN delivered_via_escalation INTEGER NOT NULL DEFAULT 0"),n.has("escalation_claimed_ts")||e.exec("ALTER TABLE queue ADD COLUMN escalation_claimed_ts TEXT"),n.has("escalation_claim_token")||e.exec("ALTER TABLE queue ADD COLUMN escalation_claim_token TEXT"),n.has("escalation_only")||e.exec("ALTER TABLE queue ADD COLUMN escalation_only INTEGER NOT NULL DEFAULT 0"),n.has("admission_fingerprint")||e.exec("ALTER TABLE queue ADD COLUMN admission_fingerprint TEXT"),n.has("expects_response")||e.exec("ALTER TABLE queue ADD COLUMN expects_response INTEGER NOT NULL DEFAULT 0"),n.has("to_alias")||e.exec("ALTER TABLE queue ADD COLUMN to_alias TEXT"),n.has("retracted_ts")||e.exec("ALTER TABLE queue ADD COLUMN retracted_ts TEXT"),n.has("retracted_reason")||e.exec("ALTER TABLE queue ADD COLUMN retracted_reason TEXT"),n.has("retraction_notice")||e.exec("ALTER TABLE queue ADD COLUMN retraction_notice INTEGER NOT NULL DEFAULT 0"),n.has("in_reply_to")||e.exec("ALTER TABLE queue ADD COLUMN in_reply_to INTEGER"),n.has("operator_priority")||e.exec("ALTER TABLE queue ADD COLUMN operator_priority INTEGER NOT NULL DEFAULT 0"),n.has("merged_into_id")||e.exec("ALTER TABLE queue ADD COLUMN merged_into_id INTEGER")}).immediate()}function E$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(team_progress)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("last_miniplayer_reply_hash")||e.exec("ALTER TABLE team_progress ADD COLUMN last_miniplayer_reply_hash TEXT"),n.has("blocked_surfaced_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN blocked_surfaced_ts TEXT"),n.has("last_escalation_attempt_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN last_escalation_attempt_ts TEXT"),n.has("escalation_attempt_count")||e.exec("ALTER TABLE team_progress ADD COLUMN escalation_attempt_count INTEGER NOT NULL DEFAULT 0"),n.has("fault_surfaced_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN fault_surfaced_ts TEXT"),n.has("epic_closed_surfaced_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN epic_closed_surfaced_ts TEXT"),n.has("quota_exhausted_last_seen_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN quota_exhausted_last_seen_ts TEXT"),n.has("quota_exhausted_message")||e.exec("ALTER TABLE team_progress ADD COLUMN quota_exhausted_message TEXT"),n.has("miniplayer_verdict_label")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_label TEXT"),n.has("miniplayer_verdict_reason")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_reason TEXT"),n.has("miniplayer_verdict_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_ts TEXT"),n.has("miniplayer_verdict_input_hash")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_input_hash TEXT"),n.has("miniplayer_verdict_structural_hash")||e.exec("ALTER TABLE team_progress ADD COLUMN miniplayer_verdict_structural_hash TEXT"),n.has("holder_watch_pid")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_pid INTEGER"),n.has("holder_watch_started_at")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_started_at TEXT"),n.has("holder_watch_cpu_ticks")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_cpu_ticks INTEGER"),n.has("holder_watch_observed_at")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_observed_at TEXT"),n.has("holder_watch_low_cpu_streak")||e.exec("ALTER TABLE team_progress ADD COLUMN holder_watch_low_cpu_streak INTEGER"),n.has("hung_holder_flagged_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN hung_holder_flagged_ts TEXT"),n.has("hung_holder_reason")||e.exec("ALTER TABLE team_progress ADD COLUMN hung_holder_reason TEXT"),n.has("last_cli_activity_ts")||e.exec("ALTER TABLE team_progress ADD COLUMN last_cli_activity_ts TEXT")}).immediate()}function b$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(cron_jobs)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("last_fire_error")||e.exec("ALTER TABLE cron_jobs ADD COLUMN last_fire_error TEXT"),n.has("running_systemd_unit")||e.exec("ALTER TABLE cron_jobs ADD COLUMN running_systemd_unit TEXT"),n.has("timezone")||e.exec("ALTER TABLE cron_jobs ADD COLUMN timezone TEXT"),n.has("provider")||e.exec("ALTER TABLE cron_jobs ADD COLUMN provider TEXT"),n.has("model")||e.exec("ALTER TABLE cron_jobs ADD COLUMN model TEXT"),n.has("working_directory")||e.exec("ALTER TABLE cron_jobs ADD COLUMN working_directory TEXT"),n.has("escalation_owner")||e.exec("ALTER TABLE cron_jobs ADD COLUMN escalation_owner TEXT"),n.has("session_teamfile")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_teamfile TEXT"),n.has("session_alias")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_alias TEXT"),n.has("session_seeded_at")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_seeded_at TEXT"),n.has("session_generation")||e.exec("ALTER TABLE cron_jobs ADD COLUMN session_generation INTEGER NOT NULL DEFAULT 0")}).immediate()}function T$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(entities)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("delivered_ts")||e.exec("ALTER TABLE entities ADD COLUMN delivered_ts TEXT"),n.has("review_time")||e.exec("ALTER TABLE entities ADD COLUMN review_time TEXT"),n.has("needs_review")||e.exec("ALTER TABLE entities ADD COLUMN needs_review INTEGER NOT NULL DEFAULT 0 CHECK(needs_review IN (0,1))"),n.has("review_reason")||e.exec("ALTER TABLE entities ADD COLUMN review_reason TEXT"),n.has("review_input_hash")||e.exec("ALTER TABLE entities ADD COLUMN review_input_hash TEXT"),n.has("hold_until")||e.exec("ALTER TABLE entities ADD COLUMN hold_until TEXT"),n.has("hold_reason")||e.exec("ALTER TABLE entities ADD COLUMN hold_reason TEXT"),n.has("blocked_on")||e.exec("ALTER TABLE entities ADD COLUMN blocked_on TEXT")}).immediate()}function S$(e){e.transaction(()=>{let r=e.prepare("PRAGMA table_info(mail_ledger)").all();if(r.length===0)return;let n=new Set(r.map(o=>o.name));n.has("ack_sent_ts")||e.exec("ALTER TABLE mail_ledger ADD COLUMN ack_sent_ts TEXT"),n.has("delivery_error")||e.exec("ALTER TABLE mail_ledger ADD COLUMN delivery_error TEXT"),n.has("delivery_error_ts")||e.exec("ALTER TABLE mail_ledger ADD COLUMN delivery_error_ts TEXT")}).immediate()}function ic(e){let t=process.env.LMBEE_TEST_DB_ROOT;if(!t||e===":memory:")return;let r=[],n=cm(e);for(;u$(n,{throwIfNoEntry:!1})===void 0;){r.unshift(m$(n));let i=sc(n);if(i===n)throw new Error("Cannot resolve test database path");n=i}let o=cm(am(n),...r),s=h$(am(t),o);if(s===".."||s.startsWith("../")||s.startsWith("..\\")||f$(s))throw new Error(`Database path is outside the test database root: ${e}`)}function lm(e){let t=o=>e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(o)!==void 0,r=o=>e.prepare(`PRAGMA table_info(${o})`).all(),n;for(let o of["queue_responses","chat_tasks","chat_messages","chat_message_task_reassignments"])if(t(o)){n=`legacy table '${o}'`;break}if(n===void 0&&t("answers")){let o=new Set(r("answers").map(s=>s.name));o.has("request_queue_id")?n="legacy column 'answers.request_queue_id'":o.has("superseded_at")||(n="legacy 'answers' shape: missing column 'superseded_at'")}if(n===void 0&&t("queue")){let o=r("queue"),s=new Set(o.map(i=>i.name));s.has("team")?n="legacy column 'queue.team'":s.has("to_id")?o.some(i=>i.name==="from_id"&&i.notnull!==1)?n="legacy 'queue' shape: from_id is still nullable":s.has("restart_nudge_sent_ts")&&(n="legacy column 'queue.restart_nudge_sent_ts'"):n="legacy 'queue' shape: missing column 'to_id'"}if(n===void 0&&t("cron_jobs")){let o=e.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'cron_jobs'").get();(o===void 0||!o.sql.includes("'miniplayer'"))&&(n="legacy 'cron_jobs' CHECK constraint predates 'miniplayer'")}if(n===void 0&&t("cron_jobs")){let o=e.prepare("SELECT id, action_payload FROM cron_jobs WHERE action_kind = 'enqueue'").all();for(let s of o){let i;try{i=JSON.parse(s.action_payload)}catch{i=void 0}let a=typeof i=="object"&&i!==null?i.prompt:void 0;if(typeof a!="string"||a.trim().length===0){n=`legacy 'cron_jobs' enqueue payload (id ${s.id}) predates the 'prompt' vocabulary`;break}}}if(n===void 0&&t("team_progress")&&new Set(r("team_progress").map(s=>s.name)).has("last_scan_head")&&(n="legacy column 'team_progress.last_scan_head'"),n===void 0&&t("cron_runs")&&(new Set(r("cron_runs").map(s=>s.name)).has("execution_state")||(n="legacy 'cron_runs' shape: missing column 'execution_state'")),n===void 0&&t("rate_limit_policy_log")){let o=e.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'rate_limit_policy_log'").get();(o===void 0||!o.sql.includes("'confirmed_would_fire_policy_disabled'"))&&(n="legacy 'rate_limit_policy_log' CHECK constraint predates 'confirmed_would_fire_policy_disabled'")}if(n===void 0&&t("rate_limit_policy_arm")&&(new Set(r("rate_limit_policy_arm").map(s=>s.name)).has("armed_used_fraction")||(n="legacy 'rate_limit_policy_arm' shape: missing column 'armed_used_fraction'")),n!==void 0)throw new Error(`Refusing to open this lmbee state.db: abandoned pre-v14 lmbee schema shape (${n}). Per the operator's 2026-10-01 shared-database decision, lmbee now shares lmctl's state.db and every pre-existing lmbee-only database is abandoned -- there is no data migration, ever. Do not remove a shared lmctl database. Check LMBEE_DB and the database ownership; point lmbee at the intended compatible database. Preserve this file for operator review.`)}var Fs=62;function um(e){let t=e.pragma("user_version",{simple:!0});if(t<=Fs)return;let r;if(e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_meta'").get()!==void 0){let o=new Set(e.prepare("PRAGMA table_info(schema_meta)").all().map(s=>s.name));if(o.has("key")&&o.has("value")){let s=e.prepare("SELECT value FROM schema_meta WHERE key = 'min_reader_version'").get();typeof s?.value=="string"&&(r=s.value)}}let n;if(r===void 0)n="schema_meta.min_reader_version is absent";else if(!/^[1-9]\d*$/.test(r))n=`schema_meta.min_reader_version=${JSON.stringify(r)} is malformed (not a canonical decimal integer)`;else if(Number(r)>Fs)n=`schema_meta.min_reader_version=${r} declares a breaking floor above ${Fs}`;else return;throw new Error(`Refusing to open the shared state.db: it was migrated by a newer lmctl with breaking changes (user_version=${t} exceeds the newest lmctl schema version this lmbee build understands, ${Fs}, and ${n}). Upgrade lmbee to a build that understands the newer lmctl schema before opening this database again. lmbee never writes user_version or schema_meta, so the file is untouched.`)}var nc;function v$(){return nc===void 0&&(nc=[...dm(mm,"utf8").matchAll(/CREATE TABLE IF NOT EXISTS (\w+)/gi)].map(t=>t[1])),nc}function A$(e,t){let r=new Set(e.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map(o=>o.name)),n=v$().filter(o=>!r.has(o));if(n.length!==0)throw new Error(`Refusing a read-only open of "${t}": required lmbee schema is missing (no table${n.length===1?"":"s"}: ${n.join(", ")}), and a read-only handle cannot create it. Run any writable lmbee command (or start the daemon) once against this database to provision it, then retry.`)}function qs(e,t={}){let r=No(e);_$(r);let n=!e&&typeof process.env.LMBEE_DB=="string"&&process.env.LMBEE_DB!=="";if(n&&w$(r,"LMBEE_DB"),ic(r),t.readOnly&&r===":memory:")throw new Error("Refusing a read-only open of ':memory:': an in-memory database starts empty on every open, so the required lmbee schema can never be present and a read-only handle cannot create it.");if(t.readOnly&&r!==":memory:"){if(!oc(r))throw new Error(`Refusing a read-only open of "${r}": the file does not exist, so the required lmbee schema is missing. Run any writable lmbee command (or start the daemon) once against this database to provision it, then retry.`);let a=new wt(r,{readonly:!0,fileMustExist:!0});try{lm(a),um(a),a.pragma("busy_timeout = 5000"),A$(a,r)}catch(c){throw a.close(),c}return{path:r,db:a,close:()=>a.close()}}if(r!==":memory:"){let a=sc(r);oc(a)||d$(a,{recursive:!0})}let o=new wt(r,n?{fileMustExist:!0}:void 0);try{lm(o),um(o)}catch(a){throw o.close(),a}o.pragma("journal_mode = WAL"),o.pragma("busy_timeout = 5000");let s=dm(mm,"utf8"),i=o.transaction(()=>{y$(o),E$(o),S$(o),T$(o),b$(o),o.exec(s)});try{i.immediate()}catch(a){throw o.close(),a}return{path:r,db:o,close:()=>o.close()}}function qe(e,t){return e.prepare("SELECT * FROM team_state WHERE team = ?").get(t)??null}function fm(e,t){let r=qe(e,t);return r===null?{kind:"never-observed"}:{kind:"observed",value:r,observedAt:r.last_ts,changedAt:r.changed_ts}}function ur(e,t,r,n){let o=new Date(n).toISOString(),s=qe(e,t),i=s&&s.status===r?s.changed_ts:o;e.prepare(`INSERT INTO team_state(team, status, changed_ts, last_ts) VALUES (?, ?, ?, ?)
67
67
  ON CONFLICT(team) DO UPDATE SET status = excluded.status, changed_ts = excluded.changed_ts, last_ts = excluded.last_ts`).run(t,r,i,o)}function nt(e,t,r,n,o={}){e.prepare("INSERT INTO events(ts, scan, team, status, note) VALUES (?, ?, ?, ?, ?)").run(new Date(n).toISOString(),o.scan??null,t,r,o.note??null)}function js(e,t,r,n){return e.prepare("SELECT * FROM events WHERE status = ? AND ts >= ? ORDER BY id DESC LIMIT ?").all(t,r,n)}function ie(e,t){return e.prepare("SELECT * FROM team_progress WHERE team = ?").get(t)??null}function pm(e,t,r,n,o=n){let s=ie(e,t),i=s&&s.progress_status===r?s.progress_changed_ts:o;e.prepare(`INSERT INTO team_progress(team, progress_status, progress_changed_ts, last_scan_ts)
68
68
  VALUES (?, ?, ?, ?)
69
69
  ON CONFLICT(team) DO UPDATE SET
@@ -184,7 +184,7 @@ ${si(d.prompt_file,"utf8")}`)}catch{l=!1;break}if(!l||c.length===0)continue;Pf(o
184
184
 
185
185
  (Also: ${u.length} task(s) marked blocked, including #${u[0].id} ("${u[0].title}") -- pending meta-lead review, no action needed from you on ${u.length===1?"it":"these"} right now.)`:"",m=Xk(e,t),f=t.entities[0],p=f?.owner_team_path!==null&&f?.owner_team_path!==void 0&&f?.owner_alias!==null&&f?.owner_alias!==void 0?` --owner-team ${mi(f.owner_team_path)} --owner-alias ${mi(f.owner_alias)}`:"",h=x=>`#${x.id} ("${x.title}") -- \`lmauto tasks create task --parent ${x.id} --title "..."${p}\` to add the next one, or \`lmauto tasks update ${x.id} --status done\` if it's genuinely complete`,g=m.length>0?`
186
186
 
187
- (Also: ${m.length} epic(s) have all tasks done: ${m.map(h).join("; ")}.)`:"",_=i.filter(x=>le(x.status)==="done").map(x=>{let H=[];return gi(e,x)&&H.push("still has an unmet dependency"),fi(e,x.id)&&H.push("still has an incomplete subtask"),{entity:x,reasons:H}}).filter(x=>x.reasons.length>0);if(_.length>0){let{entity:x,reasons:H}=_[0];return{message:`${x.kind==="subtask"?"Subtask":"Task"} #${x.id} ("${x.title}") is marked done but ${H.join(" and ")} -- please double-check and resolve the contradiction (confirm it's genuinely finished, or reopen it if something was missed).`}}let E=i.filter(x=>le(x.status)==="done"&&!Yk(e,x.id));if(E.length>0){let x=E[0];return{message:`Task #${x.id} ("${x.title}") is marked done -- close it out (commit/publish/report as appropriate), then \`lmauto tasks note add ${x.id} --body "<what you did>"\` to confirm, or update its status if it needs to be reopened.`+d+g}}let y=i.filter(x=>Jk.has(le(x.status))&&le(x.status)!==Yt&&!fi(e,x.id));if(y.length===0){let x=i.filter($=>{let q=le($.status);return q!==pi&&q!==Yt&&fi(e,$.id)});if(x.length>0){let $=x[0];return{message:`${$.kind==="subtask"?"Subtask":"Task"} #${$.id} ("${$.title}") has an incomplete subtask -- check \`lmauto tasks show ${$.id}\` for what's left.`+d+g}}let H=i.filter($=>le($.status)===Yt),C=i.filter($=>le($.status)!==Yt&&le($.status)!==pi),w=t.entities.some($=>$.kind==="epic"&&!yt($.status)&&le($.status)!==Yt);if(C.length===0&&!w)return null;if(m.length>1)return{message:`${m.length} of your open epics have all tasks done: ${m.map(h).join("; ")}.`};let b=ox(t.entities),N=t.entities[0],P=N?.owner_team_path,J=N?.owner_alias,ee=P!=null&&J!==null&&J!==void 0?` --owner-team ${mi(P)} --owner-alias ${mi(J)}`:"",oe=b!==null?String(b.id):"<epic-id>",V=b!==null?`lmauto tasks update ${b.id} --status done`:"<lmauto tasks update EPIC_ID --status done>",se=H.length>0&&u.length>0?"All your non-blocked/non-held tracked tasks are done.":H.length>0?"All your non-held tracked tasks are done.":u.length>0?"All your non-blocked tracked tasks are done.":"All your tracked tasks are done.",k=[];H.length>0&&k.push(`${H.length} other task(s) remain on_hold -- not done, just parked`),u.length>0&&k.push(`${u.length} task(s) remain blocked, pending meta-lead review`);let O=k.length>0?` (${k.join("; ")}; resolve those before treating the epic as complete.)`:"";return b===null&&!w?{message:`${se}${O}`}:{message:`${se}${O} Either \`lmauto tasks create task --parent ${oe} --title "..."${ee}\` to add the next one, or if the epic is genuinely complete, \`${V}\`.`}}let S=y.filter(x=>!gi(e,x));if(S.length===0){let x=y[0];return{message:`All ${y.length} of your tracked todo/in-progress task(s) are blocked on an unmet dependency, including #${x.id} ("${x.title}") -- check \`lmauto tasks show ${x.id}\` and report if you're stuck.`+d+g}}let T=S.filter(x=>le(x.status)==="in-progress"||x.delivered_ts!=null),R=T.length>0?T[0]:S[0],A=R.delivered_ts==null?()=>Yf(e,R.id,new Date().toISOString()):void 0;if(S.length===1){let x=R.description.trim();return{message:`Continue task #${R.id}: "${R.title}" (status: ${R.status}).${x?`
187
+ (Also: ${m.length} epic(s) have all tasks done: ${m.map(h).join("; ")}.)`:"",_=i.filter(x=>le(x.status)==="done").map(x=>{let H=[];return gi(e,x)&&H.push("still has an unmet dependency"),fi(e,x.id)&&H.push("still has an incomplete subtask"),{entity:x,reasons:H}}).filter(x=>x.reasons.length>0);if(_.length>0){let{entity:x,reasons:H}=_[0];return{message:`${x.kind==="subtask"?"Subtask":"Task"} #${x.id} ("${x.title}") is marked done but ${H.join(" and ")} -- please double-check and resolve the contradiction (confirm it's genuinely finished, or reopen it if something was missed).`}}let E=i.filter(x=>le(x.status)==="done"&&!Yk(e,x.id));if(E.length>0){let x=E[0];return{message:`Task #${x.id} ("${x.title}") is marked done -- close it out (commit/publish/report as appropriate), then \`lmauto tasks note add ${x.id} --body "<what you did>"\` to confirm, or update its status if it needs to be reopened.`+d+g}}let y=i.filter(x=>Jk.has(le(x.status))&&le(x.status)!==Yt&&!fi(e,x.id));if(y.length===0){let x=i.filter($=>{let q=le($.status);return q!==pi&&q!==Yt&&fi(e,$.id)});if(x.length>0){let $=x[0];return{message:`${$.kind==="subtask"?"Subtask":"Task"} #${$.id} ("${$.title}") has an incomplete subtask -- check \`lmauto tasks show ${$.id}\` for what's left.`+d+g}}let H=i.filter($=>le($.status)===Yt),C=i.filter($=>le($.status)!==Yt&&le($.status)!==pi),w=t.entities.some($=>$.kind==="epic"&&!yt($.status)&&le($.status)!==Yt);if(C.length===0&&!w)return null;if(m.length>1)return{message:`${m.length} of your open epics have all tasks done: ${m.map(h).join("; ")}.`};let b=ox(t.entities),N=t.entities[0],M=N?.owner_team_path,W=N?.owner_alias,ee=M!=null&&W!==null&&W!==void 0?` --owner-team ${mi(M)} --owner-alias ${mi(W)}`:"",oe=b!==null?String(b.id):"<epic-id>",J=b!==null?`lmauto tasks update ${b.id} --status done`:"<lmauto tasks update EPIC_ID --status done>",se=H.length>0&&u.length>0?"All your non-blocked/non-held tracked tasks are done.":H.length>0?"All your non-held tracked tasks are done.":u.length>0?"All your non-blocked tracked tasks are done.":"All your tracked tasks are done.",k=[];H.length>0&&k.push(`${H.length} other task(s) remain on_hold -- not done, just parked`),u.length>0&&k.push(`${u.length} task(s) remain blocked, pending meta-lead review`);let O=k.length>0?` (${k.join("; ")}; resolve those before treating the epic as complete.)`:"";return b===null&&!w?{message:`${se}${O}`}:{message:`${se}${O} Either \`lmauto tasks create task --parent ${oe} --title "..."${ee}\` to add the next one, or if the epic is genuinely complete, \`${J}\`.`}}let S=y.filter(x=>!gi(e,x));if(S.length===0){let x=y[0];return{message:`All ${y.length} of your tracked todo/in-progress task(s) are blocked on an unmet dependency, including #${x.id} ("${x.title}") -- check \`lmauto tasks show ${x.id}\` and report if you're stuck.`+d+g}}let T=S.filter(x=>le(x.status)==="in-progress"||x.delivered_ts!=null),R=T.length>0?T[0]:S[0],A=R.delivered_ts==null?()=>Yf(e,R.id,new Date().toISOString()):void 0;if(S.length===1){let x=R.description.trim();return{message:`Continue task #${R.id}: "${R.title}" (status: ${R.status}).${x?`
188
188
 
189
189
  ${x}`:""}${d}${g}`,onSent:A}}let I=R.description.trim();return{message:`Continue task #${R.id}: "${R.title}" (status: ${R.status}).${I?`
190
190
 
@@ -256,20 +256,20 @@ evidence of recent execution even if the transcript alone reads as stalled or de
256
256
  may belong to a member who did none of the actual work.
257
257
 
258
258
  Respond with EXACTLY one line of strict JSON, no other text before or after: {"label": "<one of the four exact labels above>", "reason": "<short human-readable reason, under 200 characters>"}`}function XR(e){if(e===null)return null;let t;try{t=JSON.parse(e.trim())}catch{return null}if(typeof t!="object"||t===null)return null;let r=t;if(typeof r.label!="string"||!JR.has(r.label)||typeof r.reason!="string"||r.reason.trim().length===0)return null;let n=r.reason.replace(/\s+/g," ").trim();return n.length===0?null:{label:r.label,reason:n.slice(0,VR)}}function ZR(e){if(e.length===1){let[t]=e;return`holding for #${t.id} ("${t.title}") until ${t.holdUntil} -- deliberately scheduled, not stalled`}return`holding for ${e.length} task(s), until ${e.map(t=>t.holdUntil).join(", ")} -- deliberately scheduled, not stalled`}async function eN(e,t,r,n){let o=n.fetchTailJsonImpl??Ui,s,i,a;try{s=(await o(r,t.leadAlias,{lines:20})).messages.map(y=>`${y.role}: ${typeof y.content=="string"?y.content:JSON.stringify(y.content)}`).join(`
259
- `),i=YR(e,r,t.leadAlias),a=KR(e,r,t.leadAlias,Date.now())}catch{return}let c=ie(e,t.name),l=Sh(s,i,c,a),u=Sh("",i,c,a),d=n.cooldownMs??zR,m=c?.miniplayer_verdict_input_hash!==l,f=c?.miniplayer_verdict_structural_hash!==u,p=!c?.miniplayer_verdict_ts||Date.now()-Date.parse(c.miniplayer_verdict_ts)>=d;if(!(f||m&&p))return;let h=await wi(QR(t.name,s,i,c,a),{...n.spawnPrefix!==void 0?{spawnPrefix:n.spawnPrefix}:{},...n.timeoutMs!==void 0?{timeoutMs:n.timeoutMs}:{}}),g=XR(h);if(g===null)return;let _=g.label==="stalled_needs_nudge"&&a.length>0&&i.length===0?{label:"blocked",reason:ZR(a)}:g;ym(e,t.name,_.label,_.reason,new Date().toISOString(),l,u)}async function vh(e,t,r,n={}){for(let o of t){let s=r.find(a=>a.name===o);if(s===void 0||!B(s))continue;let i;try{i=Q(s)}catch{continue}try{await eN(e,s,i,n)}catch{continue}}}import{execFileSync as KN}from"node:child_process";var U=class extends Error{code;exitCode;constructor(t,r,n=2){super(r),this.code=t,this.exitCode=n}};function Nl(e){let t;try{if(typeof e!="string")throw new Error("expected a cron expression string");let r=e.trim().split(/\s+/);if(r.length!==5)throw new Error("expected five fields: minute hour day-of-month month day-of-week");t="minute";let n=Wo(r[0],0,59);t="hour";let o=Wo(r[1],0,23);t="dayOfMonth";let s=Wo(r[2],1,31);t="month";let i=Wo(r[3],1,12);t="dayOfWeek";let a=Wo(r[4],0,7,l=>l===7?0:l);return{ok:!0,schedule:{__brand:"CronSchedule",minute:n,hour:o,dayOfMonth:s,month:i,dayOfWeek:a}}}catch(r){let n=r instanceof Error?r.message:String(r);return{ok:!1,error:t?{message:n,field:t}:{message:n}}}}function Wo(e,t,r,n=o=>o){if(e.length===0)throw new Error("empty field");let o=new Set;for(let s of e.split(",")){if(s.length===0)throw new Error(`invalid list in "${e}"`);let i=s.split("/");if(i.length>2)throw new Error(`invalid step in "${s}"`);let a=i[0],c=i[1]===void 0?1:Rl(i[1],1,r-t+1,s),l=a.split("-");if(l.length>2)throw new Error(`invalid range in "${s}"`);let u=a==="*"?t:Rl(l[0],t,r,s),d=a==="*"?r:l[1]!==void 0?Rl(l[1],t,r,s):i[1]?r:u;if(u>d)throw new Error(`range starts after it ends in "${s}"`);for(let m=u;m<=d;m+=c)o.add(n(m))}return{values:o,wildcard:e.split(",").some(s=>s.split("/")[0]==="*")}}function Rl(e,t,r,n){if(!/^\d+$/.test(e))throw new Error(`expected an integer in "${n}"`);let o=Number(e);if(!Number.isSafeInteger(o)||o<t||o>r)throw new Error(`value ${e} is outside ${t}-${r}`);return o}function tN(e,t){let r=e;if(!r.minute.values.has(t.getMinutes())||!r.hour.values.has(t.getHours())||!r.month.values.has(t.getMonth()+1))return!1;let n=r.dayOfMonth.values.has(t.getDate()),o=r.dayOfWeek.values.has(t.getDay());return r.dayOfMonth.wildcard?o:r.dayOfWeek.wildcard?n:n||o}function Ah(e,t,r){let n=t.getTime(),o=r.getTime();if(o<n)throw new RangeError("untilInclusive must not precede sinceExclusive");for(let s=(Math.floor(n/6e4)+1)*6e4;s<=o;s+=6e4)if(tN(e,new Date(s)))return!0;return!1}import{spawn as rN}from"node:child_process";import{closeSync as nN,existsSync as oN,mkdirSync as sN,openSync as iN,readdirSync as aN,unlinkSync as cN}from"node:fs";import{homedir as lN}from"node:os";import{join as Fi}from"node:path";var $h=["systemd-run","--user","--scope","--collect","--quiet"],uN=10,kh=50*6e4,dN=5e3;function qi(){return process.env.LMBEE_CRON_LOG_DIR?process.env.LMBEE_CRON_LOG_DIR:Fi(lN(),".lmbee","cron-logs")}function mN(e,t){try{let r=aN(e).sort();for(let n of r.slice(0,Math.max(0,r.length-t)))try{cN(Fi(e,n))}catch{}}catch{}}function fN(e,t){return[...t.spawnPrefix??(t.systemdUnitName!==void 0?[...$h,"--unit",t.systemdUnitName,"--"]:[...$h,"--"]),"sh","-c",e]}function Go(e,t={}){let r=Fi(t.logDir??qi(),String(e.id));oN(r)||sN(r,{recursive:!0});let n=Fi(r,`${new Date().toISOString().replace(/[:.]/g,"-")}.log`),o=iN(n,"a"),s=fN(e.action_payload,t),[i,...a]=s,c;try{c=rN(i,a,{detached:!0,stdio:["ignore",o,o],...t.cwd!==void 0?{cwd:t.cwd}:{},...t.env!==void 0?{env:t.env}:{}})}finally{nN(o)}c.unref();let l=c.pid??null,u=!1,d=t.timeoutMs===void 0?kh:t.timeoutMs,m=t.sigkillGraceMs??dN,f=d===null?void 0:setTimeout(()=>{if(u)return;let h=c.pid;if(h!==void 0){try{process.kill(-h,"SIGTERM")}catch{}setTimeout(()=>{try{process.kill(-h,0)}catch{return}try{process.kill(-h,"SIGKILL")}catch{}},m).unref()}process.stderr.write(`[lmcron] job ${e.id} timed out after ${d}ms, sending SIGTERM
259
+ `),i=YR(e,r,t.leadAlias),a=KR(e,r,t.leadAlias,Date.now())}catch{return}let c=ie(e,t.name),l=Sh(s,i,c,a),u=Sh("",i,c,a),d=n.cooldownMs??zR,m=c?.miniplayer_verdict_input_hash!==l,f=c?.miniplayer_verdict_structural_hash!==u,p=!c?.miniplayer_verdict_ts||Date.now()-Date.parse(c.miniplayer_verdict_ts)>=d;if(!(f||m&&p))return;let h=await wi(QR(t.name,s,i,c,a),{...n.spawnPrefix!==void 0?{spawnPrefix:n.spawnPrefix}:{},...n.timeoutMs!==void 0?{timeoutMs:n.timeoutMs}:{}}),g=XR(h);if(g===null)return;let _=g.label==="stalled_needs_nudge"&&a.length>0&&i.length===0?{label:"blocked",reason:ZR(a)}:g;ym(e,t.name,_.label,_.reason,new Date().toISOString(),l,u)}async function vh(e,t,r,n={}){for(let o of t){let s=r.find(a=>a.name===o);if(s===void 0||!B(s))continue;let i;try{i=Q(s)}catch{continue}try{await eN(e,s,i,n)}catch{continue}}}import{execFileSync as KN}from"node:child_process";var P=class extends Error{code;exitCode;constructor(t,r,n=2){super(r),this.code=t,this.exitCode=n}};function Nl(e){let t;try{if(typeof e!="string")throw new Error("expected a cron expression string");let r=e.trim().split(/\s+/);if(r.length!==5)throw new Error("expected five fields: minute hour day-of-month month day-of-week");t="minute";let n=Wo(r[0],0,59);t="hour";let o=Wo(r[1],0,23);t="dayOfMonth";let s=Wo(r[2],1,31);t="month";let i=Wo(r[3],1,12);t="dayOfWeek";let a=Wo(r[4],0,7,l=>l===7?0:l);return{ok:!0,schedule:{__brand:"CronSchedule",minute:n,hour:o,dayOfMonth:s,month:i,dayOfWeek:a}}}catch(r){let n=r instanceof Error?r.message:String(r);return{ok:!1,error:t?{message:n,field:t}:{message:n}}}}function Wo(e,t,r,n=o=>o){if(e.length===0)throw new Error("empty field");let o=new Set;for(let s of e.split(",")){if(s.length===0)throw new Error(`invalid list in "${e}"`);let i=s.split("/");if(i.length>2)throw new Error(`invalid step in "${s}"`);let a=i[0],c=i[1]===void 0?1:Rl(i[1],1,r-t+1,s),l=a.split("-");if(l.length>2)throw new Error(`invalid range in "${s}"`);let u=a==="*"?t:Rl(l[0],t,r,s),d=a==="*"?r:l[1]!==void 0?Rl(l[1],t,r,s):i[1]?r:u;if(u>d)throw new Error(`range starts after it ends in "${s}"`);for(let m=u;m<=d;m+=c)o.add(n(m))}return{values:o,wildcard:e.split(",").some(s=>s.split("/")[0]==="*")}}function Rl(e,t,r,n){if(!/^\d+$/.test(e))throw new Error(`expected an integer in "${n}"`);let o=Number(e);if(!Number.isSafeInteger(o)||o<t||o>r)throw new Error(`value ${e} is outside ${t}-${r}`);return o}function tN(e,t){let r=e;if(!r.minute.values.has(t.getMinutes())||!r.hour.values.has(t.getHours())||!r.month.values.has(t.getMonth()+1))return!1;let n=r.dayOfMonth.values.has(t.getDate()),o=r.dayOfWeek.values.has(t.getDay());return r.dayOfMonth.wildcard?o:r.dayOfWeek.wildcard?n:n||o}function Ah(e,t,r){let n=t.getTime(),o=r.getTime();if(o<n)throw new RangeError("untilInclusive must not precede sinceExclusive");for(let s=(Math.floor(n/6e4)+1)*6e4;s<=o;s+=6e4)if(tN(e,new Date(s)))return!0;return!1}import{spawn as rN}from"node:child_process";import{closeSync as nN,existsSync as oN,mkdirSync as sN,openSync as iN,readdirSync as aN,unlinkSync as cN}from"node:fs";import{homedir as lN}from"node:os";import{join as Fi}from"node:path";var $h=["systemd-run","--user","--scope","--collect","--quiet"],uN=10,kh=50*6e4,dN=5e3;function qi(){return process.env.LMBEE_CRON_LOG_DIR?process.env.LMBEE_CRON_LOG_DIR:Fi(lN(),".lmbee","cron-logs")}function mN(e,t){try{let r=aN(e).sort();for(let n of r.slice(0,Math.max(0,r.length-t)))try{cN(Fi(e,n))}catch{}}catch{}}function fN(e,t){return[...t.spawnPrefix??(t.systemdUnitName!==void 0?[...$h,"--unit",t.systemdUnitName,"--"]:[...$h,"--"]),"sh","-c",e]}function Go(e,t={}){let r=Fi(t.logDir??qi(),String(e.id));oN(r)||sN(r,{recursive:!0});let n=Fi(r,`${new Date().toISOString().replace(/[:.]/g,"-")}.log`),o=iN(n,"a"),s=fN(e.action_payload,t),[i,...a]=s,c;try{c=rN(i,a,{detached:!0,stdio:["ignore",o,o],...t.cwd!==void 0?{cwd:t.cwd}:{},...t.env!==void 0?{env:t.env}:{}})}finally{nN(o)}c.unref();let l=c.pid??null,u=!1,d=t.timeoutMs===void 0?kh:t.timeoutMs,m=t.sigkillGraceMs??dN,f=d===null?void 0:setTimeout(()=>{if(u)return;let h=c.pid;if(h!==void 0){try{process.kill(-h,"SIGTERM")}catch{}setTimeout(()=>{try{process.kill(-h,0)}catch{return}try{process.kill(-h,"SIGKILL")}catch{}},m).unref()}process.stderr.write(`[lmcron] job ${e.id} timed out after ${d}ms, sending SIGTERM
260
260
  `)},d??kh);f?.unref();let p=(h,g)=>{u||(u=!0,f!==void 0&&clearTimeout(f),mN(r,uN),t.onExit?.(h,g,l,n))};c.on("error",h=>{process.stderr.write(`[lmcron] job ${e.id} spawn error: ${h.message}
261
- `),p(null,h)}),c.on("exit",h=>{p(h)})}import{createHash as pN,randomUUID as hN}from"node:crypto";var ln=16*1024,Jo=16*1024,Il=512,ji=100,Ll=4096,Cl=1024*1024,zo="('pending','running')",gN="execution_state != 'gone' OR (status = 'escalated' AND escalation_resolved_at IS NULL)";function Yo(e){let{run_token_hash:t,...r}=e;return r}function xh(e){return pN("sha256").update(e,"utf8").digest("hex")}function kt(e){try{return e()}catch(t){if(t instanceof U)throw t;if(t instanceof L)throw new U(t.code,t.message,t.exitCode);let r=t&&typeof t=="object"&&"code"in t?String(t.code):void 0,n=t instanceof Error?t.message:String(t);throw r!==void 0&&(r.startsWith("SQLITE_BUSY")||r.startsWith("SQLITE_LOCKED"))?new U("DB_BUSY","Database busy; retry after the current writer completes",5):r!==void 0&&r.startsWith("SQLITE_CONSTRAINT")?new U("STRUCTURAL_ERROR",n,2):new U("STORAGE_ERROR",n,1)}}function Rh(e,t){return kt(()=>e.prepare("SELECT * FROM cron_runs WHERE id = ?").get(t)??null)}function Qe(e,t){let r=Rh(e,t);if(r===null)throw new U("NOT_FOUND",`Cron run ${t} does not exist`,3);return r}function _N(e,t){return e.prepare("SELECT * FROM cron_runs WHERE run_token_hash = ?").get(t)??null}function fr(e,t){return kt(()=>e.prepare(`SELECT * FROM cron_runs WHERE job_id = ? AND (${gN}) ORDER BY id DESC LIMIT 1`).get(t)??null)}function Ko(e,t,r,n){return kt(()=>{let o=fr(e,t);if(o!==null)return o.status==="escalated"?{kind:"escalation",run:o}:{kind:"overlap",run:o};let s=hN(),i=de();try{let a=e.prepare(`INSERT INTO cron_runs(job_id, run_token_hash, status, execution_state, trigger_kind, config_snapshot, created_at, updated_at)
261
+ `),p(null,h)}),c.on("exit",h=>{p(h)})}import{createHash as pN,randomUUID as hN}from"node:crypto";var ln=16*1024,Jo=16*1024,Il=512,ji=100,Ll=4096,Cl=1024*1024,zo="('pending','running')",gN="execution_state != 'gone' OR (status = 'escalated' AND escalation_resolved_at IS NULL)";function Yo(e){let{run_token_hash:t,...r}=e;return r}function xh(e){return pN("sha256").update(e,"utf8").digest("hex")}function kt(e){try{return e()}catch(t){if(t instanceof P)throw t;if(t instanceof L)throw new P(t.code,t.message,t.exitCode);let r=t&&typeof t=="object"&&"code"in t?String(t.code):void 0,n=t instanceof Error?t.message:String(t);throw r!==void 0&&(r.startsWith("SQLITE_BUSY")||r.startsWith("SQLITE_LOCKED"))?new P("DB_BUSY","Database busy; retry after the current writer completes",5):r!==void 0&&r.startsWith("SQLITE_CONSTRAINT")?new P("STRUCTURAL_ERROR",n,2):new P("STORAGE_ERROR",n,1)}}function Rh(e,t){return kt(()=>e.prepare("SELECT * FROM cron_runs WHERE id = ?").get(t)??null)}function Qe(e,t){let r=Rh(e,t);if(r===null)throw new P("NOT_FOUND",`Cron run ${t} does not exist`,3);return r}function _N(e,t){return e.prepare("SELECT * FROM cron_runs WHERE run_token_hash = ?").get(t)??null}function fr(e,t){return kt(()=>e.prepare(`SELECT * FROM cron_runs WHERE job_id = ? AND (${gN}) ORDER BY id DESC LIMIT 1`).get(t)??null)}function Ko(e,t,r,n){return kt(()=>{let o=fr(e,t);if(o!==null)return o.status==="escalated"?{kind:"escalation",run:o}:{kind:"overlap",run:o};let s=hN(),i=de();try{let a=e.prepare(`INSERT INTO cron_runs(job_id, run_token_hash, status, execution_state, trigger_kind, config_snapshot, created_at, updated_at)
262
262
  VALUES (?, ?, 'pending', 'active', ?, ?, ?, ?)`).run(t,xh(s),r,n,i,i);return{kind:"claimed",run:Qe(e,Number(a.lastInsertRowid)),token:s}}catch(a){let c=a&&typeof a=="object"&&"code"in a?String(a.code):void 0;if(c!==void 0&&c.startsWith("SQLITE_CONSTRAINT")){let l=fr(e,t);if(l!==null)return l.status==="escalated"?{kind:"escalation",run:l}:{kind:"overlap",run:l}}throw a}})}function Hn(e,t,r,n){kt(()=>e.prepare(`UPDATE cron_runs SET status = 'running', execution_identity = ?, pid = ?, started_at = ?, updated_at = ?
263
263
  WHERE id = ? AND status = 'pending'`).run(JSON.stringify(r),n,de(),de(),t))}function Qo(e,t,r,n){e.prepare("UPDATE cron_runs SET execution_identity = ?, pid = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(r),n,de(),t)}function wN(e,t){kt(()=>e.prepare(`UPDATE cron_runs SET execution_state = 'gone', execution_gone_at = ?, execution_uncertain_reason = NULL, updated_at = ?
264
264
  WHERE id = ? AND execution_state != 'gone'`).run(de(),de(),t))}function Xo(e,t,r){kt(()=>e.prepare(`UPDATE cron_runs SET execution_state = 'uncertain', execution_uncertain_reason = ?, updated_at = ?
265
- WHERE id = ? AND execution_state != 'gone'`).run(r.slice(0,1024),de(),t))}function Vo(e,t,r){let n=Ee(e,t);if(Buffer.byteLength(n,"utf8")>r)throw new U("INVALID_ARGUMENT",`${t} exceeds ${r} bytes`);return n}function yN(e){if(e===void 0)return[];if(!Array.isArray(e))throw new U("INVALID_ARGUMENT","artifacts must be an array");if(e.length>ji)throw new U("INVALID_ARGUMENT",`at most ${ji} artifacts are allowed`);return e.map(t=>{if(typeof t!="string")throw new U("INVALID_ARGUMENT","artifacts must be strings");return Vo(t,"artifact",Ll)})}function Nh(e,t){if(e.status!=="succeeded"&&e.status!=="failed"&&e.status!=="escalated")throw new U("INVALID_ARGUMENT",'status must be "succeeded", "failed", or "escalated"');let r=Vo(e.summary,"summary",ln),n=yN(e.artifacts),o=null,s=null,i=null;if(e.status==="escalated"){o=Vo(e.action??"","requested action",Jo),i=e.reason!==void 0?Vo(e.reason,"escalation reason",Jo):r;let a=e.owner!==void 0?Vo(e.owner,"owner",Il):t;if(a===null||a.trim().length===0)throw new U("INVALID_ARGUMENT","an escalation requires an owner or a job with a configured default escalation owner");s=a}return{status:e.status,summary:r,artifacts:JSON.stringify(n),escalationAction:o,escalationOwner:s,escalationReason:i}}function Ih(e,t){return e.status===t.status&&e.summary===t.summary&&e.artifacts===t.artifacts&&e.escalation_action===t.escalationAction&&e.escalation_owner===t.escalationOwner&&e.escalation_reason===t.escalationReason}function Lh(e){try{let t=JSON.parse(e.config_snapshot);return typeof t.escalationOwner=="string"&&t.escalationOwner.trim().length>0?t.escalationOwner:null}catch{return null}}function Ol(e,t,r){let n=Nh(r,Lh(t)),o=de();if(e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, artifacts = ?, escalation_reason = ?, escalation_action = ?,
265
+ WHERE id = ? AND execution_state != 'gone'`).run(r.slice(0,1024),de(),t))}function Vo(e,t,r){let n=Ee(e,t);if(Buffer.byteLength(n,"utf8")>r)throw new P("INVALID_ARGUMENT",`${t} exceeds ${r} bytes`);return n}function yN(e){if(e===void 0)return[];if(!Array.isArray(e))throw new P("INVALID_ARGUMENT","artifacts must be an array");if(e.length>ji)throw new P("INVALID_ARGUMENT",`at most ${ji} artifacts are allowed`);return e.map(t=>{if(typeof t!="string")throw new P("INVALID_ARGUMENT","artifacts must be strings");return Vo(t,"artifact",Ll)})}function Nh(e,t){if(e.status!=="succeeded"&&e.status!=="failed"&&e.status!=="escalated")throw new P("INVALID_ARGUMENT",'status must be "succeeded", "failed", or "escalated"');let r=Vo(e.summary,"summary",ln),n=yN(e.artifacts),o=null,s=null,i=null;if(e.status==="escalated"){o=Vo(e.action??"","requested action",Jo),i=e.reason!==void 0?Vo(e.reason,"escalation reason",Jo):r;let a=e.owner!==void 0?Vo(e.owner,"owner",Il):t;if(a===null||a.trim().length===0)throw new P("INVALID_ARGUMENT","an escalation requires an owner or a job with a configured default escalation owner");s=a}return{status:e.status,summary:r,artifacts:JSON.stringify(n),escalationAction:o,escalationOwner:s,escalationReason:i}}function Ih(e,t){return e.status===t.status&&e.summary===t.summary&&e.artifacts===t.artifacts&&e.escalation_action===t.escalationAction&&e.escalation_owner===t.escalationOwner&&e.escalation_reason===t.escalationReason}function Lh(e){try{let t=JSON.parse(e.config_snapshot);return typeof t.escalationOwner=="string"&&t.escalationOwner.trim().length>0?t.escalationOwner:null}catch{return null}}function Ol(e,t,r){let n=Nh(r,Lh(t)),o=de();if(e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, artifacts = ?, escalation_reason = ?, escalation_action = ?,
266
266
  escalation_owner = ?, reported_at = ?, finished_at = ?, updated_at = ?
267
- WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(n.status,n.summary,n.artifacts,n.escalationReason,n.escalationAction,n.escalationOwner,o,o,o,t.id).changes===0){let i=Qe(e,t.id);if(Ih(i,n))return i;throw new U("CONFLICTING_REPORT",`Cron run ${t.id} already has a different terminal report`,4)}return Qe(e,t.id)}function Ch(e,t,r){return kt(()=>{let n=_N(e,xh(t));if(n===null)throw new U("NOT_FOUND","No cron run matches the supplied report token",3);if(n.reported_at!==null||n.status!=="pending"&&n.status!=="running"){let o=Nh(r,Lh(n));if(Ih(n,o))return n;throw new U("CONFLICTING_REPORT",`Cron run ${n.id} already has a different terminal report`,4)}return Ol(e,n,r)})}function Bn(e,t,r){let n=e.transaction(()=>{let o=Qe(e,t);o.reported_at===null&&(o.status==="pending"||o.status==="running")&&r.report!==void 0&&Ol(e,o,r.report);let s=Qe(e,t);if(s.reported_at===null&&(s.status==="pending"||s.status==="running")&&r.fallback!==void 0){let i=r.fallback.ok?"succeeded":"failed";e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(i,r.fallback.summary.slice(0,ln),de(),de(),t)}return wN(e,t),Qe(e,t)});return kt(()=>n.immediate())}function Oh(e,t,r){let n=e.transaction(()=>{let o=Qe(e,t);o.reported_at===null&&(o.status==="pending"||o.status==="running")&&r.report!==void 0&&Ol(e,o,r.report);let s=Qe(e,t);if(s.reported_at===null&&(s.status==="pending"||s.status==="running")&&r.fallback!==void 0){let i=r.fallback.ok?"succeeded":"failed";e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(i,r.fallback.summary.slice(0,ln),de(),de(),t)}return Qe(e,t)});return kt(()=>n.immediate())}function Dl(e,t,r){return kt(()=>{let n=Rh(e,t);if(n===null)return null;if(n.reported_at!==null||n.status!=="pending"&&n.status!=="running")return n;let o=r.ok?"succeeded":"failed";return e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(o,r.summary.slice(0,ln),de(),de(),n.id),Qe(e,n.id)})}function Dh(e,t,r={}){let n=e.transaction(()=>{let o=Qe(e,t),s=r.resolution!==void 0?r.resolution.trim():"",i=r.actor!==void 0?r.actor.trim():"",a=r.note!==void 0?r.note.trim():"",c=!1;if(o.execution_state!=="gone"){if(r.confirmStopped!==!0)throw new U("EXECUTION_FENCED",`Cron run ${t} execution state is "${o.execution_state}"; verify the process is gone and retry with --confirm-stopped`,4);e.prepare(`UPDATE cron_runs SET execution_state = 'gone', execution_gone_at = ?, execution_uncertain_reason = NULL,
267
+ WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(n.status,n.summary,n.artifacts,n.escalationReason,n.escalationAction,n.escalationOwner,o,o,o,t.id).changes===0){let i=Qe(e,t.id);if(Ih(i,n))return i;throw new P("CONFLICTING_REPORT",`Cron run ${t.id} already has a different terminal report`,4)}return Qe(e,t.id)}function Ch(e,t,r){return kt(()=>{let n=_N(e,xh(t));if(n===null)throw new P("NOT_FOUND","No cron run matches the supplied report token",3);if(n.reported_at!==null||n.status!=="pending"&&n.status!=="running"){let o=Nh(r,Lh(n));if(Ih(n,o))return n;throw new P("CONFLICTING_REPORT",`Cron run ${n.id} already has a different terminal report`,4)}return Ol(e,n,r)})}function Bn(e,t,r){let n=e.transaction(()=>{let o=Qe(e,t);o.reported_at===null&&(o.status==="pending"||o.status==="running")&&r.report!==void 0&&Ol(e,o,r.report);let s=Qe(e,t);if(s.reported_at===null&&(s.status==="pending"||s.status==="running")&&r.fallback!==void 0){let i=r.fallback.ok?"succeeded":"failed";e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(i,r.fallback.summary.slice(0,ln),de(),de(),t)}return wN(e,t),Qe(e,t)});return kt(()=>n.immediate())}function Oh(e,t,r){let n=e.transaction(()=>{let o=Qe(e,t);o.reported_at===null&&(o.status==="pending"||o.status==="running")&&r.report!==void 0&&Ol(e,o,r.report);let s=Qe(e,t);if(s.reported_at===null&&(s.status==="pending"||s.status==="running")&&r.fallback!==void 0){let i=r.fallback.ok?"succeeded":"failed";e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(i,r.fallback.summary.slice(0,ln),de(),de(),t)}return Qe(e,t)});return kt(()=>n.immediate())}function Dl(e,t,r){return kt(()=>{let n=Rh(e,t);if(n===null)return null;if(n.reported_at!==null||n.status!=="pending"&&n.status!=="running")return n;let o=r.ok?"succeeded":"failed";return e.prepare(`UPDATE cron_runs SET status = ?, summary = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(o,r.summary.slice(0,ln),de(),de(),n.id),Qe(e,n.id)})}function Dh(e,t,r={}){let n=e.transaction(()=>{let o=Qe(e,t),s=r.resolution!==void 0?r.resolution.trim():"",i=r.actor!==void 0?r.actor.trim():"",a=r.note!==void 0?r.note.trim():"",c=!1;if(o.execution_state!=="gone"){if(r.confirmStopped!==!0)throw new P("EXECUTION_FENCED",`Cron run ${t} execution state is "${o.execution_state}"; verify the process is gone and retry with --confirm-stopped`,4);e.prepare(`UPDATE cron_runs SET execution_state = 'gone', execution_gone_at = ?, execution_uncertain_reason = NULL,
268
268
  execution_confirmation_note = ?, updated_at = ? WHERE id = ? AND execution_state != 'gone'`).run(de(),a||s||"confirmed stopped by operator",de(),t),c=!0}o.status==="escalated"&&o.escalation_resolved_at===null&&(e.prepare(`UPDATE cron_runs SET escalation_resolved_at = ?, escalation_resolution = ?, escalation_resolution_actor = ?,
269
269
  escalation_resolution_note = ?, updated_at = ? WHERE id = ? AND escalation_resolved_at IS NULL`).run(de(),s||"resolved",i||"operator",a||s||"resolved",de(),t),c=!0);let l=Qe(e,t);if(l.reported_at===null&&(l.status==="pending"||l.status==="running")&&(e.prepare(`UPDATE cron_runs SET status = 'failed', summary = ?, finished_at = ?, updated_at = ?
270
- WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(`reconciled by operator without a worker report: ${a||s||"execution confirmed stopped"}`.slice(0,ln),de(),de(),t),c=!0),!c)throw new U("INVALID_ARGUMENT",`Cron run ${t} has no fenced execution or unresolved escalation to resolve`);let u=de();return e.prepare("UPDATE cron_jobs SET last_checked_ts = ?, updated_at = ? WHERE id = ? AND (last_checked_ts IS NULL OR last_checked_ts < ?)").run(u,u,o.job_id,u),Qe(e,t)});return kt(()=>n.immediate())}function Hi(e,t){if(!Number.isSafeInteger(t.limit)||t.limit<1||t.limit>Ie)throw new U("INVALID_ARGUMENT",`limit must be a positive integer <= ${Ie}`);return kt(()=>{let r=["id > ?"],n=[t.after];t.jobId!==void 0&&(r.push("job_id = ?"),n.push(t.jobId)),t.status!==void 0&&(r.push("status = ?"),n.push(t.status));let o=e.prepare(`SELECT * FROM cron_runs WHERE ${r.join(" AND ")} ORDER BY id LIMIT ?`).all(...n,t.limit+1),s=o.length>t.limit,i=s?o.slice(0,t.limit):o;return{rows:i,next_cursor:s?i[i.length-1].id:null}})}import{spawn as Ml}from"node:child_process";import{createHash as EN}from"node:crypto";import{existsSync as bN,mkdirSync as TN,mkdtempSync as SN,readFileSync as vN,rmSync as Mh,writeFileSync as qh}from"node:fs";import{homedir as AN,tmpdir as $N}from"node:os";import{isAbsolute as kN,join as ts,resolve as Wn}from"node:path";var xN=["lmctl"],RN=["miniplayer"],NN=10*6e4,IN=50*6e4,LN=50*6e4,Ph=24*60*6e4,jh=5e3,Bi=1024*1024;function Zo(){return{text:"",overflow:!1}}function es(e,t){if(e.overflow)return;let r=e.text+t.toString("utf8");r.length>Bi?(e.text=r.slice(0,Bi),e.overflow=!0):e.text=r}function Xe(e){return e instanceof Error?e.message:String(e)}function CN(e,t,r){try{Xo(e,t,r)}catch{}}function Ge(e,t,r){try{return Bn(e,t,r),!0}catch(n){return process.stderr.write(`[lmcron] run ${t} completion could not be committed (fence retained): ${Xe(n)}
270
+ WHERE id = ? AND status IN ${zo} AND reported_at IS NULL`).run(`reconciled by operator without a worker report: ${a||s||"execution confirmed stopped"}`.slice(0,ln),de(),de(),t),c=!0),!c)throw new P("INVALID_ARGUMENT",`Cron run ${t} has no fenced execution or unresolved escalation to resolve`);let u=de();return e.prepare("UPDATE cron_jobs SET last_checked_ts = ?, updated_at = ? WHERE id = ? AND (last_checked_ts IS NULL OR last_checked_ts < ?)").run(u,u,o.job_id,u),Qe(e,t)});return kt(()=>n.immediate())}function Hi(e,t){if(!Number.isSafeInteger(t.limit)||t.limit<1||t.limit>Ie)throw new P("INVALID_ARGUMENT",`limit must be a positive integer <= ${Ie}`);return kt(()=>{let r=["id > ?"],n=[t.after];t.jobId!==void 0&&(r.push("job_id = ?"),n.push(t.jobId)),t.status!==void 0&&(r.push("status = ?"),n.push(t.status));let o=e.prepare(`SELECT * FROM cron_runs WHERE ${r.join(" AND ")} ORDER BY id LIMIT ?`).all(...n,t.limit+1),s=o.length>t.limit,i=s?o.slice(0,t.limit):o;return{rows:i,next_cursor:s?i[i.length-1].id:null}})}import{spawn as Ml}from"node:child_process";import{createHash as EN}from"node:crypto";import{existsSync as bN,mkdirSync as TN,mkdtempSync as SN,readFileSync as vN,rmSync as Mh,writeFileSync as qh}from"node:fs";import{homedir as AN,tmpdir as $N}from"node:os";import{isAbsolute as kN,join as ts,resolve as Wn}from"node:path";var xN=["lmctl"],RN=["miniplayer"],NN=10*6e4,IN=50*6e4,LN=50*6e4,Ph=24*60*6e4,jh=5e3,Bi=1024*1024;function Zo(){return{text:"",overflow:!1}}function es(e,t){if(e.overflow)return;let r=e.text+t.toString("utf8");r.length>Bi?(e.text=r.slice(0,Bi),e.overflow=!0):e.text=r}function Xe(e){return e instanceof Error?e.message:String(e)}function CN(e,t,r){try{Xo(e,t,r)}catch{}}function Ge(e,t,r){try{return Bn(e,t,r),!0}catch(n){return process.stderr.write(`[lmcron] run ${t} completion could not be committed (fence retained): ${Xe(n)}
271
271
  `),!1}}function Et(e,t,r,n){CN(e,t,r);try{Oh(e,t,n)}catch(o){process.stderr.write(`[lmcron] run ${t} outcome could not be persisted (fence retained): ${Xe(o)}
272
- `)}}function Pl(e,t,r){if(e===null)throw new Error(`${r}: disabling timeout is supported only for script workers`);let n=e??t;if(!Number.isFinite(n)||n<=0||n>Ph)throw new Error(`${r} must be a positive number of milliseconds <= ${Ph}`);return n}var Uh=new Set(["claude","codex","opencode","lmplayer","gemini","copilot","qwen","agy","kimi","dsh","hermes","ClaudeMock"]),ON=/^[A-Za-z0-9][A-Za-z0-9._:@/+~-]*$/;function Fl(e){if(!Uh.has(e))throw new U("INVALID_ARGUMENT",`provider "${e}" is not one of lmctl's supported providers (${[...Uh].join(", ")})`);return e}function ql(e){if(!ON.test(e))throw new U("INVALID_ARGUMENT",`model "${e}" is not a safe lmctl model token (no whitespace, quotes, '=' or control characters)`);return e}function Wi(e){if(!kN(e))throw new U("INVALID_ARGUMENT",`sessiondir "${e}" must be an absolute path`);if(/["\u0000-\u001f\u007f]/.test(e))throw new U("INVALID_ARGUMENT",`sessiondir contains a quote, newline, or control character that lmctl cannot represent: ${JSON.stringify(e)}`);return e}function DN(e){let t=["_MEMBER_",`alias=${e.alias}`,`provider=${Fl(e.provider)}`];return e.model!==null&&e.model!==void 0&&t.push(`model=${ql(e.model)}`),t.push(`sessiondir="${Wi(e.sessiondir)}"`),t.join(" ")}function MN(e){let t=e.name,r=t!==void 0&&t.length>0?Wn(t):":memory:";return EN("sha256").update(r,"utf8").digest("hex").slice(0,16)}function PN(){return process.env.LMBEE_CRON_SESSION_DIR?process.env.LMBEE_CRON_SESSION_DIR:ts(AN(),".lmbee","cron-sessions")}function UN(e){return`'${e.replace(/'/g,"'\\''")}'`}function FN(e){let t=e.name;return t!==void 0&&t.length>0&&t!==":memory:"?`LMBEE_DB=${UN(Wn(t))} `:""}function qN(e,t,r){let n=FN(r);return`${e}
272
+ `)}}function Pl(e,t,r){if(e===null)throw new Error(`${r}: disabling timeout is supported only for script workers`);let n=e??t;if(!Number.isFinite(n)||n<=0||n>Ph)throw new Error(`${r} must be a positive number of milliseconds <= ${Ph}`);return n}var Uh=new Set(["claude","codex","opencode","lmplayer","gemini","copilot","qwen","agy","kimi","dsh","hermes","ClaudeMock"]),ON=/^[A-Za-z0-9][A-Za-z0-9._:@/+~-]*$/;function Fl(e){if(!Uh.has(e))throw new P("INVALID_ARGUMENT",`provider "${e}" is not one of lmctl's supported providers (${[...Uh].join(", ")})`);return e}function ql(e){if(!ON.test(e))throw new P("INVALID_ARGUMENT",`model "${e}" is not a safe lmctl model token (no whitespace, quotes, '=' or control characters)`);return e}function Wi(e){if(!kN(e))throw new P("INVALID_ARGUMENT",`sessiondir "${e}" must be an absolute path`);if(/["\u0000-\u001f\u007f]/.test(e))throw new P("INVALID_ARGUMENT",`sessiondir contains a quote, newline, or control character that lmctl cannot represent: ${JSON.stringify(e)}`);return e}function DN(e){let t=["_MEMBER_",`alias=${e.alias}`,`provider=${Fl(e.provider)}`];return e.model!==null&&e.model!==void 0&&t.push(`model=${ql(e.model)}`),t.push(`sessiondir="${Wi(e.sessiondir)}"`),t.join(" ")}function MN(e){let t=e.name,r=t!==void 0&&t.length>0?Wn(t):":memory:";return EN("sha256").update(r,"utf8").digest("hex").slice(0,16)}function PN(){return process.env.LMBEE_CRON_SESSION_DIR?process.env.LMBEE_CRON_SESSION_DIR:ts(AN(),".lmbee","cron-sessions")}function UN(e){return`'${e.replace(/'/g,"'\\''")}'`}function FN(e){let t=e.name;return t!==void 0&&t.length>0&&t!==":memory:"?`LMBEE_DB=${UN(Wn(t))} `:""}function qN(e,t,r){let n=FN(r);return`${e}
273
273
 
274
274
  ---
275
275
  When you have finished, report the outcome exactly once by running this command (the token is
@@ -288,25 +288,25 @@ Respond with EXACTLY one line of strict JSON and no other text, using this run t
288
288
 
289
289
  For an escalation use {"run_token":"...","status":"escalated","summary":"...","escalation":{"owner":"...","reason":"...","requestedAction":"..."}}.
290
290
  Escalation reason and requestedAction are required. Never claim succeeded unless the work actually
291
- succeeded.`}var HN=new Set(["run_token","status","summary","artifacts","escalation"]),BN=new Set(["owner","reason","requestedAction"]);function Hh(e,t){if(e===null)return{ok:!1,reason:"no output"};if(Buffer.byteLength(e,"utf8")>Cl)return{ok:!1,reason:`result exceeds ${Cl} bytes`};let r=e.trim();if(r.length===0)return{ok:!1,reason:"empty output"};let n;try{n=JSON.parse(r)}catch{return{ok:!1,reason:"output is not a single JSON object"}}if(typeof n!="object"||n===null||Array.isArray(n))return{ok:!1,reason:"output is not a JSON object"};let o=n;for(let c of Object.keys(o))if(!HN.has(c))return{ok:!1,reason:`unknown field "${c}"`};if(o.run_token!==t)return{ok:!1,reason:"run token missing or mismatched"};let s=o.status;if(s!=="succeeded"&&s!=="failed"&&s!=="escalated")return{ok:!1,reason:"status must be succeeded, failed, or escalated"};if(typeof o.summary!="string"||o.summary.trim().length===0)return{ok:!1,reason:"summary must be a nonblank string"};if(Buffer.byteLength(o.summary,"utf8")>ln)return{ok:!1,reason:"summary is too large"};let i=[];if(o.artifacts!==void 0){if(!Array.isArray(o.artifacts)||o.artifacts.length>ji)return{ok:!1,reason:"artifacts must be an array of at most 100 strings"};for(let c of o.artifacts)if(typeof c!="string"||c.trim().length===0||Buffer.byteLength(c,"utf8")>Ll)return{ok:!1,reason:"each artifact must be a nonblank string of at most 4096 bytes"};i=o.artifacts}let a={status:s,summary:o.summary.trim(),artifacts:i};if(s==="escalated"){let c=o.escalation;if(typeof c!="object"||c===null||Array.isArray(c))return{ok:!1,reason:"an escalated result requires an escalation object"};let l=c;for(let u of Object.keys(l))if(!BN.has(u))return{ok:!1,reason:`unknown escalation field "${u}"`};if(typeof l.reason!="string"||l.reason.trim().length===0||Buffer.byteLength(l.reason,"utf8")>Jo)return{ok:!1,reason:"escalation.reason is required and bounded"};if(typeof l.requestedAction!="string"||l.requestedAction.trim().length===0||Buffer.byteLength(l.requestedAction,"utf8")>Jo)return{ok:!1,reason:"escalation.requestedAction is required and bounded"};if(a.reason=l.reason.trim(),a.action=l.requestedAction.trim(),l.owner!==void 0){if(typeof l.owner!="string"||l.owner.trim().length===0||l.owner.length>Il)return{ok:!1,reason:"escalation.owner must be a nonblank string of at most 512 chars"};a.owner=l.owner.trim()}}return{ok:!0,result:a}}function WN(e,t,r){let n=t.session_alias??"Worker";if(t.working_directory===null||t.provider===null)throw new U("INVALID_ARGUMENT",`session job ${t.id} requires provider and an absolute working_directory`);let o=ts(r??PN(),MN(e)),s=t.session_generation??0,i=t.session_teamfile??ts(o,`job-${t.id}-g${s}.lmctl`);if(t.session_teamfile!==null)return{teamfile:t.session_teamfile,alias:n};if(bN(i))return e.prepare("UPDATE cron_jobs SET session_teamfile = ?, session_alias = ?, updated_at = ? WHERE id = ?").run(i,n,new Date().toISOString(),t.id),{teamfile:i,alias:n};TN(o,{recursive:!0});let a=DN({alias:n,provider:t.provider,model:t.model,sessiondir:t.working_directory});return qh(i,`#teamfile: ${i}
291
+ succeeded.`}var HN=new Set(["run_token","status","summary","artifacts","escalation"]),BN=new Set(["owner","reason","requestedAction"]);function Hh(e,t){if(e===null)return{ok:!1,reason:"no output"};if(Buffer.byteLength(e,"utf8")>Cl)return{ok:!1,reason:`result exceeds ${Cl} bytes`};let r=e.trim();if(r.length===0)return{ok:!1,reason:"empty output"};let n;try{n=JSON.parse(r)}catch{return{ok:!1,reason:"output is not a single JSON object"}}if(typeof n!="object"||n===null||Array.isArray(n))return{ok:!1,reason:"output is not a JSON object"};let o=n;for(let c of Object.keys(o))if(!HN.has(c))return{ok:!1,reason:`unknown field "${c}"`};if(o.run_token!==t)return{ok:!1,reason:"run token missing or mismatched"};let s=o.status;if(s!=="succeeded"&&s!=="failed"&&s!=="escalated")return{ok:!1,reason:"status must be succeeded, failed, or escalated"};if(typeof o.summary!="string"||o.summary.trim().length===0)return{ok:!1,reason:"summary must be a nonblank string"};if(Buffer.byteLength(o.summary,"utf8")>ln)return{ok:!1,reason:"summary is too large"};let i=[];if(o.artifacts!==void 0){if(!Array.isArray(o.artifacts)||o.artifacts.length>ji)return{ok:!1,reason:"artifacts must be an array of at most 100 strings"};for(let c of o.artifacts)if(typeof c!="string"||c.trim().length===0||Buffer.byteLength(c,"utf8")>Ll)return{ok:!1,reason:"each artifact must be a nonblank string of at most 4096 bytes"};i=o.artifacts}let a={status:s,summary:o.summary.trim(),artifacts:i};if(s==="escalated"){let c=o.escalation;if(typeof c!="object"||c===null||Array.isArray(c))return{ok:!1,reason:"an escalated result requires an escalation object"};let l=c;for(let u of Object.keys(l))if(!BN.has(u))return{ok:!1,reason:`unknown escalation field "${u}"`};if(typeof l.reason!="string"||l.reason.trim().length===0||Buffer.byteLength(l.reason,"utf8")>Jo)return{ok:!1,reason:"escalation.reason is required and bounded"};if(typeof l.requestedAction!="string"||l.requestedAction.trim().length===0||Buffer.byteLength(l.requestedAction,"utf8")>Jo)return{ok:!1,reason:"escalation.requestedAction is required and bounded"};if(a.reason=l.reason.trim(),a.action=l.requestedAction.trim(),l.owner!==void 0){if(typeof l.owner!="string"||l.owner.trim().length===0||l.owner.length>Il)return{ok:!1,reason:"escalation.owner must be a nonblank string of at most 512 chars"};a.owner=l.owner.trim()}}return{ok:!0,result:a}}function WN(e,t,r){let n=t.session_alias??"Worker";if(t.working_directory===null||t.provider===null)throw new P("INVALID_ARGUMENT",`session job ${t.id} requires provider and an absolute working_directory`);let o=ts(r??PN(),MN(e)),s=t.session_generation??0,i=t.session_teamfile??ts(o,`job-${t.id}-g${s}.lmctl`);if(t.session_teamfile!==null)return{teamfile:t.session_teamfile,alias:n};if(bN(i))return e.prepare("UPDATE cron_jobs SET session_teamfile = ?, session_alias = ?, updated_at = ? WHERE id = ?").run(i,n,new Date().toISOString(),t.id),{teamfile:i,alias:n};TN(o,{recursive:!0});let a=DN({alias:n,provider:t.provider,model:t.model,sessiondir:t.working_directory});return qh(i,`#teamfile: ${i}
292
292
  # private single-member session for lmbee cron job ${t.id} (generation ${s})
293
293
 
294
294
  ${a}
295
295
  `,{mode:384}),e.prepare("UPDATE cron_jobs SET session_teamfile = ?, session_alias = ?, updated_at = ? WHERE id = ?").run(i,n,new Date().toISOString(),t.id),{teamfile:i,alias:n}}function jl(e){try{return process.kill(-e,0),!0}catch{return!1}}function Ul(e,t){if(e.pid===void 0)return;let r=e.pid;try{process.kill(-r,"SIGTERM")}catch{return}setTimeout(()=>{try{process.kill(-r,0)}catch{return}try{process.kill(-r,"SIGKILL")}catch{}},t).unref()}function GN(e){let t=null,r=null,n=null,o=null;for(let s of e.split(`
296
296
  `)){let i=s.trim();if(i.length===0)continue;let a;try{a=JSON.parse(i)}catch{continue}if(typeof a!="object"||a===null)continue;let c=a,l=typeof c.message=="string"?c.message:String(c.status);c.status==="ok"&&typeof c.replyText=="string"?t=c.replyText:c.status==="stalled"?r=l:c.status==="busy"?n=l:(c.status==="error"||c.status==="failed")&&(o=l)}return r!==null?{kind:"stalled",message:r}:n!==null?{kind:"busy",message:n}:o!==null?{kind:"error",message:o}:t!==null?{kind:"completed",text:t}:{kind:"none"}}function Hl(e,t){try{let r=vN(e,"utf8").trim();return r.length>t?r.slice(-t):r}catch{return""}}var VN=500,Fh=75;function JN(e){let{db:t,job:r,run:n}=e;try{Hn(t,n.id,{kind:"script",cwd:r.working_directory},null)}catch(o){Ge(t,n.id,{fallback:{ok:!1,summary:`script setup failed before spawn: ${Xe(o)}`}});return}try{Go({id:r.id,action_payload:r.action_payload},{...e.logDir!==void 0?{logDir:e.logDir}:{},...r.working_directory!==null?{cwd:r.working_directory}:{},...e.spawnPrefixes?.script!==void 0?{spawnPrefix:e.spawnPrefixes.script}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},...e.sigkillGraceMs!==void 0?{sigkillGraceMs:e.sigkillGraceMs}:{},...t.name!==void 0&&t.name!==":memory:"?{env:{...process.env,LMBEE_DB:Wn(t.name)}}:{},onExit:(o,s,i,a)=>{if(s!==void 0){Ge(t,n.id,{fallback:{ok:!1,summary:`script spawn error: ${s.message}`}});return}let c=o===0||o===Fh,l=Hl(a,VN),u=o===Fh?`script no-op (exit ${o})${l?`: ${l}`:""}`:`script exited with code ${o}${l?`: ${l}`:""}`;i!==null&&jl(i)?Et(t,n.id,"process group still alive after exit",{fallback:{ok:c,summary:u}}):Ge(t,n.id,{fallback:{ok:c,summary:u}})}})}catch(o){Ge(t,n.id,{fallback:{ok:!1,summary:`script spawn error: ${Xe(o)}`}})}}function zN(e){let{db:t,job:r,run:n}=e,o,s,i,a;try{o=Pl(e.timeoutMs,NN,"timeoutMs"),s=e.sigkillGraceMs??jh,i=[...e.spawnPrefixes?.miniplayer??RN,"run",...r.model!==null?["-m",r.model]:[]],a=jN(r.action_payload,e.runToken)}catch(g){Ge(t,n.id,{fallback:{ok:!1,summary:`miniplayer setup failed before spawn: ${Xe(g)}`}});return}let[c,...l]=i,u;try{u=Ml(c,l,{detached:!0,stdio:["pipe","pipe","pipe"],...r.working_directory!==null?{cwd:r.working_directory}:{},...t.name!==void 0&&t.name!==":memory:"?{env:{...process.env,LMBEE_DB:Wn(t.name)}}:{}})}catch(g){Ge(t,n.id,{fallback:{ok:!1,summary:`miniplayer spawn error: ${Xe(g)}`}});return}u.unref();let d=Zo(),m=Zo(),f=!1,p=!1,h=setTimeout(()=>{f||(f=!0,Ul(u,s),Et(t,n.id,`miniplayer timed out after ${o}ms`,{fallback:{ok:!1,summary:`miniplayer timed out after ${o}ms`}}))},o);h.unref(),u.on("spawn",()=>p=!0),u.stdout?.on("data",g=>es(d,g)),u.stderr?.on("data",g=>es(m,g)),u.stdin?.on("error",()=>{}),u.on("error",g=>{if(f)return;f=!0,clearTimeout(h);let _={fallback:{ok:!1,summary:`miniplayer spawn error: ${g.message}`}};p?Et(t,n.id,`miniplayer post-spawn error: ${g.message}`,_):Ge(t,n.id,_)}),u.on("close",(g,_)=>{if(f)return;f=!0,clearTimeout(h);let E=u.pid??null,y=E!==null&&jl(E),S=d.overflow?{ok:!1,reason:`output exceeded the ${Bi}-byte capture limit`}:Hh(d.text,e.runToken),T=S.ok?{report:S.result}:{fallback:{ok:!1,summary:`miniplayer produced no valid structured result (${S.reason})`+(g!==0||_!==null?`; exit ${_??g}: ${m.text.trim().slice(-300)}`:"")}};y?Et(t,n.id,"miniplayer process group still alive after wrapper exit",T):d.overflow?Et(t,n.id,"miniplayer output exceeded the capture limit; result not trusted",T):Ge(t,n.id,T)});try{Hn(t,n.id,{kind:"miniplayer",model:r.model},u.pid??null)}catch(g){process.stderr.write(`[lmcron] miniplayer run ${n.id} state write failed after spawn: ${Xe(g)}
297
297
  `)}try{u.stdin?.write(a),u.stdin?.end()}catch(g){process.stderr.write(`[lmcron] miniplayer run ${n.id} stdin write failed: ${Xe(g)}
298
- `)}}function YN(e){let{db:t,job:r,run:n}=e,o,s,i;try{o=Pl(e.timeoutMs,IN,"timeoutMs"),s=Pl(e.seedTimeoutMs,LN,"seedTimeoutMs"),i=e.sigkillGraceMs??jh}catch(y){Ge(t,n.id,{fallback:{ok:!1,summary:`session setup failed before spawn: ${Xe(y)}`}});return}let a,c;try{({teamfile:a,alias:c}=WN(t,r,e.sessionDir))}catch(y){Ge(t,n.id,{fallback:{ok:!1,summary:`session teamfile creation failed: ${Xe(y)}`}});return}let l=()=>{let y=e.spawnPrefixes?.chat??en,S,T,R;try{let J=qN(r.action_payload,e.runToken,t);S=SN(ts($N(),"lmbee-cron-session-")),T=ts(S,`${n.id}.md`),qh(T,J,{mode:384}),R=[...y,"chat",`${a}:${c}`,"--prompt-file",T,"--json"]}catch(J){Ge(t,n.id,{fallback:{ok:!1,summary:`session dispatch setup failed before spawn: ${Xe(J)}`}});return}let[A,...I]=R,x;try{x=Ml(A,I,{detached:!0,stdio:["ignore","pipe","pipe"],...r.working_directory!==null?{cwd:r.working_directory}:{},...t.name!==void 0&&t.name!==":memory:"?{env:{...process.env,LMBEE_DB:Wn(t.name)}}:{}})}catch(J){try{Mh(S,{recursive:!0,force:!0})}catch{}Ge(t,n.id,{fallback:{ok:!1,summary:`session dispatch spawn error: ${Xe(J)}`}});return}x.unref();let H=Zo(),C=Zo(),w=!1,b=!1,N=()=>{try{Mh(S,{recursive:!0,force:!0})}catch{}},P=setTimeout(()=>{w||(w=!0,Ul(x,i),Et(t,n.id,`session timed out after ${o}ms`,{fallback:{ok:!1,summary:`session timed out after ${o}ms`}}))},o);P.unref(),x.on("spawn",()=>b=!0),x.stdout?.on("data",J=>es(H,J)),x.stderr?.on("data",J=>es(C,J)),x.on("error",J=>{if(w)return;w=!0,clearTimeout(P);let ee={fallback:{ok:!1,summary:`session dispatch spawn error: ${J.message}`}};b?Et(t,n.id,`session post-spawn error: ${J.message}`,ee):(N(),Ge(t,n.id,ee))}),x.on("close",J=>{if(w)return;w=!0,clearTimeout(P);let ee=x.pid??null,oe=ee!==null&&jl(ee),V=H.overflow?{kind:"overflow"}:GN(H.text),se=V.kind==="completed"?Hh(V.text,e.runToken):null,k=V.kind==="completed"&&!oe&&!H.overflow,O=se!==null&&se.ok?{report:se.result}:{fallback:{ok:!1,summary:(V.kind==="completed"?"session ended without a valid report":V.kind==="stalled"?"session stalled (native turn still running)":V.kind==="busy"?"session was busy; not started":V.kind==="error"?`session provider error: ${V.message}`:V.kind==="overflow"?`session output exceeded the ${Bi}-byte capture limit`:"session ended without positive completion")+(J!==0?` (exit ${J}: ${C.text.trim().slice(-300)})`:"")}};if(k){if(se!==null&&!se.ok){N(),Ge(t,n.id,O);return}if(Ge(t,n.id,O)){N();return}return}let $=V.kind==="stalled"?`session stalled (native turn still running): ${V.message}`:V.kind==="busy"?`session busy (a live worker may own it): ${V.message}`:V.kind==="error"?`session provider error (termination unconfirmed): ${V.message}`:V.kind==="overflow"?"session output exceeded the capture limit; result not trusted":oe?"session process group still alive after wrapper exit":`session wrapper exited without positive completion (code ${J})`;Et(t,n.id,$,O)});try{Hn(t,n.id,{kind:"session",provider:r.provider,model:r.model,teamfile:a,alias:c},x.pid??null)}catch(J){process.stderr.write(`[lmcron] session run ${n.id} state write failed after spawn: ${Xe(J)}
299
- `)}try{Qo(t,n.id,{kind:"session",phase:"dispatch",teamfile:a,alias:c},x.pid??null)}catch{}};if(r.session_seeded_at!==null){l();return}let d=[...e.spawnPrefixes?.seed??xN,"seed",a],m=d[0],f=d.slice(1),p;try{p=Ml(m,f,{detached:!0,stdio:["ignore","ignore","pipe"],...t.name!==void 0&&t.name!==":memory:"?{env:{...process.env,LMBEE_DB:Wn(t.name)}}:{}})}catch(y){Ge(t,n.id,{fallback:{ok:!1,summary:`session seed spawn error: ${Xe(y)}`}});return}p.unref();let h=Zo(),g=!1,_=!1,E=setTimeout(()=>{g||(g=!0,Ul(p,i),Et(t,n.id,`session seed timed out after ${s}ms; provider initialization may still be running`,{fallback:{ok:!1,summary:`session seed timed out after ${s}ms`}}))},s);E.unref(),p.on("spawn",()=>_=!0),p.stderr?.on("data",y=>es(h,y)),p.on("error",y=>{if(g)return;g=!0,clearTimeout(E);let S={fallback:{ok:!1,summary:`session seed spawn error: ${y.message}`}};_?Et(t,n.id,`session seed post-spawn error: ${y.message}`,S):Ge(t,n.id,S)}),p.on("close",y=>{if(!g){if(g=!0,clearTimeout(E),y!==0){Et(t,n.id,`session seed failed (exit ${y}); provider initialization may still be running`,{fallback:{ok:!1,summary:`session seed failed (exit ${y}): ${h.text.trim().slice(-300)}`}});return}try{t.prepare("UPDATE cron_jobs SET session_seeded_at = ?, updated_at = ? WHERE id = ?").run(new Date().toISOString(),new Date().toISOString(),r.id)}catch(S){Et(t,n.id,`session seeded but recording identity failed: ${Xe(S)}`,{fallback:{ok:!1,summary:"session seeded but recording seed state failed; will recover on retry"}});return}l()}});try{Qo(t,n.id,{kind:"session",phase:"seed",teamfile:a,alias:c},p.pid??null)}catch{}}function Bl(e){try{switch(e.job.action_kind){case"script":JN(e);return;case"miniplayer":zN(e);return;case"session":YN(e);return;default:Ge(e.db,e.run.id,{fallback:{ok:!1,summary:`unsupported run worker kind: ${e.job.action_kind}`}})}}catch(t){Et(e.db,e.run.id,`unexpected worker dispatch failure: ${Xe(t)}`,{fallback:{ok:!1,summary:`worker dispatch error: ${Xe(t)}`}})}}function QN(e){return e==="enqueue"||e==="command"||e==="script"||e==="session"||e==="miniplayer"}function XN(e){return e==="script"||e==="session"||e==="miniplayer"}function bt(e){return e instanceof Error?e.message:String(e)}function Gn(e){let t=e&&typeof e=="object"&&"code"in e?String(e.code):void 0;if(t!==void 0&&(t.startsWith("SQLITE_BUSY")||t.startsWith("SQLITE_LOCKED")))throw new U("DB_BUSY","Database busy; retry after the current writer completes",5);let r=e instanceof Error?e.message:String(e);throw t!==void 0&&t.startsWith("SQLITE_CONSTRAINT")?new U("STRUCTURAL_ERROR",r,2):new U("STORAGE_ERROR",r,1)}function pr(e){try{return e()}catch(t){if(t instanceof U)throw t;if(t instanceof L)throw new U(t.code,t.message,t.exitCode);return Gn(t)}}function Gi(e,t){e.prepare("UPDATE cron_jobs SET revision = revision + 1, updated_at = ? WHERE id = ?").run(de(),t)}function Vi(e,t){return pr(()=>e.prepare("SELECT * FROM cron_jobs WHERE id = ?").get(t)??null)}function Le(e,t){let r=Vi(e,t);if(r===null)throw new U("NOT_FOUND",`Cron job ${t} does not exist`,3);return r}function ZN(e){let t;try{t=JSON.parse(e)}catch{throw new U("INVALID_ARGUMENT","enqueue action_payload must be valid JSON")}if(typeof t!="object"||t===null)throw new U("INVALID_ARGUMENT","enqueue action_payload must be a JSON object");let{to:r,prompt:n,from:o}=t;if(typeof r!="string"||r.trim().length===0)throw new U("INVALID_ARGUMENT",'enqueue action_payload requires a nonblank "to"');if(typeof n!="string"||n.trim().length===0)throw new U("INVALID_ARGUMENT",'enqueue action_payload requires a nonblank "prompt"');if(o!==void 0&&(typeof o!="string"||o.trim().length===0))throw new U("INVALID_ARGUMENT",'enqueue action_payload "from", if given, must be a nonblank string')}function Gh(e,t){Ee(t,"action_payload"),e==="enqueue"&&ZN(t)}function Vh(e){let{actionKind:t}=e;if(t==="session"){if(e.provider===void 0||e.provider===null||e.provider.trim().length===0)throw new U("INVALID_ARGUMENT","a session job requires a nonblank provider");if(Fl(e.provider),e.workingDirectory===void 0||e.workingDirectory===null||e.workingDirectory.trim().length===0)throw new U("INVALID_ARGUMENT","a session job requires an absolute working_directory (--cwd)");Wi(e.workingDirectory)}else if(e.provider!==void 0&&e.provider!==null&&e.provider.trim().length>0)throw new U("INVALID_ARGUMENT",`provider is only valid for session jobs (not ${t})`);if(e.model!==void 0&&e.model!==null&&e.model.trim().length===0)throw new U("INVALID_ARGUMENT","model, if given, must be nonblank");if(e.model!==void 0&&e.model!==null&&e.model.trim().length>0&&t!=="session"&&t!=="miniplayer")throw new U("INVALID_ARGUMENT",`model is only valid for session/miniplayer jobs (not ${t})`);if(e.model!==void 0&&e.model!==null&&e.model.trim().length>0&&ql(e.model),e.workingDirectory!==void 0&&e.workingDirectory!==null&&e.workingDirectory.trim().length>0&&t==="enqueue")throw new U("INVALID_ARGUMENT","working_directory is not valid for enqueue jobs");if(e.workingDirectory!==void 0&&e.workingDirectory!==null&&e.workingDirectory.trim().length===0)throw new U("INVALID_ARGUMENT","working_directory, if given, must be nonblank");if(e.escalationOwner!==void 0&&e.escalationOwner!==null&&e.escalationOwner.trim().length===0)throw new U("INVALID_ARGUMENT","escalation_owner, if given, must be nonblank")}function Jh(e){let t=Ee(e,"timezone");try{new Intl.DateTimeFormat(void 0,{timeZone:t})}catch{throw new U("INVALID_ARGUMENT",`timezone "${t}" is not a recognized IANA zone name`)}return t}function zh(e){let t=Nl(e);if(!t.ok){let r=t.error.field?` (field: ${t.error.field})`:"";throw new U("INVALID_SCHEDULE",`${t.error.message}${r}`)}}function Vn(e,t){let r=e.transaction(()=>{if(t.id!==void 0&&(!Number.isSafeInteger(t.id)||t.id<1))throw new U("INVALID_ARGUMENT","id, if given, must be a positive safe integer");let n=Ee(t.title,"title");if(!QN(t.actionKind))throw new U("INVALID_ARGUMENT",'action_kind must be "enqueue", "command", "script", "session", or "miniplayer"');zh(t.scheduleExpr),Gh(t.actionKind,t.actionPayload),Vh({actionKind:t.actionKind,provider:t.provider??null,model:t.model??null,workingDirectory:t.workingDirectory??null,escalationOwner:t.escalationOwner??null});let o=t.timezone!==void 0?Jh(t.timezone):null,s=de();try{let i=e.prepare(t.id!==void 0?`INSERT INTO cron_jobs(id, title, schedule_expr, action_kind, action_payload, provider, model,
298
+ `)}}function YN(e){let{db:t,job:r,run:n}=e,o,s,i;try{o=Pl(e.timeoutMs,IN,"timeoutMs"),s=Pl(e.seedTimeoutMs,LN,"seedTimeoutMs"),i=e.sigkillGraceMs??jh}catch(y){Ge(t,n.id,{fallback:{ok:!1,summary:`session setup failed before spawn: ${Xe(y)}`}});return}let a,c;try{({teamfile:a,alias:c}=WN(t,r,e.sessionDir))}catch(y){Ge(t,n.id,{fallback:{ok:!1,summary:`session teamfile creation failed: ${Xe(y)}`}});return}let l=()=>{let y=e.spawnPrefixes?.chat??en,S,T,R;try{let W=qN(r.action_payload,e.runToken,t);S=SN(ts($N(),"lmbee-cron-session-")),T=ts(S,`${n.id}.md`),qh(T,W,{mode:384}),R=[...y,"chat",`${a}:${c}`,"--prompt-file",T,"--json"]}catch(W){Ge(t,n.id,{fallback:{ok:!1,summary:`session dispatch setup failed before spawn: ${Xe(W)}`}});return}let[A,...I]=R,x;try{x=Ml(A,I,{detached:!0,stdio:["ignore","pipe","pipe"],...r.working_directory!==null?{cwd:r.working_directory}:{},...t.name!==void 0&&t.name!==":memory:"?{env:{...process.env,LMBEE_DB:Wn(t.name)}}:{}})}catch(W){try{Mh(S,{recursive:!0,force:!0})}catch{}Ge(t,n.id,{fallback:{ok:!1,summary:`session dispatch spawn error: ${Xe(W)}`}});return}x.unref();let H=Zo(),C=Zo(),w=!1,b=!1,N=()=>{try{Mh(S,{recursive:!0,force:!0})}catch{}},M=setTimeout(()=>{w||(w=!0,Ul(x,i),Et(t,n.id,`session timed out after ${o}ms`,{fallback:{ok:!1,summary:`session timed out after ${o}ms`}}))},o);M.unref(),x.on("spawn",()=>b=!0),x.stdout?.on("data",W=>es(H,W)),x.stderr?.on("data",W=>es(C,W)),x.on("error",W=>{if(w)return;w=!0,clearTimeout(M);let ee={fallback:{ok:!1,summary:`session dispatch spawn error: ${W.message}`}};b?Et(t,n.id,`session post-spawn error: ${W.message}`,ee):(N(),Ge(t,n.id,ee))}),x.on("close",W=>{if(w)return;w=!0,clearTimeout(M);let ee=x.pid??null,oe=ee!==null&&jl(ee),J=H.overflow?{kind:"overflow"}:GN(H.text),se=J.kind==="completed"?Hh(J.text,e.runToken):null,k=J.kind==="completed"&&!oe&&!H.overflow,O=se!==null&&se.ok?{report:se.result}:{fallback:{ok:!1,summary:(J.kind==="completed"?"session ended without a valid report":J.kind==="stalled"?"session stalled (native turn still running)":J.kind==="busy"?"session was busy; not started":J.kind==="error"?`session provider error: ${J.message}`:J.kind==="overflow"?`session output exceeded the ${Bi}-byte capture limit`:"session ended without positive completion")+(W!==0?` (exit ${W}: ${C.text.trim().slice(-300)})`:"")}};if(k){if(se!==null&&!se.ok){N(),Ge(t,n.id,O);return}if(Ge(t,n.id,O)){N();return}return}let $=J.kind==="stalled"?`session stalled (native turn still running): ${J.message}`:J.kind==="busy"?`session busy (a live worker may own it): ${J.message}`:J.kind==="error"?`session provider error (termination unconfirmed): ${J.message}`:J.kind==="overflow"?"session output exceeded the capture limit; result not trusted":oe?"session process group still alive after wrapper exit":`session wrapper exited without positive completion (code ${W})`;Et(t,n.id,$,O)});try{Hn(t,n.id,{kind:"session",provider:r.provider,model:r.model,teamfile:a,alias:c},x.pid??null)}catch(W){process.stderr.write(`[lmcron] session run ${n.id} state write failed after spawn: ${Xe(W)}
299
+ `)}try{Qo(t,n.id,{kind:"session",phase:"dispatch",teamfile:a,alias:c},x.pid??null)}catch{}};if(r.session_seeded_at!==null){l();return}let d=[...e.spawnPrefixes?.seed??xN,"seed",a],m=d[0],f=d.slice(1),p;try{p=Ml(m,f,{detached:!0,stdio:["ignore","ignore","pipe"],...t.name!==void 0&&t.name!==":memory:"?{env:{...process.env,LMBEE_DB:Wn(t.name)}}:{}})}catch(y){Ge(t,n.id,{fallback:{ok:!1,summary:`session seed spawn error: ${Xe(y)}`}});return}p.unref();let h=Zo(),g=!1,_=!1,E=setTimeout(()=>{g||(g=!0,Ul(p,i),Et(t,n.id,`session seed timed out after ${s}ms; provider initialization may still be running`,{fallback:{ok:!1,summary:`session seed timed out after ${s}ms`}}))},s);E.unref(),p.on("spawn",()=>_=!0),p.stderr?.on("data",y=>es(h,y)),p.on("error",y=>{if(g)return;g=!0,clearTimeout(E);let S={fallback:{ok:!1,summary:`session seed spawn error: ${y.message}`}};_?Et(t,n.id,`session seed post-spawn error: ${y.message}`,S):Ge(t,n.id,S)}),p.on("close",y=>{if(!g){if(g=!0,clearTimeout(E),y!==0){Et(t,n.id,`session seed failed (exit ${y}); provider initialization may still be running`,{fallback:{ok:!1,summary:`session seed failed (exit ${y}): ${h.text.trim().slice(-300)}`}});return}try{t.prepare("UPDATE cron_jobs SET session_seeded_at = ?, updated_at = ? WHERE id = ?").run(new Date().toISOString(),new Date().toISOString(),r.id)}catch(S){Et(t,n.id,`session seeded but recording identity failed: ${Xe(S)}`,{fallback:{ok:!1,summary:"session seeded but recording seed state failed; will recover on retry"}});return}l()}});try{Qo(t,n.id,{kind:"session",phase:"seed",teamfile:a,alias:c},p.pid??null)}catch{}}function Bl(e){try{switch(e.job.action_kind){case"script":JN(e);return;case"miniplayer":zN(e);return;case"session":YN(e);return;default:Ge(e.db,e.run.id,{fallback:{ok:!1,summary:`unsupported run worker kind: ${e.job.action_kind}`}})}}catch(t){Et(e.db,e.run.id,`unexpected worker dispatch failure: ${Xe(t)}`,{fallback:{ok:!1,summary:`worker dispatch error: ${Xe(t)}`}})}}function QN(e){return e==="enqueue"||e==="command"||e==="script"||e==="session"||e==="miniplayer"}function XN(e){return e==="script"||e==="session"||e==="miniplayer"}function bt(e){return e instanceof Error?e.message:String(e)}function Gn(e){let t=e&&typeof e=="object"&&"code"in e?String(e.code):void 0;if(t!==void 0&&(t.startsWith("SQLITE_BUSY")||t.startsWith("SQLITE_LOCKED")))throw new P("DB_BUSY","Database busy; retry after the current writer completes",5);let r=e instanceof Error?e.message:String(e);throw t!==void 0&&t.startsWith("SQLITE_CONSTRAINT")?new P("STRUCTURAL_ERROR",r,2):new P("STORAGE_ERROR",r,1)}function pr(e){try{return e()}catch(t){if(t instanceof P)throw t;if(t instanceof L)throw new P(t.code,t.message,t.exitCode);return Gn(t)}}function Gi(e,t){e.prepare("UPDATE cron_jobs SET revision = revision + 1, updated_at = ? WHERE id = ?").run(de(),t)}function Vi(e,t){return pr(()=>e.prepare("SELECT * FROM cron_jobs WHERE id = ?").get(t)??null)}function Le(e,t){let r=Vi(e,t);if(r===null)throw new P("NOT_FOUND",`Cron job ${t} does not exist`,3);return r}function ZN(e){let t;try{t=JSON.parse(e)}catch{throw new P("INVALID_ARGUMENT","enqueue action_payload must be valid JSON")}if(typeof t!="object"||t===null)throw new P("INVALID_ARGUMENT","enqueue action_payload must be a JSON object");let{to:r,prompt:n,from:o}=t;if(typeof r!="string"||r.trim().length===0)throw new P("INVALID_ARGUMENT",'enqueue action_payload requires a nonblank "to"');if(typeof n!="string"||n.trim().length===0)throw new P("INVALID_ARGUMENT",'enqueue action_payload requires a nonblank "prompt"');if(o!==void 0&&(typeof o!="string"||o.trim().length===0))throw new P("INVALID_ARGUMENT",'enqueue action_payload "from", if given, must be a nonblank string')}function Gh(e,t){Ee(t,"action_payload"),e==="enqueue"&&ZN(t)}function Vh(e){let{actionKind:t}=e;if(t==="session"){if(e.provider===void 0||e.provider===null||e.provider.trim().length===0)throw new P("INVALID_ARGUMENT","a session job requires a nonblank provider");if(Fl(e.provider),e.workingDirectory===void 0||e.workingDirectory===null||e.workingDirectory.trim().length===0)throw new P("INVALID_ARGUMENT","a session job requires an absolute working_directory (--cwd)");Wi(e.workingDirectory)}else if(e.provider!==void 0&&e.provider!==null&&e.provider.trim().length>0)throw new P("INVALID_ARGUMENT",`provider is only valid for session jobs (not ${t})`);if(e.model!==void 0&&e.model!==null&&e.model.trim().length===0)throw new P("INVALID_ARGUMENT","model, if given, must be nonblank");if(e.model!==void 0&&e.model!==null&&e.model.trim().length>0&&t!=="session"&&t!=="miniplayer")throw new P("INVALID_ARGUMENT",`model is only valid for session/miniplayer jobs (not ${t})`);if(e.model!==void 0&&e.model!==null&&e.model.trim().length>0&&ql(e.model),e.workingDirectory!==void 0&&e.workingDirectory!==null&&e.workingDirectory.trim().length>0&&t==="enqueue")throw new P("INVALID_ARGUMENT","working_directory is not valid for enqueue jobs");if(e.workingDirectory!==void 0&&e.workingDirectory!==null&&e.workingDirectory.trim().length===0)throw new P("INVALID_ARGUMENT","working_directory, if given, must be nonblank");if(e.escalationOwner!==void 0&&e.escalationOwner!==null&&e.escalationOwner.trim().length===0)throw new P("INVALID_ARGUMENT","escalation_owner, if given, must be nonblank")}function Jh(e){let t=Ee(e,"timezone");try{new Intl.DateTimeFormat(void 0,{timeZone:t})}catch{throw new P("INVALID_ARGUMENT",`timezone "${t}" is not a recognized IANA zone name`)}return t}function zh(e){let t=Nl(e);if(!t.ok){let r=t.error.field?` (field: ${t.error.field})`:"";throw new P("INVALID_SCHEDULE",`${t.error.message}${r}`)}}function Vn(e,t){let r=e.transaction(()=>{if(t.id!==void 0&&(!Number.isSafeInteger(t.id)||t.id<1))throw new P("INVALID_ARGUMENT","id, if given, must be a positive safe integer");let n=Ee(t.title,"title");if(!QN(t.actionKind))throw new P("INVALID_ARGUMENT",'action_kind must be "enqueue", "command", "script", "session", or "miniplayer"');zh(t.scheduleExpr),Gh(t.actionKind,t.actionPayload),Vh({actionKind:t.actionKind,provider:t.provider??null,model:t.model??null,workingDirectory:t.workingDirectory??null,escalationOwner:t.escalationOwner??null});let o=t.timezone!==void 0?Jh(t.timezone):null,s=de();try{let i=e.prepare(t.id!==void 0?`INSERT INTO cron_jobs(id, title, schedule_expr, action_kind, action_payload, provider, model,
300
300
  working_directory, escalation_owner, enabled, timezone, created_at, updated_at)
301
301
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`:`INSERT INTO cron_jobs(title, schedule_expr, action_kind, action_payload, provider, model,
302
302
  working_directory, escalation_owner, enabled, timezone, created_at, updated_at)
303
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(...t.id!==void 0?[t.id]:[],n,t.scheduleExpr,t.actionKind,t.actionPayload,t.provider??null,t.model??null,t.workingDirectory??null,t.escalationOwner??null,t.enabled===!1?0:1,o,s,s);return Le(e,Number(i.lastInsertRowid))}catch(i){Gn(i)}});return pr(r)}function Ji(e,t){if(!Number.isSafeInteger(t.limit)||t.limit<1||t.limit>Ie)throw new U("INVALID_ARGUMENT",`limit must be a positive integer <= ${Ie}`);return pr(()=>{let r=["id > ?"],n=[t.after];t.enabled!==void 0&&(r.push("enabled = ?"),n.push(t.enabled?1:0));let o=e.prepare(`SELECT * FROM cron_jobs WHERE ${r.join(" AND ")} ORDER BY id LIMIT ?`).all(...n,t.limit+1),s=o.length>t.limit,i=s?o.slice(0,t.limit):o;return{rows:i,meta:{next_cursor:s?i[i.length-1].id:null}}})}function Yh(e,t,r){let n=e.transaction(()=>{let o=Le(e,t);if(r.ifRevision!==void 0&&o.revision!==r.ifRevision)throw new U("REVISION_CONFLICT",`Expected revision ${r.ifRevision}; current is ${o.revision}`,4);let s={};if(r.title!==void 0&&(s.title=Ee(r.title,"title")),r.scheduleExpr!==void 0&&(zh(r.scheduleExpr),s.schedule_expr=r.scheduleExpr),r.actionPayload!==void 0&&(Gh(o.action_kind,r.actionPayload),s.action_payload=r.actionPayload),r.timezone!==void 0&&(s.timezone=r.timezone===null?null:Jh(r.timezone)),o.session_teamfile!==null&&(r.provider!==void 0&&r.provider!==o.provider||r.model!==void 0&&r.model!==o.model||r.workingDirectory!==void 0&&r.workingDirectory!==o.working_directory))throw new U("SESSION_IMMUTABLE","provider/model/cwd cannot change while a session is seeded; run `cron reset-session` first",2);if(r.provider!==void 0&&(s.provider=r.provider),r.model!==void 0&&(s.model=r.model),(r.provider!==void 0||r.model!==void 0)&&Vh({actionKind:o.action_kind,provider:r.provider??o.provider,model:r.model??o.model,workingDirectory:r.workingDirectory!==void 0?r.workingDirectory:o.working_directory}),r.workingDirectory!==void 0){if(o.action_kind==="enqueue")throw new U("INVALID_ARGUMENT","working_directory is not valid for enqueue jobs");if(r.workingDirectory===null){if(o.action_kind==="session")throw new U("INVALID_ARGUMENT","a session job requires an absolute working_directory");s.working_directory=null}else{let i=Ee(r.workingDirectory,"working_directory");o.action_kind==="session"&&Wi(i),s.working_directory=i}}if(r.escalationOwner!==void 0&&(s.escalation_owner=r.escalationOwner===null?null:Ee(r.escalationOwner,"escalation_owner")),Object.keys(s).length===0)throw new U("INVALID_ARGUMENT","Update requires at least one field");try{e.prepare(`UPDATE cron_jobs SET ${Object.keys(s).map(i=>`${i} = ?`).join(",")} WHERE id = ?`).run(...Object.values(s),t)}catch(i){Gn(i)}return Gi(e,t),Le(e,t)});return pr(n)}function zi(e,t,r){let n=e.transaction(()=>{Le(e,t);try{e.prepare("UPDATE cron_jobs SET enabled = ? WHERE id = ?").run(r?1:0,t)}catch(o){Gn(o)}return Gi(e,t),Le(e,t)});return pr(n)}function Kh(e,t){let r=e.transaction(()=>{let n=Le(e,t);if(fr(e,t)!==null)throw new U("EXECUTION_FENCED",`Cron job ${t} has a fenced execution or unresolved escalation; resolve it before removing the job`,4);try{e.prepare("DELETE FROM cron_jobs WHERE id = ?").run(t)}catch(o){Gn(o)}return n});return pr(r)}function Qh(e,t){let r=e.transaction(()=>{if(Le(e,t).action_kind!=="session")throw new U("INVALID_ARGUMENT",`Cron job ${t} is not a session job`);if(fr(e,t)!==null)throw new U("SESSION_ACTIVE",`Cron job ${t} has an active run; resolve it before resetting the session`,4);return e.prepare(`UPDATE cron_jobs SET session_teamfile = NULL, session_seeded_at = NULL, session_alias = NULL,
303
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(...t.id!==void 0?[t.id]:[],n,t.scheduleExpr,t.actionKind,t.actionPayload,t.provider??null,t.model??null,t.workingDirectory??null,t.escalationOwner??null,t.enabled===!1?0:1,o,s,s);return Le(e,Number(i.lastInsertRowid))}catch(i){Gn(i)}});return pr(()=>r.immediate())}function Ji(e,t){if(!Number.isSafeInteger(t.limit)||t.limit<1||t.limit>Ie)throw new P("INVALID_ARGUMENT",`limit must be a positive integer <= ${Ie}`);return pr(()=>{let r=["id > ?"],n=[t.after];t.enabled!==void 0&&(r.push("enabled = ?"),n.push(t.enabled?1:0));let o=e.prepare(`SELECT * FROM cron_jobs WHERE ${r.join(" AND ")} ORDER BY id LIMIT ?`).all(...n,t.limit+1),s=o.length>t.limit,i=s?o.slice(0,t.limit):o;return{rows:i,meta:{next_cursor:s?i[i.length-1].id:null}}})}function Yh(e,t,r){let n=e.transaction(()=>{let o=Le(e,t);if(r.ifRevision!==void 0&&o.revision!==r.ifRevision)throw new P("REVISION_CONFLICT",`Expected revision ${r.ifRevision}; current is ${o.revision}`,4);let s={};if(r.title!==void 0&&(s.title=Ee(r.title,"title")),r.scheduleExpr!==void 0&&(zh(r.scheduleExpr),s.schedule_expr=r.scheduleExpr),r.actionPayload!==void 0&&(Gh(o.action_kind,r.actionPayload),s.action_payload=r.actionPayload),r.timezone!==void 0&&(s.timezone=r.timezone===null?null:Jh(r.timezone)),o.session_teamfile!==null&&(r.provider!==void 0&&r.provider!==o.provider||r.model!==void 0&&r.model!==o.model||r.workingDirectory!==void 0&&r.workingDirectory!==o.working_directory))throw new P("SESSION_IMMUTABLE","provider/model/cwd cannot change while a session is seeded; run `cron reset-session` first",2);if(r.provider!==void 0&&(s.provider=r.provider),r.model!==void 0&&(s.model=r.model),(r.provider!==void 0||r.model!==void 0)&&Vh({actionKind:o.action_kind,provider:r.provider??o.provider,model:r.model??o.model,workingDirectory:r.workingDirectory!==void 0?r.workingDirectory:o.working_directory}),r.workingDirectory!==void 0){if(o.action_kind==="enqueue")throw new P("INVALID_ARGUMENT","working_directory is not valid for enqueue jobs");if(r.workingDirectory===null){if(o.action_kind==="session")throw new P("INVALID_ARGUMENT","a session job requires an absolute working_directory");s.working_directory=null}else{let i=Ee(r.workingDirectory,"working_directory");o.action_kind==="session"&&Wi(i),s.working_directory=i}}if(r.escalationOwner!==void 0&&(s.escalation_owner=r.escalationOwner===null?null:Ee(r.escalationOwner,"escalation_owner")),Object.keys(s).length===0)throw new P("INVALID_ARGUMENT","Update requires at least one field");try{e.prepare(`UPDATE cron_jobs SET ${Object.keys(s).map(i=>`${i} = ?`).join(",")} WHERE id = ?`).run(...Object.values(s),t)}catch(i){Gn(i)}return Gi(e,t),Le(e,t)});return pr(n)}function zi(e,t,r){let n=e.transaction(()=>{Le(e,t);try{e.prepare("UPDATE cron_jobs SET enabled = ? WHERE id = ?").run(r?1:0,t)}catch(o){Gn(o)}return Gi(e,t),Le(e,t)});return pr(()=>n.immediate())}function Kh(e,t){let r=e.transaction(()=>{let n=Le(e,t);if(fr(e,t)!==null)throw new P("EXECUTION_FENCED",`Cron job ${t} has a fenced execution or unresolved escalation; resolve it before removing the job`,4);try{e.prepare("DELETE FROM cron_jobs WHERE id = ?").run(t)}catch(o){Gn(o)}return n});return pr(r)}function Qh(e,t){let r=e.transaction(()=>{if(Le(e,t).action_kind!=="session")throw new P("INVALID_ARGUMENT",`Cron job ${t} is not a session job`);if(fr(e,t)!==null)throw new P("SESSION_ACTIVE",`Cron job ${t} has an active run; resolve it before resetting the session`,4);return e.prepare(`UPDATE cron_jobs SET session_teamfile = NULL, session_seeded_at = NULL, session_alias = NULL,
304
304
  session_generation = session_generation + 1 WHERE id = ?`).run(t),Gi(e,t),Le(e,t)});return pr(r)}var e0=24*60*60*1e3;function Xh(e,t=KN){try{return t("systemctl",["--user","is-active","--quiet",e]),"active"}catch(r){return r.status===3?"confirmed-gone":"unknown"}}async function Zh(e,t,r,n={}){let o=n.enqueueImpl??we,s=n.spawnCommandImpl??Go,i=n.isUnitStillRunningImpl??Xh,a=new Date(r).toISOString(),c=[],l=pr(()=>e.prepare("SELECT * FROM cron_jobs WHERE enabled = 1 ORDER BY id").all());for(let u of l)try{o0(e,u,t,r,a,o,s,i,n.logDir,c,n.onJobError,{...n.runSpawnPrefixes!==void 0?{runSpawnPrefixes:n.runSpawnPrefixes}:{},...n.sessionDir!==void 0?{sessionDir:n.sessionDir}:{},...n.runTimeoutMs!==void 0?{runTimeoutMs:n.runTimeoutMs}:{},...n.runSeedTimeoutMs!==void 0?{runSeedTimeoutMs:n.runSeedTimeoutMs}:{},executeRunImpl:n.executeRunImpl??Bl})}catch(d){try{n.onJobError?.(u.id,d)}catch{}try{Or(e,"UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, updated_at = ?",["error",bt(d),a],u)}catch{}}return c}function Bh(e,t){let r=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}).formatToParts(e),n=o=>Number(r.find(s=>s.type===o).value);return new Date(n("year"),n("month")-1,n("day"),n("hour"),n("minute"),n("second"))}var t0=500;function r0(e){return JSON.stringify({kind:"command",payload:e.action_payload,provider:e.provider,model:e.model,workingDirectory:e.working_directory,escalationOwner:e.escalation_owner})}function n0(e){if(e.execution_identity===null)return null;try{let t=JSON.parse(e.execution_identity);return typeof t.systemdUnit=="string"?t.systemdUnit:null}catch{return null}}function Wl(e,t,r){let n=fr(e,t);if(n!==null)try{Bn(e,n.id,{fallback:{ok:!1,summary:r}})}catch{}}function eg(e,t,r,n,o){try{let s=r0(t),i=Ko(e,t.id,r,s);if(i.kind!=="claimed"){let a=n0(i.run);a!==null&&o(a)==="confirmed-gone"&&(Wl(e,t.id,"reconciled: previous command execution confirmed gone before a new fire"),i=Ko(e,t.id,r,s))}return i.kind!=="claimed"?null:(Hn(e,i.run.id,{kind:"command",systemdUnit:n},null),i.run.id)}catch{return null}}function tg(e,t,r,n,o,s,i){if(t!==null)try{if(o!==null)try{Qo(e,t,{kind:"command",systemdUnit:i},o)}catch{}let a=Hl(s,t0),c=n?`command spawn error: ${n.message}`:`command exited with code ${r}${a?`: ${a}`:""}`;Bn(e,t,{fallback:{ok:n===void 0&&r===0,summary:c}})}catch{}}function rg(e,t,r){if(t!==null)try{Bn(e,t,{fallback:{ok:!1,summary:`command spawn failed: ${bt(r)}`}})}catch{}}function o0(e,t,r,n,o,s,i,a,c,l,u,d){let m=Nl(t.schedule_expr);if(!m.ok){Or(e,"UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, updated_at = ?",["error",`Unparseable schedule_expr: ${m.error.message}`,o],t);return}let f=m.schedule;if(t.action_kind==="command"&&t.running_since_ts!==null){if(t.running_systemd_unit!==null&&a(t.running_systemd_unit)==="confirmed-gone"){e.prepare(`UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?,
305
305
  last_fire_error = NULL, updated_at = ?
306
306
  WHERE id = ? AND enabled = 1 AND revision = ? AND running_since_ts = ? AND running_systemd_unit = ?`).run("reconciled",o,t.id,t.revision,t.running_since_ts,t.running_systemd_unit),Wl(e,t.id,"reconciled: command execution confirmed gone by systemd probe; no exit callback survived the restart");return}e.prepare("UPDATE cron_jobs SET last_fire_status = ?, updated_at = ? WHERE id = ? AND enabled = 1 AND revision = ? AND running_since_ts = ?").run("skipped_overlap",o,t.id,t.revision,t.running_since_ts);return}let p=t.last_checked_ts!==null?Date.parse(t.last_checked_ts):Date.parse(t.created_at);if(p>n){Or(e,"UPDATE cron_jobs SET last_checked_ts = ?, last_fire_status = ?, last_fire_error = ?, updated_at = ?",[o,"error",`last_checked_ts (${t.last_checked_ts??t.created_at}) is after the current tick time -- checkpoint reset without firing`,o],t);return}let h=new Date(p),g=new Date(n);if(n-p>e0){Or(e,"UPDATE cron_jobs SET last_checked_ts = ?, last_fire_status = ?, updated_at = ?",[o,"skipped_stale",o],t);return}let _=t.timezone!==null?Bh(h,t.timezone):h,E=t.timezone!==null?Bh(g,t.timezone):g;if(!Ah(f,_,E)){Or(e,"UPDATE cron_jobs SET last_checked_ts = ?, updated_at = ?",[o,o],t);return}let S=Vi(e,t.id);if(!(S===null||S.enabled===0||S.revision!==t.revision)){if(XN(t.action_kind)){s0(e,t,o,l,u,d);return}if(t.action_kind==="enqueue")try{let T=JSON.parse(t.action_payload),R={from:T.from??"autopilot",dedupeKey:`cron:${t.id}:${h.toISOString()}`};e.transaction(()=>{let I=e.prepare("SELECT enabled, revision, last_checked_ts FROM cron_jobs WHERE id = ?").get(t.id);return I===void 0||I.enabled===0||I.revision!==t.revision||I.last_checked_ts!==t.last_checked_ts?!1:(s(e,r,T.to,T.prompt,R),e.prepare("UPDATE cron_jobs SET last_checked_ts = ?, last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?").run(o,o,"ok",o,t.id),!0)}).immediate()&&l.push(t.title)}catch(T){try{u?.(t.id,T)}catch{}try{Or(e,"UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, updated_at = ?",["error",bt(T),o],t)}catch{}}else{let T=o,R=`lmcron-job-${t.id}-${T.replace(/[:.]/g,"-")}.scope`;if(e.prepare(`UPDATE cron_jobs SET last_checked_ts = ?, last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, running_since_ts = ?, running_systemd_unit = ?, updated_at = ?
307
- WHERE id = ? AND enabled = 1 AND revision = ? AND (last_checked_ts IS ?) AND (running_since_ts IS ?)`).run(o,o,"ok",o,R,o,t.id,t.revision,t.last_checked_ts,t.running_since_ts).changes===0)return;let I=eg(e,t,t.action_kind,R,a),x={logDir:c,systemdUnitName:R,onExit:(H,C,w,b)=>{let N=H===0?"ok":"error",P=N==="ok"?null:C?bt(C):`Command exited with code ${H} -- see ${c??qi()}/${t.id}/ for output`;if(C)try{u?.(t.id,C)}catch{}try{e.prepare("UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?, last_fire_error = ?, updated_at = ? WHERE id = ? AND running_since_ts = ?").run(N,P,new Date().toISOString(),t.id,T)}catch{}tg(e,I,H,C,w,b,R)}};try{i({id:t.id,action_payload:t.action_payload},x),l.push(t.title)}catch(H){try{u?.(t.id,H)}catch{}try{e.prepare("UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, running_since_ts = NULL, running_systemd_unit = NULL, updated_at = ? WHERE id = ? AND running_since_ts = ?").run("error",bt(H),o,t.id,T)}catch{}rg(e,I,H)}}}}async function Wh(e,t){for(;!e();)await new Promise(r=>setTimeout(r,t))}async function rs(e,t,r,n={}){let o=n.enqueueImpl??we,s=n.spawnCommandImpl??Go,i=n.isUnitStillRunningImpl??Xh,a=n.executeRunImpl??Bl,c=n.logDir,l=n.pollMs??250,u=Le(e,t);if(u.enabled===0)throw new U("DISABLED",`Cron job ${t} is disabled -- enable it first (\`cron enable ${t}\`), or a manual trigger would silently exercise a job the operator turned off on purpose`,4);let d=de();if(u.action_kind==="command"){if(u.running_since_ts!==null)return u.running_systemd_unit!==null&&i(u.running_systemd_unit)==="confirmed-gone"?(e.prepare(`UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?, last_fire_error = NULL, updated_at = ?
307
+ WHERE id = ? AND enabled = 1 AND revision = ? AND (last_checked_ts IS ?) AND (running_since_ts IS ?)`).run(o,o,"ok",o,R,o,t.id,t.revision,t.last_checked_ts,t.running_since_ts).changes===0)return;let I=eg(e,t,t.action_kind,R,a),x={logDir:c,systemdUnitName:R,onExit:(H,C,w,b)=>{let N=H===0?"ok":"error",M=N==="ok"?null:C?bt(C):`Command exited with code ${H} -- see ${c??qi()}/${t.id}/ for output`;if(C)try{u?.(t.id,C)}catch{}try{e.prepare("UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?, last_fire_error = ?, updated_at = ? WHERE id = ? AND running_since_ts = ?").run(N,M,new Date().toISOString(),t.id,T)}catch{}tg(e,I,H,C,w,b,R)}};try{i({id:t.id,action_payload:t.action_payload},x),l.push(t.title)}catch(H){try{u?.(t.id,H)}catch{}try{e.prepare("UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, running_since_ts = NULL, running_systemd_unit = NULL, updated_at = ? WHERE id = ? AND running_since_ts = ?").run("error",bt(H),o,t.id,T)}catch{}rg(e,I,H)}}}}async function Wh(e,t){for(;!e();)await new Promise(r=>setTimeout(r,t))}async function rs(e,t,r,n={}){let o=n.enqueueImpl??we,s=n.spawnCommandImpl??Go,i=n.isUnitStillRunningImpl??Xh,a=n.executeRunImpl??Bl,c=n.logDir,l=n.pollMs??250,u=Le(e,t);if(u.enabled===0)throw new P("DISABLED",`Cron job ${t} is disabled -- enable it first (\`cron enable ${t}\`), or a manual trigger would silently exercise a job the operator turned off on purpose`,4);let d=de();if(u.action_kind==="command"){if(u.running_since_ts!==null)return u.running_systemd_unit!==null&&i(u.running_systemd_unit)==="confirmed-gone"?(e.prepare(`UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?, last_fire_error = NULL, updated_at = ?
308
308
  WHERE id = ? AND revision = ? AND running_since_ts = ? AND running_systemd_unit = ?`).run("reconciled",d,u.id,u.revision,u.running_since_ts,u.running_systemd_unit),Wl(e,u.id,"reconciled: command execution confirmed gone by systemd probe; no exit callback survived the restart"),await rs(e,t,r,n)):{kind:"skipped_overlap",job:u};let p=d,h=`lmcron-job-${u.id}-${p.replace(/[:.]/g,"-")}-manual.scope`;if(e.prepare(`UPDATE cron_jobs SET last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, running_since_ts = ?, running_systemd_unit = ?, updated_at = ?
309
- WHERE id = ? AND enabled = 1 AND revision = ? AND running_since_ts IS ?`).run(d,"ok",p,h,d,u.id,u.revision,u.running_since_ts).changes===0)return{kind:"skipped_overlap",job:Le(e,t)};let _=eg(e,u,`${u.action_kind}:manual`,h,i),E={logDir:c,systemdUnitName:h,onExit:(y,S,T,R)=>{let A=y===0?"ok":"error",I=A==="ok"?null:S?bt(S):`Command exited with code ${y} -- see ${c??qi()}/${u.id}/ for output`;try{e.prepare("UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?, last_fire_error = ?, updated_at = ? WHERE id = ? AND running_since_ts = ?").run(A,I,new Date().toISOString(),u.id,p)}catch{}tg(e,_,y,S,T,R,h)}};try{s({id:u.id,action_payload:u.action_payload},E)}catch(y){rg(e,_,y);try{e.prepare("UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, running_since_ts = NULL, running_systemd_unit = NULL, updated_at = ? WHERE id = ? AND running_since_ts = ?").run("error",bt(y),d,u.id,p)}catch{}throw new U("SPAWN_FAILED",`manual trigger of job ${t} failed to spawn: ${bt(y)}`,1)}return await Wh(()=>Le(e,t).running_since_ts!==p,l),{kind:"fired",job:Le(e,t)}}if(u.action_kind==="enqueue"){let p=JSON.parse(u.action_payload);return o(e,r,p.to,p.prompt,{from:p.from??"autopilot"}),e.prepare("UPDATE cron_jobs SET last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?").run(d,"ok",d,u.id),{kind:"fired",job:Le(e,t)}}let m=JSON.stringify({kind:u.action_kind,payload:u.action_payload,provider:u.provider,model:u.model,workingDirectory:u.working_directory,escalationOwner:u.escalation_owner}),f=e.transaction(()=>{let p=e.prepare("SELECT enabled, revision FROM cron_jobs WHERE id = ?").get(u.id);if(p===void 0||p.enabled===0||p.revision!==u.revision)return null;let h=Ko(e,u.id,`${u.action_kind}:manual`,m);return h.kind==="claimed"&&e.prepare("UPDATE cron_jobs SET last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?").run(d,"ok",d,u.id),h}).immediate();if(f===null)throw new U("CONFLICT",`Cron job ${t} was modified concurrently -- re-run \`cron trigger ${t}\``,5);if(f.kind==="escalation")return{kind:"blocked_escalation",job:Le(e,t)};if(f.kind==="overlap")return{kind:"skipped_overlap",job:Le(e,t)};try{a({db:e,job:u,run:f.run,runToken:f.token,...n.runSpawnPrefixes!==void 0?{spawnPrefixes:n.runSpawnPrefixes}:{},...n.sessionDir!==void 0?{sessionDir:n.sessionDir}:{},...n.runTimeoutMs!==void 0?{timeoutMs:n.runTimeoutMs}:{},...n.runSeedTimeoutMs!==void 0?{seedTimeoutMs:n.runSeedTimeoutMs}:{}})}catch(p){try{Xo(e,f.run.id,`worker dispatch threw: ${bt(p)}`),Dl(e,f.run.id,{ok:!1,summary:`worker dispatch error: ${bt(p)}`})}catch{}throw new U("SPAWN_FAILED",`manual trigger of job ${t} failed to dispatch: ${bt(p)}`,1)}return n.waitForCompletion===!1?{kind:"fired",job:Le(e,t),runId:f.run.id}:(await Wh(()=>{let p=Qe(e,f.run.id);return p.status!=="pending"&&p.status!=="running"},l),{kind:"fired",job:Le(e,t),runId:f.run.id})}function s0(e,t,r,n,o,s){let i=JSON.stringify({kind:t.action_kind,payload:t.action_payload,provider:t.provider,model:t.model,workingDirectory:t.working_directory,escalationOwner:t.escalation_owner}),a=e.transaction(()=>{let c=e.prepare("SELECT enabled, revision, last_checked_ts FROM cron_jobs WHERE id = ?").get(t.id);if(c===void 0||c.enabled===0||c.revision!==t.revision||c.last_checked_ts!==t.last_checked_ts)return null;let l=Ko(e,t.id,t.action_kind,i);return l.kind==="claimed"&&e.prepare("UPDATE cron_jobs SET last_checked_ts = ?, last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?").run(r,r,"ok",r,t.id),l}).immediate();if(a!==null){if(a.kind==="escalation"){Or(e,"UPDATE cron_jobs SET last_fire_status = ?, updated_at = ?",["blocked_escalation",r],t);return}if(a.kind==="overlap"){Or(e,"UPDATE cron_jobs SET last_fire_status = ?, updated_at = ?",["skipped_overlap",r],t);return}n.push(t.title);try{s.executeRunImpl({db:e,job:t,run:a.run,runToken:a.token,...s.runSpawnPrefixes!==void 0?{spawnPrefixes:s.runSpawnPrefixes}:{},...s.sessionDir!==void 0?{sessionDir:s.sessionDir}:{},...s.runTimeoutMs!==void 0?{timeoutMs:s.runTimeoutMs}:{},...s.runSeedTimeoutMs!==void 0?{seedTimeoutMs:s.runSeedTimeoutMs}:{}})}catch(c){try{Xo(e,a.run.id,`worker dispatch threw: ${bt(c)}`),Dl(e,a.run.id,{ok:!1,summary:`worker dispatch error: ${bt(c)}`})}catch{}try{o?.(t.id,c)}catch{}}}}function Or(e,t,r,n){e.prepare(`${t} WHERE id = ? AND enabled = 1 AND revision = ? AND (last_checked_ts IS ?)`).run(...r,n.id,n.revision,n.last_checked_ts)}function ng(e,t){let r=e.transaction(()=>{Le(e,t);try{e.prepare("UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL WHERE id = ?").run(t)}catch(n){Gn(n)}return Gi(e,t),Le(e,t)});return pr(r)}import{execFileSync as i0}from"node:child_process";import{existsSync as a0,readFileSync as og}from"node:fs";import{homedir as sg}from"node:os";import{join as ig}from"node:path";function zn(){return process.env.LMBEE_HEAVY_STATUS??ig(sg(),".lmbee","heavy.status")}function Yn(){return process.env.LMBEE_HEAVY_LOCK??ig(sg(),".lmbee","heavy.lock")}var Jn=class extends Error{};function c0(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.holder=="string"&&typeof t.pid=="number"&&typeof t.command=="string"&&typeof t.startedAt=="string"}function l0(e){let t;try{t=og(e,"utf8")}catch{return null}try{let r=JSON.parse(t);return c0(r)?r:null}catch{return null}}function u0(e,t){return e===null||t===null?e===t:e.holder===t.holder&&e.pid===t.pid&&e.command===t.command&&e.startedAt===t.startedAt}function d0(e){try{let t=og(`/proc/${e}/stat`,"utf8");return t.slice(t.lastIndexOf(")")+2).trim().split(/\s+/)[0]==="Z"}catch{return!1}}function m0(e){try{process.kill(e,0)}catch(t){return t.code==="EPERM"}return!d0(e)}function f0(e,t=i0){if(!a0(e))return!1;try{return t("flock",["-n",e,"-c","true"],{stdio:"ignore"}),!1}catch(r){if((r&&typeof r=="object"?r.status:void 0)===1)return!0;let o=r instanceof Error?r.message:String(r);throw new Jn(`heavy-lock probe failed (flock did not run or exited abnormally): ${o}`)}}function Gl(e=zn(),t=Yn(),r=l0,n=f0,o=m0){for(let s=0;s<3;s++){let i=r(e),a=n(t),c=r(e);if(i!==null&&u0(i,c)){if(!a)return{held:!1,holder:null};if(o(i.pid))return{held:!0,holder:i}}}return{held:n(t),holder:null}}function dt(e=zn(),t=Yn(),r=Gl,n){try{return r(e,t)}catch(o){if(!(o instanceof Jn))throw o;return n?.(o),{held:!0,holder:null}}}var Yi={observedAt:null,report:null,lastErrorAt:null,lastError:null};function ag(e,t){Yi={observedAt:t,report:e,lastErrorAt:null,lastError:null}}function cg(e,t){Yi={...Yi,lastErrorAt:t,lastError:e}}function ns(){return Yi}import{execFile as p0}from"node:child_process";import{promisify as h0}from"node:util";function me(e){if(!Number.isFinite(e)||e<0)return"?";if(e<1e3)return"0s";if(e<6e4)return`${Math.floor(e/1e3)}s`;if(e<36e5)return`${Math.floor(e/6e4)}m`;if(e<864e5*2)return`${Math.floor(e/36e5)}h`;let t=Math.floor(e/864e5),r=Math.floor(e%864e5/36e5);return r===0?`${t}d`:`${t}d ${r}h`}function he(e,t=Date.now()){let r=Date.parse(e);if(Number.isNaN(r))return"?";let n=t-r;return n<6e4?"just now":`${me(n)} ago`}var g0=h0(p0);function _0(e){if(typeof e!="object"||e===null||Array.isArray(e))return!1;let t=e;return(typeof t.target=="string"||t.target===null)&&typeof t.from_identity=="string"}function w0(e){let t=JSON.parse(e);if(typeof t!="object"||t===null||!Array.isArray(t.running)||!Array.isArray(t.dead)||!Array.isArray(t.idle))throw new Error("unexpected `lmctl running --json` shape: missing running/dead/idle arrays");let r=t;for(let n of["running","dead","idle"])if(!r[n].every(_0))throw new Error(`unexpected \`lmctl running --json\` shape: a malformed element (bad/missing target or from_identity) in \`${n}\``);return r}async function ke(e=3e4){let{stdout:t}=await g0("lmctl",["running","--json"],{timeout:e});return w0(t)}function Vl(e,t=Date.now()){return{schema_version:e.schema_version,running:e.running.map(r=>({...r,running_for_human:me(r.running_for_ms),started_human:he(r.started_at,t)})),dead:e.dead.map(r=>({...r,stale_for_human:me(r.stale_for_ms),started_human:he(r.started_at,t)})),idle:e.idle.map(r=>({...r,ran_human:me(r.ran_ms)}))}}import{readFileSync as y0}from"node:fs";import{randomUUID as E0}from"node:crypto";var Jl={staleThresholdMs:2*60*6e4,escalationCooldownMs:60*6e4,digestTimeoutMs:9e4,leaseTimeoutMs:10*6e4,providerQuotaBackoffMs:24*60*6e4,operatorStaleThresholdMs:6e4,operatorEscalationCooldownMs:6e4};function b0(e){return/usage limit/i.test(e)&&/quota/i.test(e)}function T0(e){let t=[];for(let r of e)try{t.push({row:r,content:y0(r.prompt_file,"utf8")})}catch{continue}return t}function S0(e){let t=e.map(({row:r,content:n})=>`--- from "${r.from_id}", queued ${r.created_ts} ---
309
+ WHERE id = ? AND enabled = 1 AND revision = ? AND running_since_ts IS ?`).run(d,"ok",p,h,d,u.id,u.revision,u.running_since_ts).changes===0)return{kind:"skipped_overlap",job:Le(e,t)};let _=eg(e,u,`${u.action_kind}:manual`,h,i),E={logDir:c,systemdUnitName:h,onExit:(y,S,T,R)=>{let A=y===0?"ok":"error",I=A==="ok"?null:S?bt(S):`Command exited with code ${y} -- see ${c??qi()}/${u.id}/ for output`;try{e.prepare("UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL, last_fire_status = ?, last_fire_error = ?, updated_at = ? WHERE id = ? AND running_since_ts = ?").run(A,I,new Date().toISOString(),u.id,p)}catch{}tg(e,_,y,S,T,R,h)}};try{s({id:u.id,action_payload:u.action_payload},E)}catch(y){rg(e,_,y);try{e.prepare("UPDATE cron_jobs SET last_fire_status = ?, last_fire_error = ?, running_since_ts = NULL, running_systemd_unit = NULL, updated_at = ? WHERE id = ? AND running_since_ts = ?").run("error",bt(y),d,u.id,p)}catch{}throw new P("SPAWN_FAILED",`manual trigger of job ${t} failed to spawn: ${bt(y)}`,1)}return await Wh(()=>Le(e,t).running_since_ts!==p,l),{kind:"fired",job:Le(e,t)}}if(u.action_kind==="enqueue"){let p=JSON.parse(u.action_payload);return o(e,r,p.to,p.prompt,{from:p.from??"autopilot"}),e.prepare("UPDATE cron_jobs SET last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?").run(d,"ok",d,u.id),{kind:"fired",job:Le(e,t)}}let m=JSON.stringify({kind:u.action_kind,payload:u.action_payload,provider:u.provider,model:u.model,workingDirectory:u.working_directory,escalationOwner:u.escalation_owner}),f=e.transaction(()=>{let p=e.prepare("SELECT enabled, revision FROM cron_jobs WHERE id = ?").get(u.id);if(p===void 0||p.enabled===0||p.revision!==u.revision)return null;let h=Ko(e,u.id,`${u.action_kind}:manual`,m);if(h.kind==="claimed"){let g=n.disableOnClaim?"enabled = 0, ":"";e.prepare(`UPDATE cron_jobs SET ${g}last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?`).run(d,"ok",d,u.id)}return h}).immediate();if(f===null)throw new P("CONFLICT",`Cron job ${t} was modified concurrently -- re-run \`cron trigger ${t}\``,5);if(f.kind==="escalation")return{kind:"blocked_escalation",job:Le(e,t)};if(f.kind==="overlap")return{kind:"skipped_overlap",job:Le(e,t)};try{a({db:e,job:u,run:f.run,runToken:f.token,...n.runSpawnPrefixes!==void 0?{spawnPrefixes:n.runSpawnPrefixes}:{},...n.sessionDir!==void 0?{sessionDir:n.sessionDir}:{},...n.runTimeoutMs!==void 0?{timeoutMs:n.runTimeoutMs}:{},...n.runSeedTimeoutMs!==void 0?{seedTimeoutMs:n.runSeedTimeoutMs}:{}})}catch(p){try{Xo(e,f.run.id,`worker dispatch threw: ${bt(p)}`),Dl(e,f.run.id,{ok:!1,summary:`worker dispatch error: ${bt(p)}`})}catch{}throw new P("SPAWN_FAILED",`manual trigger of job ${t} failed to dispatch: ${bt(p)}`,1)}if(n.waitForCompletion===!1){let p=u;try{p=Le(e,t)}catch(h){console.warn(`[triggerCronJobNow] post-dispatch getCronJob read failed for job ${t}:`,h)}return{kind:"fired",job:p,runId:f.run.id}}return await Wh(()=>{let p=Qe(e,f.run.id);return p.status!=="pending"&&p.status!=="running"},l),{kind:"fired",job:Le(e,t),runId:f.run.id}}function s0(e,t,r,n,o,s){let i=JSON.stringify({kind:t.action_kind,payload:t.action_payload,provider:t.provider,model:t.model,workingDirectory:t.working_directory,escalationOwner:t.escalation_owner}),a=e.transaction(()=>{let c=e.prepare("SELECT enabled, revision, last_checked_ts FROM cron_jobs WHERE id = ?").get(t.id);if(c===void 0||c.enabled===0||c.revision!==t.revision||c.last_checked_ts!==t.last_checked_ts)return null;let l=Ko(e,t.id,t.action_kind,i);return l.kind==="claimed"&&e.prepare("UPDATE cron_jobs SET last_checked_ts = ?, last_fired_ts = ?, last_fire_status = ?, last_fire_error = NULL, updated_at = ? WHERE id = ?").run(r,r,"ok",r,t.id),l}).immediate();if(a!==null){if(a.kind==="escalation"){Or(e,"UPDATE cron_jobs SET last_fire_status = ?, updated_at = ?",["blocked_escalation",r],t);return}if(a.kind==="overlap"){Or(e,"UPDATE cron_jobs SET last_fire_status = ?, updated_at = ?",["skipped_overlap",r],t);return}n.push(t.title);try{s.executeRunImpl({db:e,job:t,run:a.run,runToken:a.token,...s.runSpawnPrefixes!==void 0?{spawnPrefixes:s.runSpawnPrefixes}:{},...s.sessionDir!==void 0?{sessionDir:s.sessionDir}:{},...s.runTimeoutMs!==void 0?{timeoutMs:s.runTimeoutMs}:{},...s.runSeedTimeoutMs!==void 0?{seedTimeoutMs:s.runSeedTimeoutMs}:{}})}catch(c){try{Xo(e,a.run.id,`worker dispatch threw: ${bt(c)}`),Dl(e,a.run.id,{ok:!1,summary:`worker dispatch error: ${bt(c)}`})}catch{}try{o?.(t.id,c)}catch{}}}}function Or(e,t,r,n){e.prepare(`${t} WHERE id = ? AND enabled = 1 AND revision = ? AND (last_checked_ts IS ?)`).run(...r,n.id,n.revision,n.last_checked_ts)}function ng(e,t){let r=e.transaction(()=>{Le(e,t);try{e.prepare("UPDATE cron_jobs SET running_since_ts = NULL, running_systemd_unit = NULL WHERE id = ?").run(t)}catch(n){Gn(n)}return Gi(e,t),Le(e,t)});return pr(r)}import{execFileSync as i0}from"node:child_process";import{existsSync as a0,readFileSync as og}from"node:fs";import{homedir as sg}from"node:os";import{join as ig}from"node:path";function zn(){return process.env.LMBEE_HEAVY_STATUS??ig(sg(),".lmbee","heavy.status")}function Yn(){return process.env.LMBEE_HEAVY_LOCK??ig(sg(),".lmbee","heavy.lock")}var Jn=class extends Error{};function c0(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.holder=="string"&&typeof t.pid=="number"&&typeof t.command=="string"&&typeof t.startedAt=="string"}function l0(e){let t;try{t=og(e,"utf8")}catch{return null}try{let r=JSON.parse(t);return c0(r)?r:null}catch{return null}}function u0(e,t){return e===null||t===null?e===t:e.holder===t.holder&&e.pid===t.pid&&e.command===t.command&&e.startedAt===t.startedAt}function d0(e){try{let t=og(`/proc/${e}/stat`,"utf8");return t.slice(t.lastIndexOf(")")+2).trim().split(/\s+/)[0]==="Z"}catch{return!1}}function m0(e){try{process.kill(e,0)}catch(t){return t.code==="EPERM"}return!d0(e)}function f0(e,t=i0){if(!a0(e))return!1;try{return t("flock",["-n",e,"-c","true"],{stdio:"ignore"}),!1}catch(r){if((r&&typeof r=="object"?r.status:void 0)===1)return!0;let o=r instanceof Error?r.message:String(r);throw new Jn(`heavy-lock probe failed (flock did not run or exited abnormally): ${o}`)}}function Gl(e=zn(),t=Yn(),r=l0,n=f0,o=m0){for(let s=0;s<3;s++){let i=r(e),a=n(t),c=r(e);if(i!==null&&u0(i,c)){if(!a)return{held:!1,holder:null};if(o(i.pid))return{held:!0,holder:i}}}return{held:n(t),holder:null}}function dt(e=zn(),t=Yn(),r=Gl,n){try{return r(e,t)}catch(o){if(!(o instanceof Jn))throw o;return n?.(o),{held:!0,holder:null}}}var Yi={observedAt:null,report:null,lastErrorAt:null,lastError:null};function ag(e,t){Yi={observedAt:t,report:e,lastErrorAt:null,lastError:null}}function cg(e,t){Yi={...Yi,lastErrorAt:t,lastError:e}}function ns(){return Yi}import{execFile as p0}from"node:child_process";import{promisify as h0}from"node:util";function me(e){if(!Number.isFinite(e)||e<0)return"?";if(e<1e3)return"0s";if(e<6e4)return`${Math.floor(e/1e3)}s`;if(e<36e5)return`${Math.floor(e/6e4)}m`;if(e<864e5*2)return`${Math.floor(e/36e5)}h`;let t=Math.floor(e/864e5),r=Math.floor(e%864e5/36e5);return r===0?`${t}d`:`${t}d ${r}h`}function he(e,t=Date.now()){let r=Date.parse(e);if(Number.isNaN(r))return"?";let n=t-r;return n<6e4?"just now":`${me(n)} ago`}var g0=h0(p0);function _0(e){if(typeof e!="object"||e===null||Array.isArray(e))return!1;let t=e;return(typeof t.target=="string"||t.target===null)&&typeof t.from_identity=="string"}function w0(e){let t=JSON.parse(e);if(typeof t!="object"||t===null||!Array.isArray(t.running)||!Array.isArray(t.dead)||!Array.isArray(t.idle))throw new Error("unexpected `lmctl running --json` shape: missing running/dead/idle arrays");let r=t;for(let n of["running","dead","idle"])if(!r[n].every(_0))throw new Error(`unexpected \`lmctl running --json\` shape: a malformed element (bad/missing target or from_identity) in \`${n}\``);return r}async function ke(e=3e4){let{stdout:t}=await g0("lmctl",["running","--json"],{timeout:e});return w0(t)}function Vl(e,t=Date.now()){return{schema_version:e.schema_version,running:e.running.map(r=>({...r,running_for_human:me(r.running_for_ms),started_human:he(r.started_at,t)})),dead:e.dead.map(r=>({...r,stale_for_human:me(r.stale_for_ms),started_human:he(r.started_at,t)})),idle:e.idle.map(r=>({...r,ran_human:me(r.ran_ms)}))}}import{readFileSync as y0}from"node:fs";import{randomUUID as E0}from"node:crypto";var Jl={staleThresholdMs:2*60*6e4,escalationCooldownMs:60*6e4,digestTimeoutMs:9e4,leaseTimeoutMs:10*6e4,providerQuotaBackoffMs:24*60*6e4,operatorStaleThresholdMs:6e4,operatorEscalationCooldownMs:6e4};function b0(e){return/usage limit/i.test(e)&&/quota/i.test(e)}function T0(e){let t=[];for(let r of e)try{t.push({row:r,content:y0(r.prompt_file,"utf8")})}catch{continue}return t}function S0(e){let t=e.map(({row:r,content:n})=>`--- from "${r.from_id}", queued ${r.created_ts} ---
310
310
  ${n}`);return`You have ${e.length} queued message(s) that couldn't be delivered automatically (presence-gated for a while) -- bundled here as a digest:
311
311
 
312
312
  ${t.join(`
@@ -366,7 +366,7 @@ ${t.join(`
366
366
  `)}
367
367
  )`}async function gI(e,t){try{let r=Q(e),{turns:n}=await t(r,e.leadAlias,{lines:6}),o=[...n].reverse().find(s=>s.role==="assistant");return o?{text:o.text,ts:o.ts}:null}catch(r){return process.stderr.write(`[auto-continue] tail check failed for ${e.name} (treating as no reply available): ${r instanceof Error?r.message:String(r)}
368
368
  `),null}}function _I(e,t,r){if(e===null)return!0;let n=Date.parse(e.replace(" ","T"));return Number.isFinite(n)?r-n>=t:!0}async function Wg(e,t,r,n={}){let o=n.config??pe,s=n.nowMs??Date.now(),i=n.fetchTailImpl??Pi,a=na(n.promptsDir),c=n.readHeavyLockStatusImpl??dt;function l(){return c(n.heavyLockStatusPath,n.heavyLockPath,void 0,h=>{process.stderr.write(`[auto-continue] heavy-lock probe failed, treating conservatively as held: ${h.message}
369
- `)})}let u=new Set(n.stalledTeamNames??await On(e,t,r,n.heavyLock??l(),o,s)),d=[];function m(h){let g=qe(e,h.name);if(g===null||g.status==="BLOCKED"||ie(e,h.name)?.confirmed_done_ts||He(e,h.name,{fromAutopilot:!0}).length>0)return!1;let _=l();if(_.held&&(_.holder===null||_.holder.holder===h.name))return!1;try{let E=`${Q(h)}:${h.leadAlias}`;if(ra(r,E,n.providerExhaustionBackoffMs))return!1}catch{}return!0}let f=n.clearAutoNudgeSuspendedImpl??Tm,p=n.recordAutoNudgeSuspendedImpl??bm;for(let h of t)if(!u.has(h.name)){f(e,h.name);continue}for(let h of t){if(!u.has(h.name)||(f(e,h.name),!m(h)))continue;let g=await gI(h,i);if(g!==null&&uI.test(g.text)&&!_I(g.ts,n.standbyStaleMs??dI,s)){p(e,h.name,"standby_reply_active",`last reply matches the standby pattern and is not yet stale: "${g.text.slice(0,200)}"`,new Date(s).toISOString());continue}if(!m(h))continue;let _=n.loadTeamTaskStateImpl??Re,E=n.deriveTaskAwareNudgeImpl??op,y=null;try{y=_(e,Q(h),h.leadAlias)}catch{}let S,T;if(y!==null){let oe=await E(e,y,{backoffMs:o.cooldownMs});if(oe===null||(S=oe.message,T=oe.onSent,!m(h)))continue}else try{S=oa(a,h)}catch{continue}let A=(n.findOwedResponsesImpl??dn)(e,h.name,s);S+=mI(A,h.name);let x=(n.findRecentlyAnsweredForSenderImpl??sa)(e,h.name,fI,s);S+=hI(x);let C=(n.loadAutoNudgeRedirectImpl??$t)(e,h.name),w=C===null?h.name:`${C.companionTeam}:${C.workerAlias}`,b=C===null?h.name:C.companionTeam,N=C===null?h.leadAlias:C.workerAlias,P=C===null?h.repoPath:t.find(oe=>oe.name===b)?.repoPath??h.repoPath,ee=(n.resolveMemberProviderImpl??Gt)({repoPath:P,name:b},N);if(!(ee!==null&&(n.checkProviderDisabledImpl??ot)(e,ee,s).disabled)){if(we(e,t,w,S,{from:"autopilot"}),C!==null){let oe=n.recordRedirectedDispatchImpl??eh;try{await oe(e,h.name,C,h.repoPath,new Date(s).toISOString())}catch(V){process.stderr.write(`[auto-continue] failed to record redirected dispatch for ${h.name}'s redirect to ${C.companionTeam}:${C.workerAlias} (nudge already sent, continuing): ${V instanceof Error?V.message:String(V)}
369
+ `)})}let u=new Set(n.stalledTeamNames??await On(e,t,r,n.heavyLock??l(),o,s)),d=[];function m(h){let g=qe(e,h.name);if(g===null||g.status==="BLOCKED"||ie(e,h.name)?.confirmed_done_ts||He(e,h.name,{fromAutopilot:!0}).length>0)return!1;let _=l();if(_.held&&(_.holder===null||_.holder.holder===h.name))return!1;try{let E=`${Q(h)}:${h.leadAlias}`;if(ra(r,E,n.providerExhaustionBackoffMs))return!1}catch{}return!0}let f=n.clearAutoNudgeSuspendedImpl??Tm,p=n.recordAutoNudgeSuspendedImpl??bm;for(let h of t)if(!u.has(h.name)){f(e,h.name);continue}for(let h of t){if(!u.has(h.name)||(f(e,h.name),!m(h)))continue;let g=await gI(h,i);if(g!==null&&uI.test(g.text)&&!_I(g.ts,n.standbyStaleMs??dI,s)){p(e,h.name,"standby_reply_active",`last reply matches the standby pattern and is not yet stale: "${g.text.slice(0,200)}"`,new Date(s).toISOString());continue}if(!m(h))continue;let _=n.loadTeamTaskStateImpl??Re,E=n.deriveTaskAwareNudgeImpl??op,y=null;try{y=_(e,Q(h),h.leadAlias)}catch{}let S,T;if(y!==null){let oe=await E(e,y,{backoffMs:o.cooldownMs});if(oe===null||(S=oe.message,T=oe.onSent,!m(h)))continue}else try{S=oa(a,h)}catch{continue}let A=(n.findOwedResponsesImpl??dn)(e,h.name,s);S+=mI(A,h.name);let x=(n.findRecentlyAnsweredForSenderImpl??sa)(e,h.name,fI,s);S+=hI(x);let C=(n.loadAutoNudgeRedirectImpl??$t)(e,h.name),w=C===null?h.name:`${C.companionTeam}:${C.workerAlias}`,b=C===null?h.name:C.companionTeam,N=C===null?h.leadAlias:C.workerAlias,M=C===null?h.repoPath:t.find(oe=>oe.name===b)?.repoPath??h.repoPath,ee=(n.resolveMemberProviderImpl??Gt)({repoPath:M,name:b},N);if(!(ee!==null&&(n.checkProviderDisabledImpl??ot)(e,ee,s).disabled)){if(we(e,t,w,S,{from:"autopilot"}),C!==null){let oe=n.recordRedirectedDispatchImpl??eh;try{await oe(e,h.name,C,h.repoPath,new Date(s).toISOString())}catch(J){process.stderr.write(`[auto-continue] failed to record redirected dispatch for ${h.name}'s redirect to ${C.companionTeam}:${C.workerAlias} (nudge already sent, continuing): ${J instanceof Error?J.message:String(J)}
370
370
  `)}}try{T?.()}catch(oe){process.stderr.write(`[auto-continue] onSent bookkeeping failed for ${h.name} (nudge already sent, continuing): ${oe instanceof Error?oe.message:String(oe)}
371
371
  `)}Mo(e,h.name,new Date().toISOString()),d.push(h.name)}}return d}import{readFileSync as wI}from"node:fs";function Gg(e){return`last_maintainer_wake:${e}`}function yI(e,t){return e.prepare("SELECT v FROM kv WHERE k = ?").get(Gg(t))?.v??null}function EI(e,t,r){e.prepare("INSERT INTO kv(k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v").run(Gg(t),r)}function bI(e,t,r,n){for(let o of t)if(o.autoNudge&&o.name!==n&&!ie(e,o.name)?.confirmed_done_ts&&!je(o,r))return!0;return!1}function Vg(e,t,r,n,o=a=>wI(a,"utf8"),s=Date.now(),i){let a=t.find(m=>m.name===n.teamName);if(!a||!B(a)||!(i??bI(e,t.filter(B),r,n.teamName))||je(a,r)||He(e,n.teamName,{fromAutopilot:!0}).length>0)return!1;let l=n.cooldownMs??pe.cooldownMs,u=yI(e,n.teamName);if(u!==null&&s-Date.parse(u)<=l)return!1;let d;try{d=o(n.promptFile)}catch{return!1}return we(e,t,n.teamName,d,{from:"autopilot"}),EI(e,n.teamName,new Date(s).toISOString()),!0}function ia(e){return`blocked:${e}`}function Jg(e,t,r,n){let o=r.map(s=>{let i=Nn(e,s.id),a=i!==null?`note: "${i.body}"`:"no note recorded";return`#${s.id} ("${s.title}", ${a})`});return`Team "${t}" has ${r.length} task(s) awaiting ${n}: ${o.join(", ")} -- \`lmauto tasks show <id>\` for full context. Resolve then \`lmauto tasks update <id> --status todo\` (or \`in_progress\`) to unblock, or escalate to the operator.`}async function zg(e,t,r,n,o=pe,s=Date.now()){if(!n.some(a=>a.name===r))return[];let i=[];for(let a of t){if(a.name===r)continue;let c=ie(e,a.name),l=c?.blocked_surfaced_ts?Date.parse(c.blocked_surfaced_ts):null;if(l!==null&&s-l<=o.cooldownMs)continue;let u;try{u=Q(a)}catch{continue}let d=Re(e,u,a.leadAlias);if(d===null)continue;let m=Cn(e,d);if(m.length===0)continue;let f=[],p=new Map;for(let g of m)if(g.blocked_on!=="operator"){if(g.blocked_on===null){f.push(g);continue}if(n.some(_=>_.name===g.blocked_on)){let _=p.get(g.blocked_on)??[];_.push(g),p.set(g.blocked_on,_)}else f.push(g)}let h=!1;f.length>0&&(new Set(He(e,r).map(_=>_.subject_id).filter(_=>_!==null)).has(ia(a.name))||(we(e,n,r,Jg(e,a.name,f,"your decision"),{from:"autopilot",subject:ia(a.name)}),h=!0));for(let[g,_]of p)new Set(He(e,g).map(y=>y.subject_id).filter(y=>y!==null)).has(ia(a.name))||(we(e,n,g,Jg(e,a.name,_,"your decision"),{from:"autopilot",subject:ia(a.name)}),h=!0);h&&(gm(e,a.name,new Date().toISOString()),i.push(a.name))}return i}var TI=30*6e4;function SI(e){return`unresolvable-teamfile:${e}`}async function Yg(e,t,r,n,o=pe,s=Date.now(),i=TI,a=()=>new Date().toISOString()){if(!n.some(l=>l.name===r))return[];let c=[];for(let l of t){if(l.name===r)continue;try{Q(l),Am(e,l.name);continue}catch{}vm(e,l.name,a());let u=$m(e,l.name);if(u===null)continue;let d=s-Date.parse(u.first_observed_ts);if(d<i)continue;let m=u.surfaced_ts!==null?Date.parse(u.surfaced_ts):null;if(m!==null&&s-m<=o.cooldownMs)continue;let f=SI(l.name);if(He(e,r).map(_=>_.subject_id).filter(_=>_!==null).includes(f))continue;let h=Math.round(d/6e4),g=`[status-engine] Team "${l.name}" has had an unresolvable teamfile for over ${h} minutes -- expected "${l.name}.lmctl" under repo_path "${l.repoPath}" to exist. Every other per-team check silently skips this team until the registry entry or teamfile is fixed. \`lmauto teams\` to review the current registry.`;we(e,n,r,g,{from:"autopilot",subject:f}),km(e,l.name,a()),c.push(l.name)}return c}var ru="epic_closed_surfaced_ts";function aa(e,t){return e.transaction(()=>{let n=lt(e,t);if(n===null)return null;let o=e.prepare("SELECT * FROM notes WHERE entity_id = ? ORDER BY id DESC").all(t),s=!1;for(let i of o){let a=zt(i.body);if(a!==null){if(a[$r]===!0)break;typeof a[ru]=="string"&&(s=!0)}}return{entity:n,status:n.status,alreadySurfacedThisEpisode:s}})()}function Kg(e){return`epic-closed:${e}`}async function Qg(e,t,r,n,o=pe,s=Date.now(),i={}){let a=n.find(u=>u.name===r);if(!a)return[];if(!B(a))return[];let c=new Set(He(e,r).map(u=>u.subject_id).filter(u=>u!==null)),l=[];for(let u of t){if(u.name===r||c.has(Kg(u.name)))continue;let d=ie(e,u.name),m=d?.epic_closed_surfaced_ts?Date.parse(d.epic_closed_surfaced_ts):null;if(m!==null&&s-m<=o.cooldownMs)continue;let f;try{f=Q(u)}catch{continue}let p=Re(e,f,u.leadAlias);if(p===null)continue;let h=p.entities.filter(y=>y.kind==="epic"&&Ln.has(le(y.status)));if(h.length===0)continue;i.beforeRevalidate?.();let g=Rt(Q(u)),_=!1;e.transaction(()=>{let y=[];for(let A of h){let I=aa(e,A.id);if(I===null)continue;let x=I.entity;Ln.has(le(x.status))&&(x.owner_team_path!==g||x.owner_alias!==u.leadAlias||I.alreadySurfacedThisEpisode||y.push(x))}if(y.length===0)return;let S=y.map(A=>`#${A.id} ("${A.title}")`),T=`Team "${u.name}" closed ${y.length} epic(s): ${S.join(", ")} -- review with \`lmauto tasks show <id>\`. If more work remains, add task(s) + \`lmauto tasks update <id> --status open\` to reopen; otherwise no action needed, it stays closed.`;we(e,n,r,T,{from:"autopilot",subject:Kg(u.name),escalationOnly:!0});let R=new Date().toISOString();for(let A of y)Jt(e,A.id,{body:JSON.stringify({[ru]:R})});wm(e,u.name,R),_=!0}).immediate(),_&&l.push(u.name)}return l}function Xg(e){return`done-check:${e}`}var e_="consistency_alert_ts";function Zg(e,t){return e.transaction(()=>{let n=lt(e,t);if(n===null)return null;let o=e.prepare("SELECT * FROM notes WHERE entity_id = ? ORDER BY id DESC").all(t),s=null,i=n.updated_at,a=!1;for(let c of o){let l=zt(c.body);if(l!==null){if(l[$r]===!0){s=c.id,typeof l.to=="string"&&le(l.to)==="done"&&(i=c.created_at);break}typeof l[e_]=="string"&&(a=!0)}}return{entity:n,status:n.status,epochId:s,doneTransitionIso:i,alreadyAlertedThisEpisode:a}})()}async function vI(e,t,r){let n=new Date(Date.parse(t)-r).toISOString();for(let o of e)if(await fc(o,n))return!0;return!1}async function t_(e,t,r,n,o=pe,s={}){let i=s.hasEvidenceAroundDoneImpl??vI,a=n.find(u=>u.name===r);if(!a)return[];if(!B(a))return[];let c=new Set(He(e,r).map(u=>u.subject_id).filter(u=>u!==null)),l=[];for(let u of t){if(u.name===r||c.has(Xg(u.name)))continue;let d;try{d=Q(u)}catch{continue}let m=Re(e,d,u.leadAlias);if(m===null)continue;let f=new Map(m.entities.map(T=>[T.id,T])),p=m.entities.filter(T=>(T.kind==="task"||T.kind==="subtask")&&le(T.status)==="done"&&!Kt(e,T,f));if(p.length===0)continue;let h=u.folders&&u.folders.length>0?u.folders:[u.repoPath],g=[];for(let T of p){let R=Zg(e,T.id);if(R===null||R.alreadyAlertedThisEpisode)continue;await i(h,R.doneTransitionIso,o.idleThresholdMs)||g.push({entity:T,epochId:R.epochId})}if(g.length===0)continue;let _=Rt(d),E=new Date().toISOString(),y=!1;e.transaction(()=>{let T=[];for(let{entity:I,epochId:x}of g){let H=Zg(e,I.id);if(H===null)continue;let C=H.entity;le(C.status)==="done"&&(C.owner_team_path!==_||C.owner_alias!==u.leadAlias||Kt(e,C,new Map)||H.epochId!==x||H.alreadyAlertedThisEpisode||T.push(C))}if(T.length===0)return;let R=T.map(I=>`#${I.id} ("${I.title}")`),A=`Team "${u.name}" reported ${T.length} task(s) done with no commit/file-write found in its tracked path(s) around that time: ${R.join(", ")} -- please verify (\`lmauto tasks show <id>\` for details). This is a soft signal only; no action is needed if the work is genuinely fileless (design/coordination, or landed outside the team's tracked folders).`;we(e,n,r,A,{from:"autopilot",subject:Xg(u.name),escalationOnly:!0});for(let I of T)Jt(e,I.id,{body:JSON.stringify({[e_]:E})});y=!0}).immediate(),y&&l.push(u.name)}return l}function r_(e){return`fault:${e}`}async function n_(e,t,r,n,o=pe,s=Date.now(),i={}){if(!n.some(l=>l.name===r))return[];let a=new Set(He(e,r).map(l=>l.subject_id).filter(l=>l!==null)),c=[];for(let l of t){if(l.name===r||a.has(r_(l.name)))continue;let u=ie(e,l.name),d=u?.fault_surfaced_ts?Date.parse(u.fault_surfaced_ts):null;if(d!==null&&s-d<=o.cooldownMs)continue;let m;try{m=Q(l)}catch{continue}let f=Re(e,m,l.leadAlias);if(f===null)continue;let p=Do(e,f,o.cooldownMs,s);if(p.length===0)continue;i.beforeRevalidate?.();let h=!1;e.transaction(()=>{let _=[];for(let S of p){let T=lt(e,S.id);if(T===null)continue;let R=Do(e,{entities:[T]},o.cooldownMs,s,{team:Q(l),alias:l.leadAlias});R.length!==0&&_.push(R[0])}if(_.length===0)return;let E=_.map(S=>{let T=Nn(e,S.id),R=T!==null?`note: "${T.body}"`:"no note recorded";return`#${S.id} ("${S.title}", ${S.status}, ${R})`}),y=`Team "${l.name}" has ${_.length} task(s) stuck in a fault state past expected recovery: ${E.join(", ")} -- \`lmauto tasks show <id>\` for full context. The team is still being nudged with a back-off template on its own cadence; this is a distinct heads-up that the fault has persisted, not a request to intervene on the team's behalf.`;we(e,n,r,y,{from:"autopilot",subject:r_(l.name)}),_m(e,l.name,new Date().toISOString()),h=!0}).immediate(),h&&c.push(l.name)}return c}function o_(e,t,r,n,o,s=288e5){let i=new Date(o-n).toISOString(),a=new Date(o-s).toISOString();return e.prepare(`SELECT EXISTS(
372
372
  SELECT 1 FROM tracked_invocation
@@ -382,7 +382,7 @@ ${t.join(`
382
382
  `).filter(n=>n.length>0)}catch{return null}}async function iu(e,t,r){try{let{stdout:n}=await r("git",["-C",e,"show",`HEAD:${t}`],{timeout:1e4,maxBuffer:da});return n}catch{return null}}async function S_(e,t=su){let r=await T_(e,t);if(r===null)return null;let n=a=>!WI.some(c=>c.test(a)),o=r.filter(a=>GI.some(c=>c.test(a))&&n(a)),s=r.filter(a=>VI.some(c=>c.test(a))&&n(a)),i=[];for(let a of s){let c=await iu(e,a,t);c!==null&&JI.some(l=>l.test(c))&&i.push(a)}return[...o,...i]}async function v_(e,t=su){let r=await T_(e,t);if(r===null)return null;let n=r.filter(s=>s.endsWith(".lmctl")),o=[];for(let s of n){let i=await iu(e,s,t);if(i===null)continue;let a=b_.reduce((c,l)=>c+(l.test(i)?1:0),0);a>0&&o.push({path:s,matchCount:a})}return o}var zI=[/(^|\/)template\.lmctl$/i,/(^|\/)examples\/.*\.lmctl$/i],E_=/_MEMBER_\b|\bsessionid\s*=\s*\S/;async function A_(e,t=su){try{let[r,n]=await Promise.all([t("git",["-C",e,"ls-files"],{timeout:1e4,maxBuffer:da}),t("git",["-C",e,"ls-files","--others","--exclude-standard"],{timeout:1e4,maxBuffer:da})]),o=u=>!zI.some(d=>d.test(u)),s=u=>jI(u).includes(".lmctl")&&o(u),i=r.stdout.split(`
383
383
  `).filter(u=>u.length>0&&s(u)),a=n.stdout.split(`
384
384
  `).filter(u=>u.length>0&&s(u)),c=[];for(let u of i){let d=await iu(e,u,t);d!==null&&E_.test(d)&&c.push(u)}let l=[];for(let u of a){let d;try{d=qI(HI(e,u),"utf8")}catch{continue}E_.test(d)&&l.push(u)}return{tracked:c,unprotected:l}}catch{return null}}import{execFile as YI}from"node:child_process";import{statSync as $_}from"node:fs";import{homedir as KI}from"node:os";import{join as k_}from"node:path";import{promisify as QI}from"node:util";var au=QI(YI);var XI="mike.ma@lmctl.com",cu="mike-lmctl";async function x_(e,t=au){let r,n;try{r=(await t("git",["-C",e,"config","user.name"],{timeout:1e4})).stdout.trim()||null}catch{r=null}try{n=(await t("git",["-C",e,"config","user.email"],{timeout:1e4})).stdout.trim()||null}catch{n=null}return r===null&&n===null?null:{name:r,email:n,matchesPolicy:n===XI}}var ZI=6e4,ma;async function fa(e=au,t=Date.now(),r=$_){let n=e===au&&r===$_;if(n&&ma!==void 0&&t-ma.atMs<ZI)return ma.result;let o=await tL(e,r);return n&&(ma={result:o,atMs:t}),o}function eL(){let e=process.env.GH_CONFIG_DIR;return e?k_(e,"hosts.yml"):k_(KI(),".config","gh","hosts.yml")}async function tL(e,t){let r;try{r=(await e("gh",["auth","status"],{timeout:1e4})).stdout}catch(l){let u=l&&typeof l=="object"&&"stdout"in l?String(l.stdout):"";if(u.length===0)return null;r=u}let n=r.split(`
385
- `),o=n.findIndex(l=>/Active account: true/.test(l));if(o===-1)return null;let a=n.slice(0,o).reverse().find(l=>/Logged in to .* account /.test(l))?.match(/account\s+(\S+)/)?.[1]??null;if(a===null)return null;let c;try{c=t(eL()).mtime.toISOString()}catch{c=null}return{account:a,matchesPolicy:a===cu,hostsFileChangedAt:c}}var rL=7*24*60*6e4,nL=500,oL=3*60*6e4,sL=3*60*6e4,cs=4*60*6e4,iL=24*60*6e4,aL=48*60*6e4,cL=24*60*6e4,lL=20,uu=24*60*6e4;function uL(e,t){let r=me(t);return`${t>uu?`possible ${e}`:e} as of ${r} ago (not re-observed)`}var dL=7*24*60*6e4,mL=24*60*6e4;function fL(e,t,r,n,o){if(e?.confirmed_done_ts)return{kind:"confirmed-done",confirmedDoneTs:e.confirmed_done_ts};if(r!==null){let i=n-Date.parse(r);if(Number.isFinite(i)&&i<=mL)return null}else return o!==void 0&&Sc(o)===0?{kind:"unseeded"}:{kind:"never-active"};if(t===null)return{kind:"no-state"};if(t.status!=="ACTIVE")return{kind:"self-report",status:t.status,changedTs:t.changed_ts};let s=n-Date.parse(t.changed_ts);return!Number.isFinite(s)||s>dL?{kind:"self-report",status:t.status,changedTs:t.changed_ts}:null}function pL(e,t){let r=e.teams.filter(B);return t===void 0?r:r.filter(n=>n.name===t)}function hL(e,t,r){let n=r(e);if(n.length===0)return null;let o=[],s=[];for(let i of n)i.provider!==null&&t.has(i.provider)?o.push({alias:i.alias,provider:i.provider}):s.push({alias:i.alias,provider:i.provider});return{totalMembers:n.length,quiescedMembers:o,liveMembers:s}}async function pa(e,t={}){let r=e.db.db,n=t.config??pe,o=t.nowMs??Date.now(),s=pL(e,t.team),i=t.awaitingReviewThresholdMs??Wc,a=[],c=[],l=[],u=[],d=[],m=new Set(ss(r,o).map(F=>F.row.subject_id).filter(F=>F!==null)),f=[],p=[],h=[],g=[],_=[],E=[],y=t.countDirtyGitFilesImpl??l_,S=[],T=t.lintTeamfileWarningsImpl??d_,R=[],A=[],I=[],x=[],H=[],C=t.findNeverTrackFilesImpl??S_,w=t.findSecretBearingTeamfilesImpl??v_,b=t.checkTeamfileTrackingImpl??A_,N=t.checkRepoGitIdentityImpl??x_,P=t.resolveMemberProviderImpl??Gt,J=t.listTeamMembersImpl??Xr,ee=[],oe=!1;try{ee=Bo(r).filter(F=>ot(r,F.provider,o).disabled)}catch{oe=!0}let V=Eg(r,o),se=bg(r),k=null;try{k=Tg(r,o)}catch{k=null}let O=new Set(ee.map(F=>F.provider)),$=[],q=e.teams.filter(B),M=e.teams.map(F=>F.name);for(let F of s){let _e;try{_e=Q(F)}catch{continue}let Fe=await T(_e);Fe!==null&&Fe.length>0&&S.push({team:F.name,warnings:Fe});let ct=await C(F.repoPath);ct!==null&&ct.length>0&&R.push({team:F.name,files:ct});let En=await w(F.repoPath);En!==null&&En.length>0&&A.push({team:F.name,files:En});let Ut=await b(F.repoPath);Ut!==null&&(Ut.tracked.length>0&&I.push({team:F.name,files:Ut.tracked}),Ut.unprotected.length>0&&x.push({team:F.name,files:Ut.unprotected}));let Yr=await N(F.repoPath);Yr!==null&&!Yr.matchesPolicy&&H.push({team:F.name,identity:{name:Yr.name,email:Yr.email}});let Ft=O.size>0?hL(F,O,J):null;if(O.size>0){let ce=$t(r,F.name),qt=ce===null?F.name:ce.companionTeam,Qa=ce===null?F.leadAlias:ce.workerAlias,ko=ce===null?F.repoPath:q.find(xo=>xo.name===qt)?.repoPath??F.repoPath,Kr=P({repoPath:ko,name:qt},Qa);if(Kr!==null&&O.has(Kr)){let xo=ee.find(LA=>LA.provider===Kr)?.expiresAt??null;$.push({team:F.name,provider:Kr,expiresAt:xo,totalMembers:Ft?.totalMembers??1,liveMembers:Ft?.liveMembers??[]})}}let Ya=dn(r,F.name,o,M);Ya.length>0&&l.push({team:F.name,rows:Ya,...Ft!==null&&Ft.quiescedMembers.length>0?{quiescedMembers:Ft.quiescedMembers,totalMembers:Ft.totalMembers}:{}});let Yd=Ya.filter(ce=>ce.row.status==="sent"||ce.row.status==="retrieved");if(Yd.length>0){let ce=r.prepare("SELECT MAX(created_ts) AS ts FROM queue WHERE from_id = ?").get(F.name),qt=fL(ie(r,F.name),qe(r,F.name),ce.ts,o,F);qt!==null&&d.push({team:F.name,rows:Yd,reason:qt})}let Kd=sa(r,F.name,cs,o);Kd.length>0&&u.push({team:F.name,rows:Kd});let Sr=Re(r,_e,F.leadAlias);if(Sr===null)continue;for(let ce of Cn(r,Sr)){let qt;try{let ko=w_(r,ce.id),Kr=ua(r,ce.id).filter(xo=>!ko.has(xo.id));Kr.length>0&&(qt=Kr)}catch{qt=void 0}let Qa=di(r,ce.id);a.push({team:F.name,entity:ce,blockedSinceTs:Qa,...qt!==void 0?{roots:qt}:{}}),ce.blocked_on==="operator"?m.has(`task:${ce.id}`)||c.push({team:F.name,entity:ce,blockedOn:"operator",reason:"operator-uncorrelated"}):ce.blocked_on!==null&&!e.teams.some(ko=>ko.name===ce.blocked_on)&&c.push({team:F.name,entity:ce,blockedOn:ce.blocked_on,reason:"team-unresolvable"})}for(let ce of Do(r,Sr,n.cooldownMs,o))f.push({team:F.name,entity:ce});for(let ce of rp(r,Sr,i,o))p.push({team:F.name,task:ce});for(let ce of np(r,Sr,o))h.push({team:F.name,task:ce});for(let ce of Sr.entities)ce.kind==="epic"&&ce.needs_review===1&&_i(ce)&&g.push({team:F.name,entity:ce});for(let ce of Sr.entities)ce.kind!=="epic"||!Ln.has(le(ce.status))||aa(r,ce.id)?.alreadySurfacedThisEpisode||_.push({team:F.name,entity:ce});let Ka=Sr.entities.filter(ce=>le(ce.status)==="todo");if(Ka.length>0){let ce=await y(F.repoPath);ce!==null&&ce>0&&E.push({team:F.name,dirtyCount:ce,todoCount:Ka.length,exampleEntity:Ka[0]})}}let W=await(t.fetchReportImpl??ke)(),ae=t.heavyLockImpl?t.heavyLockImpl():dt(void 0,void 0,void 0,()=>{}),be=await On(r,s,W,ae,n,o,{readOnly:!0}),ne=new Set($.map(F=>F.team)),D=be.filter(F=>!ne.has(F)),j=t.findPersistentDispatchFailuresImpl??c_,{unreachable:K,notObserved:z}=await j(r,s,W,o,cs),re=[];for(let F of D){let _e=ie(r,F);if(_e?.miniplayer_verdict_label&&_e.miniplayer_verdict_reason&&_e.miniplayer_verdict_ts){let Fe=qe(r,F),ct=_e.miniplayer_verdict_label!=="genuinely_done"&&Fe?.status==="DONE"?{changedTs:Fe.changed_ts}:void 0;re.push({team:F,label:_e.miniplayer_verdict_label,reason:_e.miniplayer_verdict_reason,ts:_e.miniplayer_verdict_ts,...ct!==void 0?{selfReportedDone:ct}:{}})}}let te=[];for(let F of s){let _e=ie(r,F.name);_e?.hung_holder_flagged_ts&&_e.hung_holder_reason&&te.push({team:F.name,reason:_e.hung_holder_reason,flaggedTs:_e.hung_holder_flagged_ts})}let ue=Sm(r).map(F=>({team:F.team,reason:F.reason,detail:F.detail,suspendedAt:F.suspended_at})),xe=t.blockedSelfReportUrgentThresholdMs??iL,Se=t.blockedSelfReportUnconfirmedThresholdMs??aL,Y=[];for(let F of s){let _e=qe(r,F.name);if(_e?.status==="BLOCKED"){let Fe=o-Date.parse(_e.changed_ts),ct=Fe>=Se;Y.push({team:F.name,changedTs:_e.changed_ts,ageMs:Fe,urgent:!ct&&Fe>=xe,unconfirmed:ct})}}Y.sort((F,_e)=>_e.ageMs-F.ageMs);let Te=t.orphanReapCandidateWindowMs??rL,Je=new Date(o-Te).toISOString(),Pt=js(r,kl,Je,nL).filter(F=>t.team===void 0||F.team===t.team).map(F=>({team:F.team,ts:F.ts,reason:F.note??"(no reason recorded)"})),G=t.maintainer===void 0?null:[...He(r,t.maintainer),...ai(r,t.maintainer)].sort((F,_e)=>F.id-_e.id).filter(F=>F.from_id!=="autopilot"),ye=t.maintainer===void 0?[]:Lg(r,t.maintainer,o).map(F=>({row:F.row,constituentCount:un(r,F.row)})),at=t.maintainer===void 0?[]:ss(r,o).map(F=>{let _e=un(r,F.row),Fe=os(r,F.row),ct=F.ageMs>=cs||_e>=2&&F.row.sent_ts===null;return{row:F.row,constituentCount:_e,retractedCount:Fe,urgent:ct}}),tt=t.maintainerStaleThresholdMs??oL,gt=[];if(t.maintainer!==void 0&&G!==null){let _e=ie(r,t.maintainer)?.last_cli_activity_ts??null,Fe=oh(_e,o),ct=!vl(_e,tt,o),En=G[0],Ut=En?o-Date.parse(En.created_ts):null,Yr=Ut!==null&&Ut>tt;if(ct||Yr){let Ft=[];ct&&Ft.push(_e===null?"no CLI activity ever recorded":`no CLI activity in ${me(Fe)}`),Yr&&Ft.push(`oldest queued item is ${me(Ut)} old`),gt.push({team:t.maintainer,reason:Ft.join("; "),ageMs:Fe===null?1/0:Math.max(Fe,Ut??0)})}}let ze;if(t.team===void 0)ze=a.map(F=>F.entity);else{ze=[];for(let F of e.teams.filter(B)){let _e;try{_e=Q(F)}catch{continue}let Fe=Re(r,_e,F.leadAlias);Fe!==null&&ze.push(...Cn(r,Fe))}}let yn=y_(r,ze,e.teams),br=m_(r),cr=p_(r,e.teams),rt=h_(r),Tr=[];for(let F of e.teams.filter(B)){try{Q(F)}catch{continue}Sc(F)===0&&Tr.push({team:F.name,repoPath:F.repoPath})}let $o=t.stuckProcessingThresholdMs??sL,Ds=t.stuckProcessingMaxAgeMs??cL,za=t.maintainer!==void 0&&t.stuckProcessingFleetWide!==!0?t.maintainer:void 0,IA=Ig(r,{minAgeMs:$o,maxAgeMs:Ds,fromId:za},o).map(F=>({queueId:F.row.id,fromId:F.row.from_id,toId:F.row.to_id,ageMs:F.ageMs,constituentCount:un(r,F.row)}));return{blocked:a,blockedOnUnresolved:c,owedAnswers:l,recentlyAnsweredForSender:u,parkedTeamsWithOwedPrompts:d,awaitingDecision:f,awaitingReview:p,stalled:D,stalledVerdicts:re,hungHolders:te,autoNudgeSuspended:ue,blockedSelfReports:Y,flaggedEpics:g,closedEpicsToReview:_,orphanReapCandidates:Pt,maintainerStale:gt,blockingRoots:yn,epicsWithoutOwner:br,unresolvableOwnerEntities:cr,untrackedBlockers:rt,unseededTeams:Tr,stuckProcessing:IA,inbox:G,memory:(t.readMemoryAvailabilityImpl??Co)(),operatorPrompts:ye,operatorEscalations:at,uncommittedWork:E,teamfileLintWarnings:S,expiredHolds:h,neverTrackFiles:R,secretBearingTeamfiles:A,trackedTeamfiles:I,unprotectedTeamfiles:x,gitIdentityMismatches:H,activeGhAccount:await(t.checkActiveGhAccountImpl??fa)(),disabledProviders:ee,providerDisableReadFailed:oe,quiescedByProviderDisable:$,staleAutoScanPause:k,persistentDispatchFailures:K,notObserved:z,rateLimitPolicyHealth:V,rateLimitLevelWarnings:se}}function lu(e){return` ${e.team}: #${e.entity.id} ("${e.entity.title}")`}function R_(e){return e.length===0?"":`
385
+ `),o=n.findIndex(l=>/Active account: true/.test(l));if(o===-1)return null;let a=n.slice(0,o).reverse().find(l=>/Logged in to .* account /.test(l))?.match(/account\s+(\S+)/)?.[1]??null;if(a===null)return null;let c;try{c=t(eL()).mtime.toISOString()}catch{c=null}return{account:a,matchesPolicy:a===cu,hostsFileChangedAt:c}}var rL=7*24*60*6e4,nL=500,oL=3*60*6e4,sL=3*60*6e4,cs=4*60*6e4,iL=24*60*6e4,aL=48*60*6e4,cL=24*60*6e4,lL=20,uu=24*60*6e4;function uL(e,t){let r=me(t);return`${t>uu?`possible ${e}`:e} as of ${r} ago (not re-observed)`}var dL=7*24*60*6e4,mL=24*60*6e4;function fL(e,t,r,n,o){if(e?.confirmed_done_ts)return{kind:"confirmed-done",confirmedDoneTs:e.confirmed_done_ts};if(r!==null){let i=n-Date.parse(r);if(Number.isFinite(i)&&i<=mL)return null}else return o!==void 0&&Sc(o)===0?{kind:"unseeded"}:{kind:"never-active"};if(t===null)return{kind:"no-state"};if(t.status!=="ACTIVE")return{kind:"self-report",status:t.status,changedTs:t.changed_ts};let s=n-Date.parse(t.changed_ts);return!Number.isFinite(s)||s>dL?{kind:"self-report",status:t.status,changedTs:t.changed_ts}:null}function pL(e,t){let r=e.teams.filter(B);return t===void 0?r:r.filter(n=>n.name===t)}function hL(e,t,r){let n=r(e);if(n.length===0)return null;let o=[],s=[];for(let i of n)i.provider!==null&&t.has(i.provider)?o.push({alias:i.alias,provider:i.provider}):s.push({alias:i.alias,provider:i.provider});return{totalMembers:n.length,quiescedMembers:o,liveMembers:s}}async function pa(e,t={}){let r=e.db.db,n=t.config??pe,o=t.nowMs??Date.now(),s=pL(e,t.team),i=t.awaitingReviewThresholdMs??Wc,a=[],c=[],l=[],u=[],d=[],m=new Set(ss(r,o).map(F=>F.row.subject_id).filter(F=>F!==null)),f=[],p=[],h=[],g=[],_=[],E=[],y=t.countDirtyGitFilesImpl??l_,S=[],T=t.lintTeamfileWarningsImpl??d_,R=[],A=[],I=[],x=[],H=[],C=t.findNeverTrackFilesImpl??S_,w=t.findSecretBearingTeamfilesImpl??v_,b=t.checkTeamfileTrackingImpl??A_,N=t.checkRepoGitIdentityImpl??x_,M=t.resolveMemberProviderImpl??Gt,W=t.listTeamMembersImpl??Xr,ee=[],oe=!1;try{ee=Bo(r).filter(F=>ot(r,F.provider,o).disabled)}catch{oe=!0}let J=Eg(r,o),se=bg(r),k=null;try{k=Tg(r,o)}catch{k=null}let O=new Set(ee.map(F=>F.provider)),$=[],q=e.teams.filter(B),U=e.teams.map(F=>F.name);for(let F of s){let _e;try{_e=Q(F)}catch{continue}let Fe=await T(_e);Fe!==null&&Fe.length>0&&S.push({team:F.name,warnings:Fe});let ct=await C(F.repoPath);ct!==null&&ct.length>0&&R.push({team:F.name,files:ct});let En=await w(F.repoPath);En!==null&&En.length>0&&A.push({team:F.name,files:En});let Ut=await b(F.repoPath);Ut!==null&&(Ut.tracked.length>0&&I.push({team:F.name,files:Ut.tracked}),Ut.unprotected.length>0&&x.push({team:F.name,files:Ut.unprotected}));let Yr=await N(F.repoPath);Yr!==null&&!Yr.matchesPolicy&&H.push({team:F.name,identity:{name:Yr.name,email:Yr.email}});let Ft=O.size>0?hL(F,O,W):null;if(O.size>0){let ce=$t(r,F.name),qt=ce===null?F.name:ce.companionTeam,Qa=ce===null?F.leadAlias:ce.workerAlias,ko=ce===null?F.repoPath:q.find(xo=>xo.name===qt)?.repoPath??F.repoPath,Kr=M({repoPath:ko,name:qt},Qa);if(Kr!==null&&O.has(Kr)){let xo=ee.find(LA=>LA.provider===Kr)?.expiresAt??null;$.push({team:F.name,provider:Kr,expiresAt:xo,totalMembers:Ft?.totalMembers??1,liveMembers:Ft?.liveMembers??[]})}}let Ya=dn(r,F.name,o,U);Ya.length>0&&l.push({team:F.name,rows:Ya,...Ft!==null&&Ft.quiescedMembers.length>0?{quiescedMembers:Ft.quiescedMembers,totalMembers:Ft.totalMembers}:{}});let Yd=Ya.filter(ce=>ce.row.status==="sent"||ce.row.status==="retrieved");if(Yd.length>0){let ce=r.prepare("SELECT MAX(created_ts) AS ts FROM queue WHERE from_id = ?").get(F.name),qt=fL(ie(r,F.name),qe(r,F.name),ce.ts,o,F);qt!==null&&d.push({team:F.name,rows:Yd,reason:qt})}let Kd=sa(r,F.name,cs,o);Kd.length>0&&u.push({team:F.name,rows:Kd});let Sr=Re(r,_e,F.leadAlias);if(Sr===null)continue;for(let ce of Cn(r,Sr)){let qt;try{let ko=w_(r,ce.id),Kr=ua(r,ce.id).filter(xo=>!ko.has(xo.id));Kr.length>0&&(qt=Kr)}catch{qt=void 0}let Qa=di(r,ce.id);a.push({team:F.name,entity:ce,blockedSinceTs:Qa,...qt!==void 0?{roots:qt}:{}}),ce.blocked_on==="operator"?m.has(`task:${ce.id}`)||c.push({team:F.name,entity:ce,blockedOn:"operator",reason:"operator-uncorrelated"}):ce.blocked_on!==null&&!e.teams.some(ko=>ko.name===ce.blocked_on)&&c.push({team:F.name,entity:ce,blockedOn:ce.blocked_on,reason:"team-unresolvable"})}for(let ce of Do(r,Sr,n.cooldownMs,o))f.push({team:F.name,entity:ce});for(let ce of rp(r,Sr,i,o))p.push({team:F.name,task:ce});for(let ce of np(r,Sr,o))h.push({team:F.name,task:ce});for(let ce of Sr.entities)ce.kind==="epic"&&ce.needs_review===1&&_i(ce)&&g.push({team:F.name,entity:ce});for(let ce of Sr.entities)ce.kind!=="epic"||!Ln.has(le(ce.status))||aa(r,ce.id)?.alreadySurfacedThisEpisode||_.push({team:F.name,entity:ce});let Ka=Sr.entities.filter(ce=>le(ce.status)==="todo");if(Ka.length>0){let ce=await y(F.repoPath);ce!==null&&ce>0&&E.push({team:F.name,dirtyCount:ce,todoCount:Ka.length,exampleEntity:Ka[0]})}}let G=await(t.fetchReportImpl??ke)(),ae=t.heavyLockImpl?t.heavyLockImpl():dt(void 0,void 0,void 0,()=>{}),be=await On(r,s,G,ae,n,o,{readOnly:!0}),ne=new Set($.map(F=>F.team)),D=be.filter(F=>!ne.has(F)),j=t.findPersistentDispatchFailuresImpl??c_,{unreachable:K,notObserved:z}=await j(r,s,G,o,cs),re=[];for(let F of D){let _e=ie(r,F);if(_e?.miniplayer_verdict_label&&_e.miniplayer_verdict_reason&&_e.miniplayer_verdict_ts){let Fe=qe(r,F),ct=_e.miniplayer_verdict_label!=="genuinely_done"&&Fe?.status==="DONE"?{changedTs:Fe.changed_ts}:void 0;re.push({team:F,label:_e.miniplayer_verdict_label,reason:_e.miniplayer_verdict_reason,ts:_e.miniplayer_verdict_ts,...ct!==void 0?{selfReportedDone:ct}:{}})}}let te=[];for(let F of s){let _e=ie(r,F.name);_e?.hung_holder_flagged_ts&&_e.hung_holder_reason&&te.push({team:F.name,reason:_e.hung_holder_reason,flaggedTs:_e.hung_holder_flagged_ts})}let ue=Sm(r).map(F=>({team:F.team,reason:F.reason,detail:F.detail,suspendedAt:F.suspended_at})),xe=t.blockedSelfReportUrgentThresholdMs??iL,Se=t.blockedSelfReportUnconfirmedThresholdMs??aL,Y=[];for(let F of s){let _e=qe(r,F.name);if(_e?.status==="BLOCKED"){let Fe=o-Date.parse(_e.changed_ts),ct=Fe>=Se;Y.push({team:F.name,changedTs:_e.changed_ts,ageMs:Fe,urgent:!ct&&Fe>=xe,unconfirmed:ct})}}Y.sort((F,_e)=>_e.ageMs-F.ageMs);let Te=t.orphanReapCandidateWindowMs??rL,Je=new Date(o-Te).toISOString(),Pt=js(r,kl,Je,nL).filter(F=>t.team===void 0||F.team===t.team).map(F=>({team:F.team,ts:F.ts,reason:F.note??"(no reason recorded)"})),V=t.maintainer===void 0?null:[...He(r,t.maintainer),...ai(r,t.maintainer)].sort((F,_e)=>F.id-_e.id).filter(F=>F.from_id!=="autopilot"),ye=t.maintainer===void 0?[]:Lg(r,t.maintainer,o).map(F=>({row:F.row,constituentCount:un(r,F.row)})),at=t.maintainer===void 0?[]:ss(r,o).map(F=>{let _e=un(r,F.row),Fe=os(r,F.row),ct=F.ageMs>=cs||_e>=2&&F.row.sent_ts===null;return{row:F.row,constituentCount:_e,retractedCount:Fe,urgent:ct}}),tt=t.maintainerStaleThresholdMs??oL,gt=[];if(t.maintainer!==void 0&&V!==null){let _e=ie(r,t.maintainer)?.last_cli_activity_ts??null,Fe=oh(_e,o),ct=!vl(_e,tt,o),En=V[0],Ut=En?o-Date.parse(En.created_ts):null,Yr=Ut!==null&&Ut>tt;if(ct||Yr){let Ft=[];ct&&Ft.push(_e===null?"no CLI activity ever recorded":`no CLI activity in ${me(Fe)}`),Yr&&Ft.push(`oldest queued item is ${me(Ut)} old`),gt.push({team:t.maintainer,reason:Ft.join("; "),ageMs:Fe===null?1/0:Math.max(Fe,Ut??0)})}}let ze;if(t.team===void 0)ze=a.map(F=>F.entity);else{ze=[];for(let F of e.teams.filter(B)){let _e;try{_e=Q(F)}catch{continue}let Fe=Re(r,_e,F.leadAlias);Fe!==null&&ze.push(...Cn(r,Fe))}}let yn=y_(r,ze,e.teams),br=m_(r),cr=p_(r,e.teams),rt=h_(r),Tr=[];for(let F of e.teams.filter(B)){try{Q(F)}catch{continue}Sc(F)===0&&Tr.push({team:F.name,repoPath:F.repoPath})}let $o=t.stuckProcessingThresholdMs??sL,Ds=t.stuckProcessingMaxAgeMs??cL,za=t.maintainer!==void 0&&t.stuckProcessingFleetWide!==!0?t.maintainer:void 0,IA=Ig(r,{minAgeMs:$o,maxAgeMs:Ds,fromId:za},o).map(F=>({queueId:F.row.id,fromId:F.row.from_id,toId:F.row.to_id,ageMs:F.ageMs,constituentCount:un(r,F.row)}));return{blocked:a,blockedOnUnresolved:c,owedAnswers:l,recentlyAnsweredForSender:u,parkedTeamsWithOwedPrompts:d,awaitingDecision:f,awaitingReview:p,stalled:D,stalledVerdicts:re,hungHolders:te,autoNudgeSuspended:ue,blockedSelfReports:Y,flaggedEpics:g,closedEpicsToReview:_,orphanReapCandidates:Pt,maintainerStale:gt,blockingRoots:yn,epicsWithoutOwner:br,unresolvableOwnerEntities:cr,untrackedBlockers:rt,unseededTeams:Tr,stuckProcessing:IA,inbox:V,memory:(t.readMemoryAvailabilityImpl??Co)(),operatorPrompts:ye,operatorEscalations:at,uncommittedWork:E,teamfileLintWarnings:S,expiredHolds:h,neverTrackFiles:R,secretBearingTeamfiles:A,trackedTeamfiles:I,unprotectedTeamfiles:x,gitIdentityMismatches:H,activeGhAccount:await(t.checkActiveGhAccountImpl??fa)(),disabledProviders:ee,providerDisableReadFailed:oe,quiescedByProviderDisable:$,staleAutoScanPause:k,persistentDispatchFailures:K,notObserved:z,rateLimitPolicyHealth:J,rateLimitLevelWarnings:se}}function lu(e){return` ${e.team}: #${e.entity.id} ("${e.entity.title}")`}function R_(e){return e.length===0?"":`
386
386
  later traffic worth checking before ruling on this (not proof it was answered): ${e.map(r=>`#${r.row.id} ${r.row.from_id}->${r.row.to_id} (${he(r.row.created_ts)}, via ${r.matchedTeam})`).join("; ")}`}function ls(e,t={}){if(t.json)return JSON.stringify(e);let r=[];if(e.operatorPrompts.length>0){let c=Date.now(),l=e.operatorPrompts.map(m=>` #${m.row.id} -- sent ${me(c-Date.parse(m.row.created_ts))} ago, unanswered`+(m.constituentCount>1?` (${m.constituentCount} merged into this one)`:"")),u=e.operatorPrompts.reduce((m,f)=>m+f.constituentCount,0),d=u===e.operatorPrompts.length?`${e.operatorPrompts.length}`:`${u} in ${e.operatorPrompts.length} thread${e.operatorPrompts.length===1?"":"s"}`;r.push(`OPERATOR MESSAGE, UNANSWERED (${d}):
387
387
  ${l.join(`
388
388
  `)}`)}if(e.operatorEscalations.length>0){let c=Date.now(),l=f=>{let p=f.constituentCount>1?` (${f.constituentCount} merged into this one${f.retractedCount>0?`, ${f.retractedCount} retracted`:""})`:"";return` #${f.row.id} from ${f.row.from_id} -- sent ${me(c-Date.parse(f.row.created_ts))} ago, unanswered${p}`},u=f=>{let p=f.reduce((h,g)=>h+g.constituentCount,0);return p===f.length?`${f.length}`:`${p} in ${f.length} thread${f.length===1?"":"s"}`},d=e.operatorEscalations.filter(f=>f.urgent),m=e.operatorEscalations.filter(f=>!f.urgent);d.length>0&&r.push(`ESCALATED TO OPERATOR, URGENT (${u(d)}) -- past 4h old or an undelivered pileup:
@@ -471,16 +471,16 @@ ${o}`;if(e.activeGhAccount===null||e.activeGhAccount.matchesPolicy)return s;let
471
471
 
472
472
  ${s}`}async function N_(e,t,r,n={}){let o={db:{path:"",db:e,close:()=>{}},teamsConfPath:"",teams:[...t]},s=await pa(o,{maintainer:r,...n.config!==void 0?{config:n.config}:{},...n.nowMs!==void 0?{nowMs:n.nowMs}:{},...n.awaitingReviewThresholdMs!==void 0?{awaitingReviewThresholdMs:n.awaitingReviewThresholdMs}:{},...n.maintainerStaleThresholdMs!==void 0?{maintainerStaleThresholdMs:n.maintainerStaleThresholdMs}:{},...n.fetchReportImpl!==void 0?{fetchReportImpl:n.fetchReportImpl}:{},...n.heavyLockImpl!==void 0?{heavyLockImpl:n.heavyLockImpl}:{},...n.findNeverTrackFilesImpl!==void 0?{findNeverTrackFilesImpl:n.findNeverTrackFilesImpl}:{},...n.findSecretBearingTeamfilesImpl!==void 0?{findSecretBearingTeamfilesImpl:n.findSecretBearingTeamfilesImpl}:{},...n.checkRepoGitIdentityImpl!==void 0?{checkRepoGitIdentityImpl:n.checkRepoGitIdentityImpl}:{},...n.checkActiveGhAccountImpl!==void 0?{checkActiveGhAccountImpl:n.checkActiveGhAccountImpl}:{},...n.resolveMemberProviderImpl!==void 0?{resolveMemberProviderImpl:n.resolveMemberProviderImpl}:{},...n.lintTeamfileWarningsImpl!==void 0?{lintTeamfileWarningsImpl:n.lintTeamfileWarningsImpl}:{}}),i=(n.readMemoryAvailabilityImpl??Co)(),a=s.blocked.length===0&&s.awaitingDecision.length===0&&s.awaitingReview.length===0&&s.stalled.length===0&&s.hungHolders.length===0&&s.flaggedEpics.length===0&&s.closedEpicsToReview.length===0&&(s.inbox===null||s.inbox.length===0)&&s.operatorPrompts.length===0&&s.operatorEscalations.length===0&&s.uncommittedWork.length===0&&s.expiredHolds.length===0&&s.neverTrackFiles.length===0&&s.secretBearingTeamfiles.length===0&&s.gitIdentityMismatches.length===0&&(s.activeGhAccount===null||s.activeGhAccount.matchesPolicy)&&!s.providerDisableReadFailed&&s.quiescedByProviderDisable.length===0&&s.blockedOnUnresolved.length===0&&s.staleAutoScanPause===null&&s.persistentDispatchFailures.every(u=>u.kind!=="continuous")&&s.parkedTeamsWithOwedPrompts.length===0&&s.rateLimitPolicyHealth===null,c=oi(i),l=c===null?ls(s):`${ls(s)}
473
473
 
474
- ${c}`;return{attention:s,memory:i,isEmpty:a,rendered:l}}var yL=18e5,EL={watch:{first:!1,active:[],wentIdle:[],newlyActive:[],wake:!1,why:"nochange"},stalled:[],maintainerWoken:!1,autoContinued:[],surfacedUnknown:[],surfacedBlocked:[],surfacedDoneConsistency:[],surfacedUnresolvableTeamfiles:[],surfacedFault:[],surfacedClosedEpics:[],escalated:[],autoRedelivered:[],woken:[],firedCronJobs:[],rateLimitCollected:null,rateLimitPolicyEvaluations:[]};function I_(e){let t=e.fetchReport??ke,r=e.readHeavyLockStatusImpl??dt,n=e.heavyLockStatusPath??zn(),o=e.heavyLockPath??Yn(),s=e.maintainerWakeImpl??Vg,i=e.autoContinueImpl??Wg,a=e.surfaceUnknownImpl??i_,c=e.surfaceBlockedImpl??zg,l=e.surfaceDoneConsistencyImpl??t_,u=e.surfaceUnresolvableTeamfilesImpl??Yg,d=e.surfaceFaultImpl??n_,m=e.surfaceClosedEpicsImpl??Qg,f=e.escalateImpl??lg,p=e.autoRedeliverImpl??ug,h=e.wakeImpl??dg,g=e.evaluateCronJobsImpl??Zh,_=e.miniplayerVerifyImpl??vh,E=e.hungHolderCheckImpl??mh,y=e.epicReviewImpl??bh,S=e.orphanReconcilerImpl??wh,T=e.hangProbeCollectImpl??Eh,R=e.rateLimitCollectImpl??hg,A=e.rateLimitPolicyImpl??wg,I=e.assembleWakeReportImpl??N_,x=e.existsSyncImpl??gL,H=e.statSyncImpl??wL,C=e.config??pe,w=e.escalation??Jl,b=e.autoRedeliver??zl,N=e.wake??Yl,P=e.intervalMs??yL,J=null,ee=!1;async function oe(){if(ee)return EL;ee=!0;try{let V=e.getTeams(),se=V.filter(B),k;try{k=await t(),ag(k,new Date().toISOString())}catch(G){throw cg(G instanceof Error?G.message:String(G),new Date().toISOString()),G}let O=Date.now(),$=r(n,o,void 0,G=>{e.onError?.(G)}),q=Ks(e.db,se,k),{stalled:M,continueEligible:Z}=await cp(e.db,se,k,$,C,O);if(e.miniplayerVerify)try{await _(e.db,M,se,e.miniplayerVerify)}catch(G){e.onError?.(G)}let W=new Set(M);for(let G of se)!W.has(G.name)&&ie(e.db,G.name)?.miniplayer_verdict_label&&Em(e.db,G.name);if(e.hungHolderCheck)try{let G=e.maintainerWake?.sessionAlivePath!==void 0||e.maintainerWake?.activityFreshnessMs!==void 0?{sessionAliveExemptTeamName:e.maintainerWake.teamName,sessionAliveExemptPath:e.maintainerWake.sessionAlivePath,sessionAliveFreshnessMs:e.maintainerWake.sessionAliveFreshnessMs,activityFreshnessMs:e.maintainerWake.activityFreshnessMs}:{};await E(e.db,se,{...G,...e.hungHolderCheck})}catch(G){e.onError?.(G)}if(e.orphanReconciler)try{let G=e.maintainerWake?.sessionAlivePath!==void 0||e.maintainerWake?.activityFreshnessMs!==void 0?{sessionAliveExemptTeamName:e.maintainerWake.teamName,sessionAliveExemptPath:e.maintainerWake.sessionAlivePath,sessionAliveFreshnessMs:e.maintainerWake.sessionAliveFreshnessMs,activityFreshnessMs:e.maintainerWake.activityFreshnessMs}:{};await S(e.db,V,k,{...G,...e.orphanReconciler})}catch(G){e.onError?.(G)}if(e.hangProbeCollect)try{T(e.db,e.hangProbeCollect)}catch(G){e.onError?.(G)}if(e.autoNudgeRedirectReview)try{let G=e.findDueAutoNudgeReviewsImpl??th,ye=new Map(se.map(rt=>[rt.name,rt.repoPath])),at=new Map(se.map(rt=>[rt.name,rt])),tt=await G(e.db,ye,O),gt=e.buildReviewMessageImpl??nh,ze=e.resetShiftImpl??rh,yn=e.enqueueImpl??we,br=e.checkProviderDisabledImpl??ot,cr=e.resolveMemberProviderImpl??Gt;for(let rt of tt)try{let Tr=ye.get(rt.team);if(Tr===void 0)continue;let $o=at.get(rt.team),Ds=$o===void 0?null:cr($o,$o.leadAlias);if(Ds!==null&&br(e.db,Ds,O).disabled)continue;let za=await gt(rt,Tr);yn(e.db,V,rt.team,za,{from:"autopilot"}),await ze(e.db,rt.team,Tr,new Date(O).toISOString())}catch(Tr){e.onError?.(Tr)}}catch(G){e.onError?.(G)}if(e.epicReview)try{await y(e.db,V,e.epicReview)}catch(G){e.onError?.(G)}let ae=!1;if(e.maintainerWake)try{let G={cooldownMs:C.cooldownMs,...e.maintainerWake};if(G.sessionAlivePath!==void 0){let ye=qn(G.sessionAlivePath,G.sessionAliveFreshnessMs,G.activityFreshnessMs!==void 0?ie(e.db,G.teamName)?.last_cli_activity_ts??null:null,G.activityFreshnessMs,{existsSyncImpl:x,statSyncImpl:H,nowMs:O}),at,tt;try{let ze=await I(e.db,V,G.teamName,{nowMs:O,config:C,fetchReportImpl:async()=>k,heavyLockImpl:()=>$,...G.maintainerStaleThresholdMs!==void 0?{maintainerStaleThresholdMs:G.maintainerStaleThresholdMs}:{}});at=ze.rendered,tt=ze.isEmpty}catch(ze){e.onError?.(ze),at="wake-report assembly failed this tick -- waking conservatively; check server logs for the error.",tt=!1}let gt=ze=>`${_L(ze,"utf8")}
474
+ ${c}`;return{attention:s,memory:i,isEmpty:a,rendered:l}}var yL=18e5,EL={watch:{first:!1,active:[],wentIdle:[],newlyActive:[],wake:!1,why:"nochange"},stalled:[],maintainerWoken:!1,autoContinued:[],surfacedUnknown:[],surfacedBlocked:[],surfacedDoneConsistency:[],surfacedUnresolvableTeamfiles:[],surfacedFault:[],surfacedClosedEpics:[],escalated:[],autoRedelivered:[],woken:[],firedCronJobs:[],rateLimitCollected:null,rateLimitPolicyEvaluations:[]};function I_(e){let t=e.fetchReport??ke,r=e.readHeavyLockStatusImpl??dt,n=e.heavyLockStatusPath??zn(),o=e.heavyLockPath??Yn(),s=e.maintainerWakeImpl??Vg,i=e.autoContinueImpl??Wg,a=e.surfaceUnknownImpl??i_,c=e.surfaceBlockedImpl??zg,l=e.surfaceDoneConsistencyImpl??t_,u=e.surfaceUnresolvableTeamfilesImpl??Yg,d=e.surfaceFaultImpl??n_,m=e.surfaceClosedEpicsImpl??Qg,f=e.escalateImpl??lg,p=e.autoRedeliverImpl??ug,h=e.wakeImpl??dg,g=e.evaluateCronJobsImpl??Zh,_=e.miniplayerVerifyImpl??vh,E=e.hungHolderCheckImpl??mh,y=e.epicReviewImpl??bh,S=e.orphanReconcilerImpl??wh,T=e.hangProbeCollectImpl??Eh,R=e.rateLimitCollectImpl??hg,A=e.rateLimitPolicyImpl??wg,I=e.assembleWakeReportImpl??N_,x=e.existsSyncImpl??gL,H=e.statSyncImpl??wL,C=e.config??pe,w=e.escalation??Jl,b=e.autoRedeliver??zl,N=e.wake??Yl,M=e.intervalMs??yL,W=null,ee=!1;async function oe(){if(ee)return EL;ee=!0;try{let J=e.getTeams(),se=J.filter(B),k;try{k=await t(),ag(k,new Date().toISOString())}catch(V){throw cg(V instanceof Error?V.message:String(V),new Date().toISOString()),V}let O=Date.now(),$=r(n,o,void 0,V=>{e.onError?.(V)}),q=Ks(e.db,se,k),{stalled:U,continueEligible:Z}=await cp(e.db,se,k,$,C,O);if(e.miniplayerVerify)try{await _(e.db,U,se,e.miniplayerVerify)}catch(V){e.onError?.(V)}let G=new Set(U);for(let V of se)!G.has(V.name)&&ie(e.db,V.name)?.miniplayer_verdict_label&&Em(e.db,V.name);if(e.hungHolderCheck)try{let V=e.maintainerWake?.sessionAlivePath!==void 0||e.maintainerWake?.activityFreshnessMs!==void 0?{sessionAliveExemptTeamName:e.maintainerWake.teamName,sessionAliveExemptPath:e.maintainerWake.sessionAlivePath,sessionAliveFreshnessMs:e.maintainerWake.sessionAliveFreshnessMs,activityFreshnessMs:e.maintainerWake.activityFreshnessMs}:{};await E(e.db,se,{...V,...e.hungHolderCheck})}catch(V){e.onError?.(V)}if(e.orphanReconciler)try{let V=e.maintainerWake?.sessionAlivePath!==void 0||e.maintainerWake?.activityFreshnessMs!==void 0?{sessionAliveExemptTeamName:e.maintainerWake.teamName,sessionAliveExemptPath:e.maintainerWake.sessionAlivePath,sessionAliveFreshnessMs:e.maintainerWake.sessionAliveFreshnessMs,activityFreshnessMs:e.maintainerWake.activityFreshnessMs}:{};await S(e.db,J,k,{...V,...e.orphanReconciler})}catch(V){e.onError?.(V)}if(e.hangProbeCollect)try{T(e.db,e.hangProbeCollect)}catch(V){e.onError?.(V)}if(e.autoNudgeRedirectReview)try{let V=e.findDueAutoNudgeReviewsImpl??th,ye=new Map(se.map(rt=>[rt.name,rt.repoPath])),at=new Map(se.map(rt=>[rt.name,rt])),tt=await V(e.db,ye,O),gt=e.buildReviewMessageImpl??nh,ze=e.resetShiftImpl??rh,yn=e.enqueueImpl??we,br=e.checkProviderDisabledImpl??ot,cr=e.resolveMemberProviderImpl??Gt;for(let rt of tt)try{let Tr=ye.get(rt.team);if(Tr===void 0)continue;let $o=at.get(rt.team),Ds=$o===void 0?null:cr($o,$o.leadAlias);if(Ds!==null&&br(e.db,Ds,O).disabled)continue;let za=await gt(rt,Tr);yn(e.db,J,rt.team,za,{from:"autopilot"}),await ze(e.db,rt.team,Tr,new Date(O).toISOString())}catch(Tr){e.onError?.(Tr)}}catch(V){e.onError?.(V)}if(e.epicReview)try{await y(e.db,J,e.epicReview)}catch(V){e.onError?.(V)}let ae=!1;if(e.maintainerWake)try{let V={cooldownMs:C.cooldownMs,...e.maintainerWake};if(V.sessionAlivePath!==void 0){let ye=qn(V.sessionAlivePath,V.sessionAliveFreshnessMs,V.activityFreshnessMs!==void 0?ie(e.db,V.teamName)?.last_cli_activity_ts??null:null,V.activityFreshnessMs,{existsSyncImpl:x,statSyncImpl:H,nowMs:O}),at,tt;try{let ze=await I(e.db,J,V.teamName,{nowMs:O,config:C,fetchReportImpl:async()=>k,heavyLockImpl:()=>$,...V.maintainerStaleThresholdMs!==void 0?{maintainerStaleThresholdMs:V.maintainerStaleThresholdMs}:{}});at=ze.rendered,tt=ze.isEmpty}catch(ze){e.onError?.(ze),at="wake-report assembly failed this tick -- waking conservatively; check server logs for the error.",tt=!1}let gt=ze=>`${_L(ze,"utf8")}
475
475
 
476
476
  ---
477
- ${at}`;ae=s(e.db,se,k,G,gt,O,ye?void 0:!tt)}else ae=s(e.db,se,k,G,void 0,O)}catch(G){e.onError?.(G)}let be=[];if(e.autoContinue&&Dr(e.db)===null)try{be=await i(e.db,se,k,{config:C,...e.autoContinue,nowMs:O,stalledTeamNames:Z,heavyLockStatusPath:n,heavyLockPath:o,readHeavyLockStatusImpl:r})}catch(G){e.onError?.(G)}let ne=[];if(e.maintainerWake)try{ne=await a(e.db,M,e.maintainerWake.teamName,V,C,O)}catch(G){e.onError?.(G)}let D=[];if(e.maintainerWake)try{D=await c(e.db,se,e.maintainerWake.teamName,V,C,O)}catch(G){e.onError?.(G)}let j=[];if(e.maintainerWake)try{j=await l(e.db,se,e.maintainerWake.teamName,V,C)}catch(G){e.onError?.(G)}let K=[];if(e.maintainerWake)try{K=await d(e.db,se,e.maintainerWake.teamName,V,C,O)}catch(G){e.onError?.(G)}let z=[];if(e.maintainerWake)try{z=await m(e.db,se,e.maintainerWake.teamName,V,C,O)}catch(G){e.onError?.(G)}let re=[];if(e.maintainerWake)try{re=await u(e.db,se,e.maintainerWake.teamName,V,C,O)}catch(G){e.onError?.(G)}let te=[];try{te=await g(e.db,V,O,{onJobError:(G,ye)=>e.onError?.(ye)})}catch(G){e.onError?.(G)}let ue=[];try{ue=await f(e.db,se,w,O)}catch(G){e.onError?.(G)}let xe=[];try{xe=p(e.db,se,b,O)}catch(G){e.onError?.(G)}let Se=[];try{Se=h(e.db,se,k,N,O)}catch(G){e.onError?.(G)}let Y=null,Te=[],Je=e.rateLimitPolicy??e.rateLimitAutomation,Be=e.rateLimitCollect??Je;if(Be!==void 0){let G=Date.now();try{Y=await R(e.db,{nowMs:G,...Be})}catch(ye){e.onError?.(ye)}try{Te=A(e.db,{nowMs:G,...Je,dryRun:Je===void 0})}catch(ye){e.onError?.(ye)}}let Pt={watch:q,stalled:M,maintainerWoken:ae,autoContinued:be,surfacedUnknown:ne,surfacedBlocked:D,surfacedDoneConsistency:j,surfacedUnresolvableTeamfiles:re,surfacedFault:K,surfacedClosedEpics:z,escalated:ue,autoRedelivered:xe,woken:Se,firedCronJobs:te,rateLimitCollected:Y,rateLimitPolicyEvaluations:Te};return e.onTick?.(Pt),Pt}catch(V){throw e.onError?.(V),V}finally{ee=!1}}return{start(){J||(J=setInterval(()=>{oe().catch(()=>{})},P),J.unref())},stop(){J&&(clearInterval(J),J=null)},runTickNow:oe,isRunning:()=>J!==null,isTicking:()=>ee}}import{closeSync as bL,linkSync as TL,openSync as SL,readdirSync as vL,readFileSync as ga,readlinkSync as AL,realpathSync as $L,renameSync as L_,unlinkSync as mu,writeSync as kL}from"node:fs";import{dirname as xL,join as RL}from"node:path";var Qn=class extends Error{holder;lockPath;constructor(t,r){super(`site lock held by "${t.ownerLabel}" (pid ${t.pid}, started ${t.startedAt}) at ${r} -- only one process (standalone \`lmauto serve\` or \`lmt site start\`) may run lmauto's scheduler against this DB at a time`),this.holder=t,this.lockPath=r,this.name="SiteLockHeldError"}};function us(e){return e===":memory:"?null:`${e}.lock`}function M_(e){let t=ds(e);return t.kind==="held"?t.identity:null}function C_(e){let t;try{t=ga(e,"utf8")}catch(o){return o.code==="ENOENT"?{kind:"free"}:{kind:"unknown"}}let r=wc(t);if(!r)return{kind:"unknown"};let n={...r,bootId:r.bootId??null};return du(n)?{kind:"held",identity:n}:{kind:"free"}}function NL(e,t){let r;try{r=$L(t)}catch{return!1}let n;try{n=vL(`/proc/${e}/fd`)}catch{return!1}for(let o of n)try{if(AL(`/proc/${e}/fd/${o}`)===r)return!0}catch{}return!1}function ds(e){let t=us(e);if(t===null)return{kind:"free"};let r=C_(t);if(r.kind==="held")return r;let n=RL(xL(e),"site.lock");if(n===t)return r;let o=C_(n);return o.kind==="held"&&NL(o.identity.pid,e)?o:r}function ha(e){try{let t=wc(ga(e,"utf8"));return t?{...t,bootId:t.bootId??null}:null}catch{return null}}function P_(){try{let e=ga("/proc/sys/kernel/random/boot_id","utf8").trim();return yc(e)?e:null}catch{return null}}function U_(e){try{let t=ga(`/proc/${e}/stat`,"utf8"),o=t.slice(t.lastIndexOf(")")+2).trim().split(/\s+/)[19];if(o===void 0)return null;let s=Number(o);return Number.isFinite(s)?s:null}catch{return null}}function du(e){let t;try{process.kill(e.pid,0),t=!0}catch(n){t=n.code==="EPERM"}if(!t)return!1;if(e.bootId!==null){let n=P_();if(n!==null&&n!==e.bootId)return!1}if(e.pidStartTicks===null)return!0;let r=U_(e.pid);return r===null?!0:r===e.pidStartTicks}function O_(e,t){let r=`${e}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`,n=SL(r,"wx");try{kL(n,JSON.stringify(t))}finally{bL(n)}try{return TL(r,e),!0}catch(o){if(o.code!=="EEXIST")throw o;return!1}finally{mu(r)}}function _a(e,t){let r={pid:process.pid,ownerLabel:t,startedAt:new Date().toISOString(),pidStartTicks:U_(process.pid),bootId:P_()};if(O_(e,r))return D_(e,r);let n=ha(e);if(n!==null&&du(n))throw new Qn(n,e);let o=`${e}.reclaim.${process.pid}.${Math.random().toString(36).slice(2)}`,s=!1;try{L_(e,o);let a=ha(o);n===null&&a===null||n!==null&&a!==null&&a.pid===n.pid&&a.startedAt===n.startedAt?(mu(o),s=!0):L_(o,e)}catch{}if(s&&O_(e,r))return D_(e,r);let i=ha(e);throw i!==null&&du(i)?new Qn(i,e):new Error(`failed to acquire site lock at ${e} (lost a reclaim race)`)}function D_(e,t){let r=!1;return{release(){if(!r){r=!0;try{let n=ha(e);n!==null&&n.pid===t.pid&&n.startedAt===t.startedAt&&mu(e)}catch{}}}}}import{closeSync as fu,existsSync as IL,fstatSync as LL,mkdirSync as CL,openSync as F_,readFileSync as q_,renameSync as OL,unlinkSync as DL,writeSync as ML}from"node:fs";import{dirname as j_,join as PL}from"node:path";import{createHash as UL,randomBytes as FL}from"node:crypto";var qL=32;function Xn(e){return e===":memory:"?null:PL(j_(e),"localweb-passcode")}function jL(){return FL(qL).toString("base64url")}function pu(e,t){let r=j_(e);IL(r)||CL(r,{recursive:!0});let n=`${e}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`,o;try{o=F_(n,"wx",384);let s=Buffer.from(t,"utf8"),i=0;for(;i<s.length;){let a=ML(o,s,i,s.length-i);if(a<=0)throw new Error("passcode file write made no progress");i+=a}fu(o),o=void 0,OL(n,e)}catch(s){if(o!==void 0)try{fu(o)}catch{}try{DL(n)}catch{}throw s}}function H_(e){let t;try{t=F_(e,"r")}catch(r){if(r.code==="ENOENT")return null;throw r}try{let r=LL(t,{bigint:!0}),n=q_(t,"utf8"),o=UL("sha256").update(`${r.dev}:${r.ino}:${r.ctimeNs}:${r.mtimeNs}:${r.size}:`).update(n,"utf8").digest("base64url");return{passcode:n,generation:o}}finally{fu(t)}}function B_(e){try{return q_(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}function wa(e){let t=jL();return pu(e,t),t}import{randomUUID as HL}from"node:crypto";function hu(e){return`remote:${e.from.team?`${e.from.site}:${e.from.team}:${e.from.alias}`:`${e.from.site}:${e.from.alias}`}`}function W_(e,t,r){let n=t.find(o=>o.name===r.to.team);if(!n)throw new Error(`no local team registered for remote envelope's to.team "${r.to.team}"`);if(!B(n))throw new Error(`remote envelope addressed to "${r.to.team}", which is itself a remote (channel=lmmail) team -- not locally dispatchable`);we(e,t,n.name,r.payload,{from:hu(r),dedupeKey:r.msgId})}var BL=new Set(["dispatched","queued","failed"]);function WL(e){let t;try{t=JSON.parse(e)}catch{return!1}if(typeof t!="object"||t===null||Array.isArray(t))return!1;let r=t.state;return typeof r=="string"&&BL.has(r)}var GL="reply-surfaced:";function VL(e,t,r,n){let o=r.inReplyTo;if(!o)throw new Error("recordReplyOrAck: envelope has no in_reply_to");let s=Nf(e,o);if(!s)return"orphan";if(WL(r.payload))return If(e,o,n),"acked";Lf(e,o,n);let i=t.find(a=>B(a)&&a.name===s.from_alias);if(i)try{we(e,t,i.name,r.payload,{from:hu(r),dedupeKey:`${GL}${r.msgId}`})}catch(a){process.stderr.write(`[mail] failed to surface reply to ${i.name}'s inbox (in_reply_to ${o}): ${a instanceof Error?a.message:String(a)}
477
+ ${at}`;ae=s(e.db,se,k,V,gt,O,ye?void 0:!tt)}else ae=s(e.db,se,k,V,void 0,O)}catch(V){e.onError?.(V)}let be=[];if(e.autoContinue&&Dr(e.db)===null)try{be=await i(e.db,se,k,{config:C,...e.autoContinue,nowMs:O,stalledTeamNames:Z,heavyLockStatusPath:n,heavyLockPath:o,readHeavyLockStatusImpl:r})}catch(V){e.onError?.(V)}let ne=[];if(e.maintainerWake)try{ne=await a(e.db,U,e.maintainerWake.teamName,J,C,O)}catch(V){e.onError?.(V)}let D=[];if(e.maintainerWake)try{D=await c(e.db,se,e.maintainerWake.teamName,J,C,O)}catch(V){e.onError?.(V)}let j=[];if(e.maintainerWake)try{j=await l(e.db,se,e.maintainerWake.teamName,J,C)}catch(V){e.onError?.(V)}let K=[];if(e.maintainerWake)try{K=await d(e.db,se,e.maintainerWake.teamName,J,C,O)}catch(V){e.onError?.(V)}let z=[];if(e.maintainerWake)try{z=await m(e.db,se,e.maintainerWake.teamName,J,C,O)}catch(V){e.onError?.(V)}let re=[];if(e.maintainerWake)try{re=await u(e.db,se,e.maintainerWake.teamName,J,C,O)}catch(V){e.onError?.(V)}let te=[];try{te=await g(e.db,J,O,{onJobError:(V,ye)=>e.onError?.(ye)})}catch(V){e.onError?.(V)}let ue=[];try{ue=await f(e.db,se,w,O)}catch(V){e.onError?.(V)}let xe=[];try{xe=p(e.db,se,b,O)}catch(V){e.onError?.(V)}let Se=[];try{Se=h(e.db,se,k,N,O)}catch(V){e.onError?.(V)}let Y=null,Te=[],Je=e.rateLimitPolicy??e.rateLimitAutomation,Be=e.rateLimitCollect??Je;if(Be!==void 0){let V=Date.now();try{Y=await R(e.db,{nowMs:V,...Be})}catch(ye){e.onError?.(ye)}try{Te=A(e.db,{nowMs:V,...Je,dryRun:Je===void 0})}catch(ye){e.onError?.(ye)}}let Pt={watch:q,stalled:U,maintainerWoken:ae,autoContinued:be,surfacedUnknown:ne,surfacedBlocked:D,surfacedDoneConsistency:j,surfacedUnresolvableTeamfiles:re,surfacedFault:K,surfacedClosedEpics:z,escalated:ue,autoRedelivered:xe,woken:Se,firedCronJobs:te,rateLimitCollected:Y,rateLimitPolicyEvaluations:Te};return e.onTick?.(Pt),Pt}catch(J){throw e.onError?.(J),J}finally{ee=!1}}return{start(){W||(W=setInterval(()=>{oe().catch(()=>{})},M),W.unref())},stop(){W&&(clearInterval(W),W=null)},runTickNow:oe,isRunning:()=>W!==null,isTicking:()=>ee}}import{closeSync as bL,linkSync as TL,openSync as SL,readdirSync as vL,readFileSync as ga,readlinkSync as AL,realpathSync as $L,renameSync as L_,unlinkSync as mu,writeSync as kL}from"node:fs";import{dirname as xL,join as RL}from"node:path";var Qn=class extends Error{holder;lockPath;constructor(t,r){super(`site lock held by "${t.ownerLabel}" (pid ${t.pid}, started ${t.startedAt}) at ${r} -- only one process (standalone \`lmauto serve\` or \`lmt site start\`) may run lmauto's scheduler against this DB at a time`),this.holder=t,this.lockPath=r,this.name="SiteLockHeldError"}};function us(e){return e===":memory:"?null:`${e}.lock`}function M_(e){let t=ds(e);return t.kind==="held"?t.identity:null}function C_(e){let t;try{t=ga(e,"utf8")}catch(o){return o.code==="ENOENT"?{kind:"free"}:{kind:"unknown"}}let r=wc(t);if(!r)return{kind:"unknown"};let n={...r,bootId:r.bootId??null};return du(n)?{kind:"held",identity:n}:{kind:"free"}}function NL(e,t){let r;try{r=$L(t)}catch{return!1}let n;try{n=vL(`/proc/${e}/fd`)}catch{return!1}for(let o of n)try{if(AL(`/proc/${e}/fd/${o}`)===r)return!0}catch{}return!1}function ds(e){let t=us(e);if(t===null)return{kind:"free"};let r=C_(t);if(r.kind==="held")return r;let n=RL(xL(e),"site.lock");if(n===t)return r;let o=C_(n);return o.kind==="held"&&NL(o.identity.pid,e)?o:r}function ha(e){try{let t=wc(ga(e,"utf8"));return t?{...t,bootId:t.bootId??null}:null}catch{return null}}function P_(){try{let e=ga("/proc/sys/kernel/random/boot_id","utf8").trim();return yc(e)?e:null}catch{return null}}function U_(e){try{let t=ga(`/proc/${e}/stat`,"utf8"),o=t.slice(t.lastIndexOf(")")+2).trim().split(/\s+/)[19];if(o===void 0)return null;let s=Number(o);return Number.isFinite(s)?s:null}catch{return null}}function du(e){let t;try{process.kill(e.pid,0),t=!0}catch(n){t=n.code==="EPERM"}if(!t)return!1;if(e.bootId!==null){let n=P_();if(n!==null&&n!==e.bootId)return!1}if(e.pidStartTicks===null)return!0;let r=U_(e.pid);return r===null?!0:r===e.pidStartTicks}function O_(e,t){let r=`${e}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`,n=SL(r,"wx");try{kL(n,JSON.stringify(t))}finally{bL(n)}try{return TL(r,e),!0}catch(o){if(o.code!=="EEXIST")throw o;return!1}finally{mu(r)}}function _a(e,t){let r={pid:process.pid,ownerLabel:t,startedAt:new Date().toISOString(),pidStartTicks:U_(process.pid),bootId:P_()};if(O_(e,r))return D_(e,r);let n=ha(e);if(n!==null&&du(n))throw new Qn(n,e);let o=`${e}.reclaim.${process.pid}.${Math.random().toString(36).slice(2)}`,s=!1;try{L_(e,o);let a=ha(o);n===null&&a===null||n!==null&&a!==null&&a.pid===n.pid&&a.startedAt===n.startedAt?(mu(o),s=!0):L_(o,e)}catch{}if(s&&O_(e,r))return D_(e,r);let i=ha(e);throw i!==null&&du(i)?new Qn(i,e):new Error(`failed to acquire site lock at ${e} (lost a reclaim race)`)}function D_(e,t){let r=!1;return{release(){if(!r){r=!0;try{let n=ha(e);n!==null&&n.pid===t.pid&&n.startedAt===t.startedAt&&mu(e)}catch{}}}}}import{closeSync as fu,existsSync as IL,fstatSync as LL,mkdirSync as CL,openSync as F_,readFileSync as q_,renameSync as OL,unlinkSync as DL,writeSync as ML}from"node:fs";import{dirname as j_,join as PL}from"node:path";import{createHash as UL,randomBytes as FL}from"node:crypto";var qL=32;function Xn(e){return e===":memory:"?null:PL(j_(e),"localweb-passcode")}function jL(){return FL(qL).toString("base64url")}function pu(e,t){let r=j_(e);IL(r)||CL(r,{recursive:!0});let n=`${e}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`,o;try{o=F_(n,"wx",384);let s=Buffer.from(t,"utf8"),i=0;for(;i<s.length;){let a=ML(o,s,i,s.length-i);if(a<=0)throw new Error("passcode file write made no progress");i+=a}fu(o),o=void 0,OL(n,e)}catch(s){if(o!==void 0)try{fu(o)}catch{}try{DL(n)}catch{}throw s}}function H_(e){let t;try{t=F_(e,"r")}catch(r){if(r.code==="ENOENT")return null;throw r}try{let r=LL(t,{bigint:!0}),n=q_(t,"utf8"),o=UL("sha256").update(`${r.dev}:${r.ino}:${r.ctimeNs}:${r.mtimeNs}:${r.size}:`).update(n,"utf8").digest("base64url");return{passcode:n,generation:o}}finally{fu(t)}}function B_(e){try{return q_(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}function wa(e){let t=jL();return pu(e,t),t}import{randomUUID as HL}from"node:crypto";function hu(e){return`remote:${e.from.team?`${e.from.site}:${e.from.team}:${e.from.alias}`:`${e.from.site}:${e.from.alias}`}`}function W_(e,t,r){let n=t.find(o=>o.name===r.to.team);if(!n)throw new Error(`no local team registered for remote envelope's to.team "${r.to.team}"`);if(!B(n))throw new Error(`remote envelope addressed to "${r.to.team}", which is itself a remote (channel=lmmail) team -- not locally dispatchable`);we(e,t,n.name,r.payload,{from:hu(r),dedupeKey:r.msgId})}var BL=new Set(["dispatched","queued","failed"]);function WL(e){let t;try{t=JSON.parse(e)}catch{return!1}if(typeof t!="object"||t===null||Array.isArray(t))return!1;let r=t.state;return typeof r=="string"&&BL.has(r)}var GL="reply-surfaced:";function VL(e,t,r,n){let o=r.inReplyTo;if(!o)throw new Error("recordReplyOrAck: envelope has no in_reply_to");let s=Nf(e,o);if(!s)return"orphan";if(WL(r.payload))return If(e,o,n),"acked";Lf(e,o,n);let i=t.find(a=>B(a)&&a.name===s.from_alias);if(i)try{we(e,t,i.name,r.payload,{from:hu(r),dedupeKey:`${GL}${r.msgId}`})}catch(a){process.stderr.write(`[mail] failed to surface reply to ${i.name}'s inbox (in_reply_to ${o}): ${a instanceof Error?a.message:String(a)}
478
478
  `)}return"replied"}function JL(e,t,r,n,o){let s=e.now??(()=>new Date().toISOString()),i={v:1,msgId:HL(),to:t,from:{site:e.localSiteId,team:"",alias:"lmauto"},sentAt:s(),payload:JSON.stringify({state:n,...o?{note:o}:{}}),inReplyTo:r},a=tn(t.site),c=new TextEncoder().encode(Lo(i));e.client.sendMessage({mailbox:a,subject:`lmauto ack ${i.msgId}`,body:{name:"body.txt",contentType:"text/plain; charset=utf-8",bytes:c}}).catch(l=>{process.stderr.write(`[mail] failed to send ack to mailbox ${a} (in_reply_to ${r}): ${l instanceof Error?l.message:String(l)}
479
479
  `)})}function G_(e,t,r,n){if(r.inReplyTo){VL(e,t,r,(n.now??(()=>new Date().toISOString()))());return}let o;try{W_(e,t,r)}catch(i){o=i}let s=n.now??(()=>new Date().toISOString());if(kf(e,r.msgId,s())){let i=o?(o instanceof Error?o.message:String(o)).slice(0,500):void 0;JL(n,r.from,r.msgId,o?"failed":"dispatched",i)}if(o)throw o}var Y_=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,zL=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,YL="text/plain; charset=utf-8",gu="exec",K_="exec-result";var KL="exec-result";var QL=`
480
480
  ... [lmexec output truncated; middle elided, see attachment] ...
481
481
  `;function Q_(e){return _u(tw(e))}function X_(e){return Z_(tw(e))}function _u(e){let t=rw(e),r=nw(t.type,"type",gu),n=ow(t.id,"id"),o=yu(t.command,"command"),s=rC(t.timeout_s,"timeout_s"),i=tC(t.reply_to,"reply_to"),a=ZL(t.from,"from");return{v:1,type:r,id:n,command:o,timeout_s:s,reply_to:i,...a===void 0?{}:{from:a}}}function Z_(e){let t=rw(e),r=XL(t.v),n=nw(t.type,"type",K_),o=ow(t.id,"id"),s=oC(t.exit_code,"exit_code"),i=J_(t.stdout,"stdout"),a=J_(t.stderr,"stderr"),c=nC(t.duration_ms,"duration_ms"),l=z_(t.timed_out,"timed_out"),u=z_(t.truncated,"truncated");if(l&&s!==null)throw new Error("invalid exec result: exit_code must be null when timed_out is true");if(!l&&s===null)throw new Error("invalid exec result: exit_code must be a number when timed_out is false");let d={type:n,id:o,exit_code:s,stdout:i,stderr:a,duration_ms:c,timed_out:l,truncated:u};if(r===1)return{v:r,...d};let m=eC(t.sender_trust),f=yu(t.sender,"sender");return{v:r,...d,sender_trust:m,sender:f}}function wu(e){if(!Y_.test(e))throw new Error(`invalid exec id: ${e}`);return`${KL} ${e}`}function V_(e,t,r){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),o=r?.capBytes??49152,s=r?.marker??QL;if(!Number.isInteger(o)||o<1)throw new Error("inline cap must be a positive integer");if(n.byteLength<=o)return{inline:n.toString("utf8"),truncated:!1};let i=Buffer.byteLength(s,"utf8");if(i>=o)throw new Error("elision marker must be smaller than the inline cap");let a=n.toString("utf8"),c=o-i,l=Math.ceil(c/2),u=Math.floor(c/2);return{inline:`${sC(a,l)}${s}${iC(a,u)}`,truncated:!0,attachment:{name:e==="stdout"?"stdout.txt":"stderr.txt",content_type:YL,data:n}}}function ew(e,t){let r=V_("stdout",e.stdout,t),n=V_("stderr",e.stderr,t),o=Z_({v:2,type:K_,id:e.id,exit_code:e.exit_code,stdout:r.inline,stderr:n.inline,duration_ms:e.duration_ms,timed_out:e.timed_out,truncated:r.truncated||n.truncated,sender_trust:e.sender_trust,sender:e.sender});return{subject:wu(e.id),envelope:o,attachments:[r.attachment,n.attachment].filter(s=>s!==void 0)}}function tw(e){try{return JSON.parse(e)}catch(t){throw new Error(`invalid JSON: ${aC(t)}`)}}function rw(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("expected object");return e}function nw(e,t,r){if(e!==r)throw new Error(`invalid ${t}: expected ${r}`);return r}function XL(e){if(e===void 0||e===1)return 1;if(e===2)return 2;throw new Error("invalid v: expected 1 or 2")}function ow(e,t){if(typeof e!="string"||!Y_.test(e))throw new Error(`invalid ${t}: expected UUID v4`);return e}function yu(e,t){if(typeof e!="string"||e.trim().length===0)throw new Error(`invalid ${t}: expected non-empty string`);return e}function ZL(e,t){if(e!==void 0)return yu(e,t)}function eC(e){if(e==="admin"||e==="registered"||e==="anonymous")return e;throw new Error("invalid sender_trust: expected admin, registered, or anonymous")}function tC(e,t){if(typeof e!="string"||e.includes("/")||e.includes("\\")||e.includes("..")||e.endsWith(".")||/[\u0000-\u001f\u007f]/.test(e)||!zL.test(e))throw new Error(`invalid ${t}: expected mailbox name`);return e}function J_(e,t){if(typeof e!="string")throw new Error(`invalid ${t}: expected string`);return e}function rC(e,t){if(typeof e!="number"||!Number.isSafeInteger(e)||e<1)throw new Error(`invalid ${t}: expected positive integer`);return e}function nC(e,t){if(typeof e!="number"||!Number.isSafeInteger(e)||e<0)throw new Error(`invalid ${t}: expected non-negative integer`);return e}function oC(e,t){if(e===null)return null;if(typeof e!="number"||!Number.isSafeInteger(e)||e<0)throw new Error(`invalid ${t}: expected non-negative integer or null`);return e}function z_(e,t){if(typeof e!="boolean")throw new Error(`invalid ${t}: expected boolean`);return e}function sC(e,t){if(t<=0||e.length===0)return"";let r=0,n="";for(let o of e){let s=Buffer.byteLength(o,"utf8");if(r+s>t)break;n+=o,r+=s}return n}function iC(e,t){if(t<=0||e.length===0)return"";let r=0,n=[],o=Array.from(e);for(let s=o.length-1;s>=0;s-=1){let i=o[s],a=Buffer.byteLength(i,"utf8");if(r+a>t)break;n.push(i),r+=a}return n.reverse().join("")}function aC(e){return e instanceof Error&&e.message?e.message:String(e)}var cC=/[;&|`$<>(){}\\]/,sw=/[\x00-\x1f\x7f]/;function aw(e){let t=[],r=0,n=e.length;for(;r<n;){for(;r<n&&e[r]===" ";)r+=1;if(r>=n)break;let o;if(e[r]==='"'||e[r]==="'"){let s=e[r];r+=1,o="";let i=r;for(;;){for(;r<n&&e[r]!==s;){if(sw.test(e[r])||s==="'"&&e[r]==="\\")return null;r+=1}if(r>=n)return null;if(o+=e.slice(i,r),s==="'"&&e[r+1]==="\\"&&e[r+2]==="'"&&e[r+3]==="'"){o+="'",r+=4,i=r;continue}r+=1;break}if(r<n&&e[r]!==" ")return null}else{let s=r;for(;r<n&&e[r]!==" ";){if(sw.test(e[r])||cC.test(e[r]))return null;r+=1}if(o=e.slice(s,r),o.includes('"')||o.includes("'"))return null}t.push(o)}return t.length>0?t:null}function Eu(e){if(!e.includes("--json"))return"requires --json when run via exec (plain-text output has no machine-readable contract)"}function lC(e){return e.includes("--watch")?"tail --watch is a long-running stream, not a fit for a single bounded exec call":e.includes("--lines")?Eu(e):"tail requires --lines N when run via exec (unbounded --max-bytes/no-limit output is not allowed)"}var uC=[{prefix:["lmbee","status"]},{prefix:["lmbee","teams"]},{prefix:["lmbee","queue","list"]},{prefix:["lmbee","queue","get"]},{prefix:["lmbee","queue","inbox"]},{prefix:["lmbee","history"]},{prefix:["lmbee","state","list"]},{prefix:["lmbee","state","get"]},{prefix:["lmbee","state","active"]},{prefix:["lmbee","source","list"]},{prefix:["lmctl","health"],validate:Eu},{prefix:["lmctl","running"],validate:Eu},{prefix:["lmctl","tail"],validate:lC}],dC=[{prefix:["lmbee","enqueue"]},{prefix:["lmbee","send"]},{prefix:["lmbee","nudge"]},{prefix:["lmbee","state","set"]},{prefix:["lmbee","queue","deliver"]},{prefix:["lmbee","queue","retrieve"]},{prefix:["lmbee","queue","gc"]},{prefix:["lmbee","source","add"]},{prefix:["lmbee","source","remove"]}];function mC(e,t){return e.length<t.prefix.length?!1:t.prefix.every((r,n)=>e[n]===r)}function iw(e,t){return t.find(r=>mC(e,r))}function cw(e,t){let r=iw(e,uC);if(r){let o=r.validate?.(e);return o?{allowed:!1,code:"command_not_allowed",message:o}:{allowed:!0}}let n=iw(e,dC);if(n){let o=n.validate?.(e);return o?{allowed:!1,code:"command_not_allowed",message:o}:t!=="admin"?{allowed:!1,code:"insufficient_trust",message:`write command requires the operator (admin) trust tier; sender is ${t}`}:{allowed:!0}}return{allowed:!1,code:"command_not_allowed",message:`command is not exec-able from the web: ${e.join(" ")}`}}import{spawn as lw}from"node:child_process";var fC=5e3,pC="/bin/sh";function uw(e){if(!Number.isInteger(e.timeoutMs)||e.timeoutMs<1)throw new Error("timeoutMs must be a positive integer");let t=e.killGraceMs??fC;if(!Number.isInteger(t)||t<0)throw new Error("killGraceMs must be a non-negative integer");return{killGraceMs:t,now:e.now??Date.now}}function dw(e,t,r,n){return new Promise((o,s)=>{let i=n(),a=[],c=[],l=!1,u=!1,d,m,f=h=>{u||(u=!0,d&&clearTimeout(d),m&&clearTimeout(m),o(h))},p=h=>{u||(u=!0,d&&clearTimeout(d),m&&clearTimeout(m),s(h))};e.stdout.on("data",h=>{a.push(Buffer.isBuffer(h)?h:Buffer.from(h))}),e.stderr.on("data",h=>{c.push(Buffer.isBuffer(h)?h:Buffer.from(h))}),e.on("error",h=>{p(h)}),e.on("close",h=>{f({exit_code:l?null:typeof h=="number"?h:null,stdout:Buffer.concat(a),stderr:Buffer.concat(c),duration_ms:Math.max(0,Math.round(n()-i)),timed_out:l})}),d=setTimeout(()=>{l=!0,bu(e.pid,"SIGTERM"),r>0?m=setTimeout(()=>{bu(e.pid,"SIGKILL")},r):bu(e.pid,"SIGKILL")},t)})}async function mw(e,t){if(e.trim().length===0)throw new Error("command must be non-empty");let{killGraceMs:r,now:n}=uw(t),o=t.shellPath??pC,s=lw(o,["-c",e],{cwd:t.cwd,env:t.env,detached:!0,stdio:["ignore","pipe","pipe"]});return dw(s,t.timeoutMs,r,n)}async function fw(e,t){if(e.length===0)throw new Error("argv must be non-empty");let{killGraceMs:r,now:n}=uw(t),o=lw(e[0],e.slice(1),{cwd:t.cwd,env:t.env,detached:!0,stdio:["ignore","pipe","pipe"]});return dw(o,t.timeoutMs,r,n)}function bu(e,t){if(e)try{process.kill(-e,t)}catch(r){if(!hC(r))throw r}}function hC(e){return!!e&&typeof e=="object"&&"code"in e&&e.code==="ESRCH"}var pw=1e3,_C=6e4,wC=20,yC=1e3;async function gw(e,t){let r=t.runCommand??mw,n=t.runCommandArgv??fw,o=t.sleep??bC,s=t.pollNow??Date.now,i=t.now??(()=>new Date),a=t.stderr??(d=>process.stderr.write(`${d}
482
482
  `)),c=t.shouldStop??(()=>!1),l=pw,u=!1;for(It(a,i,"info","daemon_started",{mailbox:e.mailbox}),e.allowAnonymous&&It(a,i,"warn","anonymous_execution_enabled",{mailbox:e.mailbox,warning:"REMOTE SHELL OPEN TO EVERY AUTHENTICATED LMMAIL USER"});!c();)try{let d=s(),m=await t.client.listMessages(e.mailbox,{status:"unread",after:0,...e.once?{}:{wait_s:wC}}),f=Math.max(0,s()-d);for(let p of m.messages){if(c())break;let h=EC(e,p.sender);if(h==="anonymous"&&!e.allowAnonymous){await t.client.getMessageMetadata(e.mailbox,p.seq),It(a,i,"warn","message_rejected",{seq:p.seq,sender:p.sender,sender_trust:h,reason:"anonymous_not_allowed"});continue}let g=await t.client.getMessage(e.mailbox,p.seq),_=Buffer.from(await t.client.download(g.body.download_url)).toString("utf8"),E;try{E=Q_(_)}catch(A){It(a,i,"warn","message_rejected",{seq:p.seq,sender:p.sender,sender_trust:h,reason:"malformed_request",error:Tu(A)});continue}let y=e.execAllowlist?aw(E.command):void 0,S=e.execAllowlist?y?cw(y,h):{allowed:!1,code:"malformed_command",message:"command could not be safely tokenized into arguments"}:{allowed:!0};if(!S.allowed){It(a,i,"warn","command_rejected",{id:E.id,sender:p.sender,sender_trust:h,...E.from===void 0?{}:{asserted_from:E.from},code:S.code,seq:p.seq}),await hw(t.client,E.reply_to,{id:E.id,exit_code:126,stdout:"",stderr:JSON.stringify({error:{code:S.code,message:S.message}}),duration_ms:0,timed_out:!1,sender_trust:h,sender:p.sender});continue}It(a,i,"info","command_started",{id:E.id,sender:p.sender,sender_trust:h,...E.from===void 0?{}:{asserted_from:E.from},seq:p.seq});let T;try{T=y?await n(y,{timeoutMs:Math.min(E.timeout_s,e.timeoutCapSeconds)*1e3}):await r(E.command,{timeoutMs:Math.min(E.timeout_s,e.timeoutCapSeconds)*1e3})}catch(A){It(a,i,"error","command_failed",{id:E.id,sender:p.sender,sender_trust:h,...E.from===void 0?{}:{asserted_from:E.from},error:Tu(A)});continue}let R=await hw(t.client,E.reply_to,{id:E.id,...T,sender_trust:h,sender:p.sender});It(a,i,"info","command_finished",{id:E.id,sender:p.sender,sender_trust:h,...E.from===void 0?{}:{asserted_from:E.from},duration_ms:T.duration_ms,exit_code:T.exit_code,timed_out:T.timed_out,truncated:R.envelope.truncated})}if(l=pw,e.once||c())break;m.messages.length===0&&f<yC&&(u||(It(a,i,"warn","long_poll_unsupported",{elapsed_ms:f,fallback_interval_ms:e.pollIntervalMs}),u=!0),await o(e.pollIntervalMs))}catch(d){if(It(a,i,"error","api_error",{error:Tu(d),retry_ms:l}),c())break;await o(l),l=Math.min(l*2,_C)}It(a,i,"info","daemon_stopped",{mailbox:e.mailbox})}function EC(e,t){return e.adminUsers.has(t)?"admin":e.allowUsers.has(t)?"registered":"anonymous"}async function hw(e,t,r){let n=ew(r);return await e.sendMessage({mailbox:t,subject:n.subject,body:{name:"body.txt",contentType:"text/plain; charset=utf-8",bytes:Buffer.from(JSON.stringify(n.envelope),"utf8")},attachments:n.attachments.map(o=>({name:o.name,contentType:o.content_type,bytes:o.data}))}),n}function It(e,t,r,n,o){e(JSON.stringify({ts:t().toISOString(),level:r,event:n,...o}))}function bC(e){return new Promise(t=>setTimeout(t,e))}function Tu(e){return e instanceof Error?e.message:String(e)}var TC=5e3,SC=300;async function _w(e,t){await e.createMailbox(t,{tolerate409:!0})}function ww(e){let t=!1,r=!1,n=Promise.resolve(),o=e.stderr??(c=>process.stderr.write(`${c}
483
- `)),s=e.runDaemonLoopImpl??gw,i={mailbox:e.mailbox,allowUsers:e.allowUsers,adminUsers:e.adminUsers,allowAnonymous:e.allowAnonymous,apiUrl:"",pollIntervalMs:e.pollIntervalMs??TC,timeoutCapSeconds:e.timeoutCapSeconds??SC,once:!1,execAllowlist:!0},a={client:e.client,shouldStop:()=>t,stderr:o};return{start(){r||t||(r=!0,n=s(i,a).catch(c=>{o(`[exec-worker] unexpected top-level failure, worker stopped: ${c instanceof Error?c.message:String(c)}`)}))},stop(){t=!0},isRunning:()=>r&&!t,whenIdle:()=>n}}var vC=64*1024;function yw(e){return{v:1,msgId:e.msg_id,to:{site:e.to_site,team:e.to_team,alias:e.to_alias},from:{site:e.from_site,team:e.from_team,alias:e.from_alias},sentAt:e.sent_at,payload:e.payload}}async function Su(e,t,r,n,o,s){if(r.to.site!==t.localSiteId){xn(e,r.msgId,`${rn}addressed to a different site: ${r.to.site}`,o()),s.rejected++;return}if(!t.allowlist.includes(n)){xn(e,r.msgId,`sender not allowlisted: ${n}`,o()),s.rejected++;return}try{await t.dispatch(r,n),Sf(e,r.msgId,o()),s.dispatched++}catch(i){xn(e,r.msgId,i instanceof Error?i.message:String(i),o()),s.failed++}}async function Ew(e,t,r,n){let o=n.now??(()=>new Date().toISOString()),s=n.maxBodyBytes??vC,i={recovered:0,retriedFailed:0,listed:0,recorded:0,dispatched:0,rejected:0,failed:0,stoppedEarly:!1};for(let d of bf(e))i.recovered++,await Su(e,n,yw(d),d.sender_user_id,o,i);let a=n.retryPolicy??Nc;for(let d of ri(e,o(),a))$f(e,d.msg_id)&&(i.retriedFailed++,await Su(e,n,yw(d),d.sender_user_id,o,i));let c=Tf(e)??0,{messages:l}=await t.listMessages(r,{after:c});i.listed=l.length;let u=[...l].sort((d,m)=>d.seq-m.seq);for(let d of u){let m;try{m=await t.getMessage(r,d.seq)}catch{i.stoppedEarly=!0;break}if(m.body.size>s){i.stoppedEarly=!0;break}let f;try{f=await t.download(m.body.download_url)}catch{i.stoppedEarly=!0;break}let p;try{p=yf(Buffer.from(f).toString("utf8"))}catch{i.stoppedEarly=!0;break}let h=o(),g=Ef(e,{msgId:p.msgId,seq:d.seq,to:p.to,from:p.from,senderUserId:m.sender,sentAt:p.sentAt,payload:p.payload},h);if(g!=="duplicate"){if(g==="conflict"){i.rejected++;continue}i.recorded++,await Su(e,n,p,m.sender,o,i)}}return i}async function bw(e,t){await e.createMailbox(t,{tolerate409:!0})}var AC=6e4,$C={recovered:0,retriedFailed:0,listed:0,recorded:0,dispatched:0,rejected:0,failed:0,stoppedEarly:!1};function Tw(e){let t=e.intervalMs??AC,r=null,n=!1;async function o(){if(n)return $C;n=!0;try{let s=await Ew(e.db,e.client,e.mailbox,e.worker);return e.onPoll?.(s),s}catch(s){throw e.onError?.(s),s}finally{n=!1}}return{start(){r||(r=setInterval(()=>{o().catch(()=>{})},t),r.unref())},stop(){r&&(clearInterval(r),r=null)},pollNow:o,isRunning:()=>r!==null,isPolling:()=>n}}var kC=5e3;function Sw(e){let t=e.intervalMs??kC,r=e.fetchReport??ke,n=e.deliverImpl??Ar,o=null,s=!1;async function i(){if(s)return 0;s=!0;try{let a=e.getTeams(),c=await r(),l=n(e.db,{teams:a,report:c,...e.remoteMail?{remoteMail:e.remoteMail}:{},...e.minMemoryPercent!==void 0?{minMemoryPercent:e.minMemoryPercent}:{}});return e.onDeliver?.(l),l}catch(a){throw e.onError?.(a),a}finally{s=!1}}return{start(){o||(o=setInterval(()=>{i().catch(()=>{})},t),o.unref())},stop(){o&&(clearInterval(o),o=null)},deliverNow:i,isRunning:()=>o!==null,isDelivering:()=>s}}import{isAbsolute as vw,resolve as Aw}from"node:path";import{randomUUID as xC}from"node:crypto";function RC(e){return`'${e.replaceAll("'","'\\''")}'`}async function $w(e,t,r,n){if(!vw(n.db)||Aw(n.db)!==Aw(t))throw new Error("db must select the running daemon database");let o=n.conversationId?.trim()||xC();if(n.localScope.trim()==="")throw new Error("local_scope is required");if(!vw(n.script))throw new Error("script must be an absolute path");if(!n.args.every(c=>typeof c=="string"))throw new Error("args must be strings");let s=[process.env.LMSCRIPT_BIN||"lmscript",n.script,n.db,n.localScope,o,...n.args].map(RC).join(" "),i=Vn(e,{title:`on-demand conversation ${o}`,scheduleExpr:"0 0 31 2 *",actionKind:"script",actionPayload:s,enabled:!0}),a=await rs(e,i.id,r,{runTimeoutMs:null,waitForCompletion:!1});if(zi(e,i.id,!1),a.kind!=="fired"||a.runId===void 0)throw new Error(`on-demand launch was ${a.kind}`);return{conversationid:o,job_id:i.id,run_id:a.runId}}import{readFileSync as JD}from"node:fs";var NC=10*6e4,IC=60*6e4;function kw(e,t,r={},n=Date.now()){let o=r.ackDeadlineMs??NC,s=r.replyThresholdMs??IC,i=[];for(let a of t){let c=ni(e,{site:a.peerSite,team:a.name,alias:a.alias});if(!c)continue;let l=Date.parse(c.sent_ts);if(c.state==="sent"){n-l>=o&&i.push(a.name);continue}c.state!=="replied"&&n-l>=s&&i.push(a.name)}return i}var LC=[/^\S+'s turn has finished and exited; resubmit/i,/^resubmit .*lmctl chat/i];function CC(e){let t=e.split(/\r?\n/).filter(n=>n.trim().length>0).filter(n=>!LC.some(o=>o.test(n.trim()))),r=(t[t.length-1]??"").trim();return r==="BLOCKED"?"BLOCKED":r==="DONE"?"DONE":null}function xw(e){if(e.trim()==="")return{status:"NO-OUTPUT",wake:"env"};let t=CC(e);return t==="BLOCKED"?{status:"BLOCKED",wake:"blocked"}:t==="DONE"?{status:"DONE",wake:null}:{status:"IDLE",wake:null}}function Zn(e){switch(e.kind){case"ok":return xw(e.replyText);case"stalled":{let t=xw(e.replyText);return t.status==="BLOCKED"||t.status==="DONE"?t:{status:"NO-OUTPUT",wake:"env"}}case"busy":return{status:"RUNNING(busy)",wake:null};case"timeout":case"no-signal":return{status:"NO-OUTPUT",wake:"env"};case"error":return{status:"ENV-ERROR",wake:"env"}}}var eo=Ht(Lt(),1);function Ae(e,t){return{error:{code:e,message:t}}}var Mw=1e4;function Au(e,t,r){let n=20;if(r!==void 0){let s=typeof r=="number"?r:r.trim()===""?NaN:Number(r);if(!Number.isSafeInteger(s)||s<0||s>Mw)return Ae("invalid_limit",`invalid limit "${r}" -- must be an integer from 0 to ${Mw}`);n=s}return{events:t?e.db.db.prepare("SELECT * FROM events WHERE team = ? ORDER BY id DESC LIMIT ?").all(t,n):e.db.db.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(n)}}function Pw(e,t,r,n={}){let o=Au(e,t,r);return n.json?JSON.stringify(o):"error"in o?o.error.message:(0,eo.formatTable)([["ID","TS","TEAM","STATUS","NOTE"],...o.events.map(s=>[String(s.id),he(s.ts),(0,eo.escapeCell)(s.team),(0,eo.escapeCell)(s.status),(0,eo.escapeCell)(s.note??"")])])}var Uw=Ht(Lt(),1);function $u(e){let t=e.db.db,r=Af(t),n=Ic(t),o=n.filter(c=>c.failure_reason?.startsWith(rn)).length,s=n.length-o,i=ri(t,new Date().toISOString()).length,a=Rf(t);return{counts:r,retryEligibleCount:s,permanentCount:o,dueNowCount:i,deliveryErrorCount:a}}function Fw(e,t={}){let r=$u(e);if(t.json)return JSON.stringify(r);let n=[["persisted (awaiting dispatch)",String(r.counts.persisted)],["dispatched",String(r.counts.dispatched)],["replied",String(r.counts.replied)],["failed -- retry-eligible (backoff pending)",String(r.retryEligibleCount)],["failed -- permanent (never retried)",String(r.permanentCount)]],o=(0,Uw.formatTable)([["STATE","COUNT"],...n]),s=r.deliveryErrorCount>0?`
483
+ `)),s=e.runDaemonLoopImpl??gw,i={mailbox:e.mailbox,allowUsers:e.allowUsers,adminUsers:e.adminUsers,allowAnonymous:e.allowAnonymous,apiUrl:"",pollIntervalMs:e.pollIntervalMs??TC,timeoutCapSeconds:e.timeoutCapSeconds??SC,once:!1,execAllowlist:!0},a={client:e.client,shouldStop:()=>t,stderr:o};return{start(){r||t||(r=!0,n=s(i,a).catch(c=>{o(`[exec-worker] unexpected top-level failure, worker stopped: ${c instanceof Error?c.message:String(c)}`)}))},stop(){t=!0},isRunning:()=>r&&!t,whenIdle:()=>n}}var vC=64*1024;function yw(e){return{v:1,msgId:e.msg_id,to:{site:e.to_site,team:e.to_team,alias:e.to_alias},from:{site:e.from_site,team:e.from_team,alias:e.from_alias},sentAt:e.sent_at,payload:e.payload}}async function Su(e,t,r,n,o,s){if(r.to.site!==t.localSiteId){xn(e,r.msgId,`${rn}addressed to a different site: ${r.to.site}`,o()),s.rejected++;return}if(!t.allowlist.includes(n)){xn(e,r.msgId,`sender not allowlisted: ${n}`,o()),s.rejected++;return}try{await t.dispatch(r,n),Sf(e,r.msgId,o()),s.dispatched++}catch(i){xn(e,r.msgId,i instanceof Error?i.message:String(i),o()),s.failed++}}async function Ew(e,t,r,n){let o=n.now??(()=>new Date().toISOString()),s=n.maxBodyBytes??vC,i={recovered:0,retriedFailed:0,listed:0,recorded:0,dispatched:0,rejected:0,failed:0,stoppedEarly:!1};for(let d of bf(e))i.recovered++,await Su(e,n,yw(d),d.sender_user_id,o,i);let a=n.retryPolicy??Nc;for(let d of ri(e,o(),a))$f(e,d.msg_id)&&(i.retriedFailed++,await Su(e,n,yw(d),d.sender_user_id,o,i));let c=Tf(e)??0,{messages:l}=await t.listMessages(r,{after:c});i.listed=l.length;let u=[...l].sort((d,m)=>d.seq-m.seq);for(let d of u){let m;try{m=await t.getMessage(r,d.seq)}catch{i.stoppedEarly=!0;break}if(m.body.size>s){i.stoppedEarly=!0;break}let f;try{f=await t.download(m.body.download_url)}catch{i.stoppedEarly=!0;break}let p;try{p=yf(Buffer.from(f).toString("utf8"))}catch{i.stoppedEarly=!0;break}let h=o(),g=Ef(e,{msgId:p.msgId,seq:d.seq,to:p.to,from:p.from,senderUserId:m.sender,sentAt:p.sentAt,payload:p.payload},h);if(g!=="duplicate"){if(g==="conflict"){i.rejected++;continue}i.recorded++,await Su(e,n,p,m.sender,o,i)}}return i}async function bw(e,t){await e.createMailbox(t,{tolerate409:!0})}var AC=6e4,$C={recovered:0,retriedFailed:0,listed:0,recorded:0,dispatched:0,rejected:0,failed:0,stoppedEarly:!1};function Tw(e){let t=e.intervalMs??AC,r=null,n=!1;async function o(){if(n)return $C;n=!0;try{let s=await Ew(e.db,e.client,e.mailbox,e.worker);return e.onPoll?.(s),s}catch(s){throw e.onError?.(s),s}finally{n=!1}}return{start(){r||(r=setInterval(()=>{o().catch(()=>{})},t),r.unref())},stop(){r&&(clearInterval(r),r=null)},pollNow:o,isRunning:()=>r!==null,isPolling:()=>n}}var kC=5e3;function Sw(e){let t=e.intervalMs??kC,r=e.fetchReport??ke,n=e.deliverImpl??Ar,o=null,s=!1;async function i(){if(s)return 0;s=!0;try{let a=e.getTeams(),c=await r(),l=n(e.db,{teams:a,report:c,...e.remoteMail?{remoteMail:e.remoteMail}:{},...e.minMemoryPercent!==void 0?{minMemoryPercent:e.minMemoryPercent}:{}});return e.onDeliver?.(l),l}catch(a){throw e.onError?.(a),a}finally{s=!1}}return{start(){o||(o=setInterval(()=>{i().catch(()=>{})},t),o.unref())},stop(){o&&(clearInterval(o),o=null)},deliverNow:i,isRunning:()=>o!==null,isDelivering:()=>s}}import{isAbsolute as vw,resolve as Aw}from"node:path";import{randomUUID as xC}from"node:crypto";function RC(e){return`'${e.replaceAll("'","'\\''")}'`}async function $w(e,t,r,n){if(!vw(n.db)||Aw(n.db)!==Aw(t))throw new P("INVALID_ARGUMENT","db must select the running daemon database");let o=n.conversationId?.trim()||xC();if(n.localScope.trim()==="")throw new P("INVALID_ARGUMENT","local_scope is required");if(!vw(n.script))throw new P("INVALID_ARGUMENT","script must be an absolute path");if(!n.args.every(c=>typeof c=="string"))throw new P("INVALID_ARGUMENT","args must be strings");let s=[process.env.LMSCRIPT_BIN||"lmscript",n.script,n.db,n.localScope,o,...n.args].map(RC).join(" "),i=Vn(e,{title:`on-demand conversation ${o}`,scheduleExpr:"0 0 31 2 *",actionKind:"script",actionPayload:s,enabled:!0}),a=await rs(e,i.id,r,{runTimeoutMs:null,waitForCompletion:!1,disableOnClaim:!0});try{zi(e,i.id,!1)}catch(c){console.warn(`[on-demand] post-dispatch disable warning for job ${i.id}:`,c)}if(a.kind!=="fired"||a.runId===void 0)throw new Error(`on-demand launch was ${a.kind}`);return{conversationid:o,job_id:i.id,run_id:a.runId}}import{readFileSync as JD}from"node:fs";var NC=10*6e4,IC=60*6e4;function kw(e,t,r={},n=Date.now()){let o=r.ackDeadlineMs??NC,s=r.replyThresholdMs??IC,i=[];for(let a of t){let c=ni(e,{site:a.peerSite,team:a.name,alias:a.alias});if(!c)continue;let l=Date.parse(c.sent_ts);if(c.state==="sent"){n-l>=o&&i.push(a.name);continue}c.state!=="replied"&&n-l>=s&&i.push(a.name)}return i}var LC=[/^\S+'s turn has finished and exited; resubmit/i,/^resubmit .*lmctl chat/i];function CC(e){let t=e.split(/\r?\n/).filter(n=>n.trim().length>0).filter(n=>!LC.some(o=>o.test(n.trim()))),r=(t[t.length-1]??"").trim();return r==="BLOCKED"?"BLOCKED":r==="DONE"?"DONE":null}function xw(e){if(e.trim()==="")return{status:"NO-OUTPUT",wake:"env"};let t=CC(e);return t==="BLOCKED"?{status:"BLOCKED",wake:"blocked"}:t==="DONE"?{status:"DONE",wake:null}:{status:"IDLE",wake:null}}function Zn(e){switch(e.kind){case"ok":return xw(e.replyText);case"stalled":{let t=xw(e.replyText);return t.status==="BLOCKED"||t.status==="DONE"?t:{status:"NO-OUTPUT",wake:"env"}}case"busy":return{status:"RUNNING(busy)",wake:null};case"timeout":case"no-signal":return{status:"NO-OUTPUT",wake:"env"};case"error":return{status:"ENV-ERROR",wake:"env"}}}var eo=Ht(Lt(),1);function Ae(e,t){return{error:{code:e,message:t}}}var Mw=1e4;function Au(e,t,r){let n=20;if(r!==void 0){let s=typeof r=="number"?r:r.trim()===""?NaN:Number(r);if(!Number.isSafeInteger(s)||s<0||s>Mw)return Ae("invalid_limit",`invalid limit "${r}" -- must be an integer from 0 to ${Mw}`);n=s}return{events:t?e.db.db.prepare("SELECT * FROM events WHERE team = ? ORDER BY id DESC LIMIT ?").all(t,n):e.db.db.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(n)}}function Pw(e,t,r,n={}){let o=Au(e,t,r);return n.json?JSON.stringify(o):"error"in o?o.error.message:(0,eo.formatTable)([["ID","TS","TEAM","STATUS","NOTE"],...o.events.map(s=>[String(s.id),he(s.ts),(0,eo.escapeCell)(s.team),(0,eo.escapeCell)(s.status),(0,eo.escapeCell)(s.note??"")])])}var Uw=Ht(Lt(),1);function $u(e){let t=e.db.db,r=Af(t),n=Ic(t),o=n.filter(c=>c.failure_reason?.startsWith(rn)).length,s=n.length-o,i=ri(t,new Date().toISOString()).length,a=Rf(t);return{counts:r,retryEligibleCount:s,permanentCount:o,dueNowCount:i,deliveryErrorCount:a}}function Fw(e,t={}){let r=$u(e);if(t.json)return JSON.stringify(r);let n=[["persisted (awaiting dispatch)",String(r.counts.persisted)],["dispatched",String(r.counts.dispatched)],["replied",String(r.counts.replied)],["failed -- retry-eligible (backoff pending)",String(r.retryEligibleCount)],["failed -- permanent (never retried)",String(r.permanentCount)]],o=(0,Uw.formatTable)([["STATE","COUNT"],...n]),s=r.deliveryErrorCount>0?`
484
484
  ${r.deliveryErrorCount} row(s) with a recorded delivery error (invocation failed to spawn -- see delivery_error)`:"";return`${o}
485
485
  ${r.dueNowCount} failed row(s) due for retry now${s}`}import{closeSync as lO,existsSync as uO,openSync as dO,readFileSync as Mu,readSync as mO,realpathSync as fO,statSync as pO}from"node:fs";var YC="member_health:";function ku(e,t){return`${YC}${e}:${t}`}function qw(e,t,r,n){let o={kind:n.kind,observedAt:n.nowIso??new Date().toISOString(),remedy:n.remedy};e.prepare("INSERT INTO kv(k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v").run(ku(t,r),JSON.stringify(o))}function ms(e,t,r){let n=e.prepare("SELECT v FROM kv WHERE k = ?").get(ku(t,r));if(n===void 0)return null;try{let o=JSON.parse(n.v);return o.kind!=="evicted"||typeof o.observedAt!="string"||typeof o.remedy!="string"?null:{kind:"evicted",observedAt:o.observedAt,remedy:o.remedy}}catch{return null}}function jw(e,t,r){e.prepare("DELETE FROM kv WHERE k = ?").run(ku(t,r))}function Hw(e,t){let r=t.title.trim();if(r.length===0)throw new Error("prompt: task title must not be blank");let n=new Date().toISOString(),o=e.prepare("INSERT INTO prompt_tasks(title, description, created_at) VALUES (?, ?, ?)").run(r,t.description??"",n);return e.prepare("SELECT * FROM prompt_tasks WHERE id = ?").get(o.lastInsertRowid)}function fs(e,t){return e.prepare("SELECT * FROM prompt_tasks WHERE id = ?").get(t)??null}function Bw(e,t){let r=t.prompt.trim();if(r.length===0)throw new Error("prompt: prompt must not be blank");let n=new Date().toISOString(),o=e.prepare("INSERT INTO task_prompts(task_id, from_id, to_id, prompt, created_at) VALUES (?, ?, ?, ?, ?)").run(t.taskId,t.fromId,t.toId,r,n);return e.prepare("SELECT * FROM task_prompts WHERE id = ?").get(o.lastInsertRowid)}function Ww(e,t){return e.prepare("SELECT * FROM task_prompts WHERE task_id = ? ORDER BY id ASC").all(t)}function Gw(e,t){return e.prepare("SELECT * FROM task_prompts WHERE to_id = ? AND retrieved_ts IS NULL ORDER BY id ASC").all(t)}function Vw(e,t){return e.transaction(n=>{let o=e.prepare("SELECT * FROM task_prompts WHERE to_id = ? AND retrieved_ts IS NULL ORDER BY id").all(n);if(o.length===0)return o;let s=new Date().toISOString(),i=e.prepare("UPDATE task_prompts SET retrieved_ts = ? WHERE id = ? AND retrieved_ts IS NULL");for(let a of o)i.run(s,a.id),a.retrieved_ts=s;return o})(t)}function Jw(e,t){return e.prepare("SELECT task_id FROM task_prompts WHERE from_id = ? OR to_id = ? ORDER BY id DESC LIMIT 1").get(t,t)?.task_id??null}function zw(e,t){let r=e.prepare("SELECT * FROM task_prompts WHERE id = ?").get(t.promptId);if(r===void 0)throw new Error(`prompt: prompt #${t.promptId} does not exist`);if(fs(e,t.toTaskId)===null)throw new Error(`prompt: --task ${t.toTaskId} does not refer to an existing prompt task`);return e.transaction(()=>{e.prepare("INSERT INTO prompt_task_reassignments(prompt_id, from_task_id, to_task_id, reassigned_by, reassigned_at) VALUES (?, ?, ?, ?, ?)").run(t.promptId,r.task_id,t.toTaskId,t.reassignedBy,new Date().toISOString()),e.prepare("UPDATE task_prompts SET task_id = ? WHERE id = ?").run(t.toTaskId,t.promptId)}).immediate(),e.prepare("SELECT * FROM task_prompts WHERE id = ?").get(t.promptId)}function Yw(e,t){return e.prepare("SELECT * FROM prompt_task_reassignments WHERE prompt_id = ? ORDER BY id ASC").all(t)}function Kw(e,t){return e.prepare(`SELECT task_id, MAX(created_at) AS last_message_at, COUNT(*) AS message_count
486
486
  FROM task_prompts
@@ -541,23 +541,23 @@ appkey source: ${t.appkeySource}`,exitCode:r}}import{execFile as IO}from"node:ch
541
541
  ${a?`<base href="${v(i)}/" />`:""}
542
542
  <style>${Yy}</style></head><body><a href="#main">Skip to content</a><header><p>Local operations / lmauto</p><nav aria-label="Main">${u.map(([d,m])=>Ne(d,m)).join(" | ")}</nav></header><main${l} id="main"><h1>${v(e)}</h1>${t}</main><footer><p>Times are relative to this page load. Refresh for current data.</p></footer></body></html>`}function qr(e){let t=new Map;for(let r of e)if(B(r))try{t.set(Q(r),r.name)}catch{}return t}function Ky(e,t,r){function n(s,i=!0){if(s===null)return"\u2014";let a=Sn(s);if(!a)return v(s);let{teamfilePath:c,alias:l}=a,u=`${UO(c)}:${l}`,d=t.get(c);if(i&&d)return`<a href="${v(`${r}/sessions/${encodeURIComponent(d)}/${encodeURIComponent(l)}`)}" title="${v(s)}">${v(u)}</a>`;let m=i?`${s} \u2014 Not in the current local team registry -- no session page available`:s;return`<span title="${v(m)}">${v(u)}</span>`}function o(s,i,a){return`<section><h2>${s}</h2><table><thead><tr>${i.map(c=>`<th scope="col">${c}</th>`).join("")}</tr></thead><tbody>${a.length?a.map(c=>`<tr>${c.map(l=>`<td>${l}</td>`).join("")}</tr>`).join(""):`<tr><td colspan="${i.length}">No ${s.toLowerCase()} invocations.</td></tr>`}</tbody></table></section>`}return"<p>Running shows work still in progress. Dead means its process stopped abnormally while work was still in progress; session data remains intact and may be resumed. Idle means the invocation finished, successfully or with a recorded error; an Idle error status describes that finished result, not an ongoing crash. A target is &lt;teamfile&gt;.lmctl:&lt;role&gt;: the team\u2019s configuration file and the member role executing, such as Lead or Coder. From names what started the invocation: another member\u2019s identity, or operator for a person acting directly, not through an agent. Only targets whose team can be resolved in the current local registry link to a session page; other targets remain unlinked. Full identities are available in the labels\u2019 tooltips.</p>"+o("Running",["Target","From","Started","Running for"],e.running.map(s=>[n(s.target),n(s.from_identity,!1),v(s.started_human),v(s.running_for_human)]))+o("Dead",["Target","From","Started","Stale for"],e.dead.map(s=>[n(s.target),n(s.from_identity,!1),v(s.started_human),v(s.stale_for_human)]))+o("Idle",["Target","From","Status","Ended","Idle for","Ran for"],e.idle.map(s=>[n(s.target),n(s.from_identity,!1),v(s.status),v(he(s.ended_at)),v(me(s.idle_ms)),v(s.ran_human)]))}var va="localweb_session",HO=8*1024,BO=1024,WO=30*24*60*60,GO=10,VO=6e4,JO=6e4,zO=1024;function oE(e,t){let r=YO(t.mountPath),n=`${r}/login`||"/login",o=`${r}/`||"/",s=r||"/",i=t.allowedOrigins,a=new Map,c=new Map,l=t.remoteKey??nD,u,d=()=>{let m;try{m=t.readAuthority()}catch{m=null}return!m||!m.passcode||!m.generation?(a.clear(),u=void 0,null):(u!==void 0&&m.generation!==u&&a.clear(),u=m.generation,m)};e.use("*",async(m,f)=>{m.header("Cache-Control","no-store");let p=KO(m.req.path,r);if(m.req.method==="GET"&&(p==="/healthz"||p==="/login")||m.req.method==="POST"&&p==="/login"){await f();return}let h=m.req.header("origin");if(h!==void 0&&!i.includes(h))return m.json({error:"origin not allowed"},403);let g=d();if(g===null)return gs(m,p,n,r,"unavailable");let _=m.req.header("authorization");if(_!==void 0){let y=l(m),S=Date.now();if(tE(c,y,S))return gs(m,p,n,r,"locked_out");let T=_.startsWith("Bearer ")?_.slice(7):"";if(!eE(T,g.passcode))return rE(c,y,S),gs(m,p,n,r);nE(c,y),await f();return}let E=Zy(m.req.header("cookie"));if(E===null||a.get(E)!==g.generation)return gs(m,p,n,r,E===null?"missing":"expired");if(eD(m.req.method)&&!Xy(m.req.url,m.req.header("host"),h,i))return gs(m,p,n,r);await f()}),e.get("/healthz",m=>m.json({ok:!0})),e.get("/login",m=>m.html(QO(aE(m,n,r),r))),e.post("/login",async m=>{if(!Xy(m.req.url,m.req.header("host"),m.req.header("origin"),i))return Yu(m,n,r);let f=l(m),p=Date.now();if(tE(c,f,p))return XO(m,r);let h=d();if(h===null)return Yu(m,n,r);let g=await ZO(m.req.raw).catch(()=>null);if(g===null||!eE(g,h.passcode))return rE(c,f,p),Yu(m,n,r);nE(c,f),a.size>=BO&&a.delete(a.keys().next().value);let _=qO(32).toString("base64url");return a.set(_,h.generation),m.header("Set-Cookie",tD(_,s,new URL(m.req.url).protocol==="https:")),m.redirect(iE(m,r)??o,303)}),e.post("/logout",m=>{let f=Zy(m.req.header("cookie"));return f!==null&&a.delete(f),m.header("Set-Cookie",rD(s,new URL(m.req.url).protocol==="https:")),m.redirect(n,303)})}function YO(e=""){if(e===""||e==="/")return"";let t=e.endsWith("/")?e.slice(0,-1):e;if(!/^\/[A-Za-z0-9_./~-]+$/.test(t)||t.startsWith("//"))throw new Error("Invalid mount path");return t}function KO(e,t){return t&&(e===t||e.startsWith(`${t}/`))?e.slice(t.length)||"/":e}function gs(e,t,r,n,o="required"){let s=o==="locked_out"?429:401;if(t==="/api"||t.startsWith("/api/"))return e.json({error:o==="locked_out"?"too many failed attempts":"unauthorized"},s);let i={unavailable:"Authentication is not currently available.",missing:"You are not logged in yet.",expired:"Your session expired. Log in again to continue.",required:"Authentication required.",locked_out:"Too many failed attempts from this source. Try again shortly."}[o],a=e.req.method==="GET"?sE(`${n}${t}${new URL(e.req.url).search}`,n):null,c=a===null?r:`${r}?next=${encodeURIComponent(a)}`,l=o==="locked_out"?`<p>${i}</p>`:`<p>${i}</p><p><a href="${v(c)}">Log in</a></p>`;return e.html($e("Authentication required",l,n),s)}function QO(e,t){return $e("LocalWeb login",`<form method="post" action="${v(e)}"><label>Passcode<input type="password" name="passcode" autocomplete="current-password" required></label><button type="submit">Log in</button></form>`,t)}function Yu(e,t,r){return e.html($e("Login failed",`<p>Invalid credentials.</p><a href="${v(aE(e,t,r))}">Try again</a>`,r),401)}function XO(e,t){return e.html($e("Login failed","<p>Too many failed attempts from this source. Try again shortly.</p>",t),429)}function sE(e,t){if(!e||e.length>4096||!e.startsWith("/")||e.startsWith("//")||/[\\\x00-\x20\x7f]/.test(e))return null;let r="http://localweb.invalid";try{let n=new URL(e,r),o=decodeURIComponent(n.pathname);if(n.origin!==r||o.includes("//")||/[\\\x00-\x1f\x7f]/.test(o))return null;let s=new URL(o,r),i=a=>!t||a===t||a.startsWith(`${t}/`);return s.origin!==r||s.pathname.includes("//")||!i(n.pathname)||!i(s.pathname)?null:`${n.pathname}${n.search}${n.hash}`}catch{return null}}function iE(e,t){let r=new URL(e.req.url).searchParams.getAll("next");return r.length===1?sE(r[0],t):null}function aE(e,t,r){let n=iE(e,r);return n===null?t:`${t}?next=${encodeURIComponent(n)}`}async function ZO(e){if(!e.headers.get("content-type")?.toLowerCase().startsWith("application/x-www-form-urlencoded"))throw new Error("invalid form");let t=e.body?.getReader();if(!t)throw new Error("missing form");let r=[],n=0;for(;;){let{done:s,value:i}=await t.read();if(s)break;if(n+=i.byteLength,n>HO)throw await t.cancel(),new Error("form too large");r.push(i)}let o=new URLSearchParams(Buffer.concat(r).toString("utf8"));if(o.getAll("passcode").length!==1||[...o.keys()].some(s=>s!=="passcode"))throw new Error("invalid form");return o.get("passcode")??""}function Xy(e,t,r,n){if(r===void 0||!n.includes(r))return!1;let o=new URL(e),s=t??o.host;return r===`${o.protocol}//${s}`&&n.includes(`${o.protocol}//${o.host}`)}function eD(e){return e!=="GET"&&e!=="HEAD"&&e!=="OPTIONS"}function Zy(e){let t=(e??"").split(";").map(r=>r.trim()).filter(r=>r.startsWith(`${va}=`)).map(r=>r.slice(va.length+1));return t.length===1&&/^[A-Za-z0-9_-]{43}$/.test(t[0])?t[0]:null}function tD(e,t,r){return`${va}=${e}; Path=${t}; HttpOnly; SameSite=Strict; Max-Age=${WO}${r?"; Secure":""}`}function rD(e,t){return`${va}=; Path=${e}; HttpOnly; SameSite=Strict; Max-Age=0${t?"; Secure":""}`}function eE(e,t){let r=Qy("sha256").update(e,"utf8").digest(),n=Qy("sha256").update(t,"utf8").digest();return jO(r,n)}function nD(e){try{return Jy(e).remote.address??"unknown"}catch{return"unknown"}}function tE(e,t,r){let n=e.get(t);return n!==void 0&&r<n.lockedUntilMs}function rE(e,t,r){let n=e.get(t);if(n===void 0||r-n.windowStartMs>VO){e.size>=zO&&e.delete(e.keys().next().value),e.set(t,{count:1,windowStartMs:r,lockedUntilMs:0});return}n.count+=1,n.count>=GO&&(n.lockedUntilMs=r+JO)}function nE(e,t){e.delete(t)}import{createHash as oD}from"node:crypto";var cE=64*1024,sD=new Set(["math"]);function iD(e,t){return oD("sha256").update(e,"utf8").update("\0","utf8").update(t,"utf8").digest("hex")}function Aa(e,t,r){let n=r.to?.trim(),o=r.prompt??"",s=r.dedupeKey?.trim();if(!n)throw new L("INVALID_ARGUMENT","to is required",2);if(!s)throw new L("INVALID_ARGUMENT","dedupeKey is required",2);if(o.trim().length===0)throw new L("INVALID_ARGUMENT","prompt is required",2);if(Buffer.byteLength(o,"utf8")>cE)throw new L("INVALID_ARGUMENT",`prompt exceeds the ${cE}-byte comm-flow cap`,2);if(!sD.has(n))throw new L("INVALID_ARGUMENT",`"${n}" is not a comm-flow-enabled target`,2);let i=t.find(l=>l.name===n);if(i===void 0||!B(i))throw new L("INVALID_ARGUMENT",`"${n}" is not a registered local team`,2);let a=iD(n,o);return e.transaction(()=>{let l=e.prepare("SELECT id, admission_fingerprint FROM queue WHERE dedupe_key = ?").get(s);if(l){if(l.admission_fingerprint===a)return{queueId:l.id,replayed:!0};throw new L("CONFLICT",`dedupeKey "${s}" was already used for a different prompt`,4)}let u=we(e,t,n,o,{from:"operator",dedupeKey:s});return e.prepare("UPDATE queue SET admission_fingerprint = ? WHERE id = ?").run(a,u),{queueId:u,replayed:!1}}).immediate()}import{existsSync as aD,readFileSync as cD}from"node:fs";import{dirname as uE,join as Ku}from"node:path";import{fileURLToPath as dE}from"node:url";var lD=Ku(uE(dE(import.meta.url)),"public"),uD={"/legacy":{file:"index.html",contentType:"text/html; charset=utf-8"},"/legacy/":{file:"index.html",contentType:"text/html; charset=utf-8"},"/legacy/index.html":{file:"index.html",contentType:"text/html; charset=utf-8"},"/legacy/app.js":{file:"app.js",contentType:"text/javascript; charset=utf-8"},"/legacy/styles.css":{file:"styles.css",contentType:"text/css; charset=utf-8"}},dD=Ku(uE(dE(import.meta.url)),"vendor-webui"),mD={"/":{file:"index.html",contentType:"text/html; charset=utf-8"},"/index.html":{file:"index.html",contentType:"text/html; charset=utf-8"},"/local.js":{file:"local.js",contentType:"text/javascript; charset=utf-8"},"/styles.css":{file:"styles.css",contentType:"text/css; charset=utf-8"}};function fD(e){return e.endsWith("/")?e.slice(0,-1):e}function pD(e,t){let r=e.replace(/<head[^>]*>/i,n=>`${n}
543
543
  <base href="${t}" />`);if(r===e)throw new Error("injectBaseHref: no <head> tag found in index.html -- cannot inject <base href>");return r}function lE(e,t,r,n){for(let o of Object.keys(r))e.get(o,s=>{let i=r[o];if(!i)return s.notFound();let a=Ku(t,i.file);if(!aD(a))return s.notFound();let c=cD(a);return n!==void 0&&i.contentType.startsWith("text/html")&&(c=pD(c.toString("utf8"),n)),s.body(c,200,{"content-type":i.contentType})})}function mE(e,t={}){let r=fD(t.mountPath??""),n=t.webDistDir??dD;lE(e,n,mD,r!==""?`${r}/`:void 0),lE(e,lD,uD,`${r}/legacy/`)}import{createHash as Zu,createHmac as ED,randomBytes as Qu,timingSafeEqual as bD}from"node:crypto";import{basename as TD}from"node:path";import{existsSync as hD}from"node:fs";import{homedir as gD}from"node:os";import{join as _D}from"node:path";function wD(e){return e||(process.env.LMTEAM_DB_PATH?process.env.LMTEAM_DB_PATH:_D(gD(),".lmteam","lmteam.db"))}function $a(e){let t=wD(e);if(!hD(t))throw new Error(`lmteam database not found at ${t} -- set LMTEAM_DB_PATH or check the path`);return new wt(t,{readonly:!0,fileMustExist:!0})}function fE(e,t={}){let r=t.status??"stands",n=t.affects?e.prepare(`SELECT d.* FROM decisions d JOIN decision_affects a ON a.decision_id = d.id
544
- WHERE a.target = ? AND d.status = ? ORDER BY d.decided_at DESC`).all(t.affects,r):e.prepare("SELECT * FROM decisions WHERE status = ? ORDER BY decided_at DESC").all(r),o=e.prepare("SELECT target FROM decision_affects WHERE decision_id = ? ORDER BY target");return n.map(s=>({...s,affects:o.all(s.id).map(i=>i.target)}))}function pE(e){return e.prepare("SELECT * FROM asks WHERE status = 'open' ORDER BY raised_at ASC").all()}function hE(e,t){return e.prepare("SELECT * FROM asks WHERE id = ?").get(t)??null}function gE(e){return e.prepare("SELECT * FROM blocked WHERE status = 'open' ORDER BY raised_at ASC").all()}function yD(){let e=!1,t=0,r=new Set,n=$=>!e&&!document.hidden&&$===t,o=$=>document.getElementById($),s=($,q)=>{let M=o($);M&&(M.textContent=q)},i=($,q="")=>{let M=document.createElement($);return M.textContent=q,M},a=$=>$!==null&&typeof $=="object"&&!Array.isArray($),c=$=>Number.isSafeInteger($)&&Number($)>0,l=$=>typeof $=="string"&&Number.isFinite(Date.parse($)),u=$=>$===null||l($);async function d($,q,M,Z){r.add(M);let W,ae,be=new Promise((j,K)=>{W=()=>{ae?.cancel().catch(()=>{}),K(new Error("Request cancelled or timed out"))},M.signal.addEventListener("abort",W,{once:!0})}),ne=setTimeout(()=>M.abort(),15e3),D=async()=>{M.signal.throwIfAborted();let j=await fetch($,{method:Z===void 0?"GET":"POST",signal:M.signal,credentials:"same-origin",cache:"no-store",redirect:"error",headers:{Accept:q==="json"?"application/json":"text/html",...Z===void 0?{}:{"Content-Type":"application/x-www-form-urlencoded"}},...Z===void 0?{}:{body:Z}});if(M.signal.throwIfAborted(),j.status!==200||j.redirected||!j.headers.get("content-type")?.includes(q==="json"?"application/json":"text/html")){let ue;if(q==="html"&&!j.redirected&&j.headers.get("content-type")?.includes("text/html")){let Se=await j.text().catch(()=>""),Y=/<h1>[^<]*<\/h1>\s*<p>([^<]*)<\/p>/.exec(Se);Y&&Y[1]&&(ue=Y[1].replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'"))}else j.body?.cancel().catch(()=>{});let xe=new Error(ue??"Unexpected server response");throw xe.status=j.status,xe}let K=j.body?.getReader();if(ae=K,!K)throw new Error("Missing response body");let z=new TextDecoder,re=0,te="";try{for(;;){let ue=await K.read();if(M.signal.throwIfAborted(),ue.done)break;if(re+=ue.value.byteLength,re>(q==="json"?262144:2e6))throw new Error("Response exceeds safety limit");te+=z.decode(ue.value,{stream:!0})}return te+z.decode()}catch(ue){throw K.cancel().catch(()=>{}),ue}};try{return await Promise.race([D(),be])}finally{clearTimeout(ne),M.signal.removeEventListener("abort",W),r.delete(M)}}function m($,q){if(!a($)||$.id!==q||!l($.createdAt)||!u($.pulledAt)||!u($.answeredAt))throw new Error("Invalid queue state");let M=$.lifecycle,Z=$.lifecycleBasis,W=$.answer;if(!(M==="queued"?Z==="dispatched":M==="processing"?Z==="confirmed"||Z==="dispatched":M==="finished"&&["answer","merged","informational"].includes(String(Z))))throw new Error("Invalid lifecycle evidence");if(Z==="answer"){if(!a(W)||!c(W.id)||W.prompt_queue_id!==q||typeof W.answer_text!="string"||!l(W.answered_at)||W.answered_at!==$.answeredAt||!l(W.created_at)||typeof W.truncated!="boolean")throw new Error("Invalid correlated answer");let be=new TextEncoder().encode(W.answer_text).length;if(!Number.isSafeInteger(W.byteLength)||W.byteLength!==be||be>65536||!Number.isSafeInteger(W.totalBytes)||Number(W.totalBytes)<be||(W.truncated?Number(W.totalBytes)<=be:W.totalBytes!==be))throw new Error("Invalid response coverage")}else if(W!==null||$.answeredAt!==null)throw new Error("Unexpected answer");if(M==="queued"&&$.pulledAt!==null)throw new Error("Unexpected handling time");return $}let f=o("comm-state"),p=Number(f?.dataset.queueId),h=f?.dataset.mount??"",g,_=null,E=0,y=f?.dataset.lifecycle==="finished";function S(){if(clearTimeout(g),!(!f||!c(p)||e||document.hidden||y||_)){if(E>=60){s("comm-poll-notice","Automatic checks paused after 60 reads. Use Refresh state to check again.");return}g=setTimeout(()=>void T(),Math.min(1e3*1.5**E,1e4))}}async function T(){if(!f||_||e||document.hidden||y||E>=60)return;let $=new AbortController,q=t;_=$,E++;try{let M=await d(`${h}/api/queue/${p}/state`,"json",$);if(!n(q))return;let Z=m(JSON.parse(M),p),W=Z.lifecycleBasis,ae=Z.answer,be=Z.lifecycle==="queued"?"Queued":Z.lifecycle==="processing"?"Processing":W==="merged"?"Combined":W==="informational"?"Informational":"Replied",ne=Z.lifecycle==="queued"?"Queued \u2014 waiting for handling":Z.lifecycle==="processing"?W==="confirmed"?"Processing \u2014 picked up by inbox":"Processing \u2014 delivery attempted; read not confirmed":W==="merged"?"Finished \u2014 combined with another prompt":W==="informational"?"Finished \u2014 informational, no answer expected":"Finished \u2014 answer recorded",D=W==="merged"?"No separate answer: prompt combined into another prompt.":"No answer expected: this was an informational send.",j=f.dataset.sender??"sender not recorded",K=f.dataset.recipient??"inbox not recorded",z=ae?`Answer recorded in the ${K} inbox for prompt #${p} from ${j}.`:Z.lifecycle==="finished"?D:`No answer recorded for prompt #${p} from ${j} to ${K}.`,re=i("span",be);re.className=`status-chip status-${Z.lifecycle==="finished"?ae?"replied":"muted":Z.lifecycle}`,re.title=ne,f.replaceChildren(re,i("span",` \xB7 ${ne}`)),f.dataset.lifecycle=Z.lifecycle,f.dataset.lifecycleBasis=W,s("comm-receipt-summary",ae?"An answer is recorded below.":Z.lifecycle==="finished"?D:"No answer recorded yet."),s("comm-response-status",z),s("comm-response-none",!ae&&Z.lifecycle!=="finished"?"No correlated answer recorded yet. Refresh to check again.":""),s("comm-response-meta",ae?`Recorded ${ae.answered_at} \xB7 answer #${ae.id} to prompt #${ae.prompt_queue_id}`:""),s("comm-response",ae?.answer_text??"");let te=o("comm-response");te&&(te.hidden=!ae),s("comm-response-truncation",ae?ae.truncated?`Truncated: ${ae.byteLength} of ${ae.totalBytes} bytes. No continuation endpoint is available.`:`${ae.byteLength} bytes returned.`:""),s("comm-reply-time",ae?.answered_at??"not recorded"),s("comm-handling-observation",`Latest handling evidence: ${Z.pulledAt??"not recorded"}${Z.pulledAt?W==="confirmed"?" (picked up)":W==="dispatched"?" (delivery attempted)":" (transport or pickup time)":""}`),s("comm-poll-notice",`State checked ${new Date().toISOString()}.`),y=Z.lifecycle==="finished"}catch(M){n(q)&&s("comm-poll-notice",`State unavailable; displayed records may be stale. ${M instanceof Error?M.message:String(M)}. Use Refresh state.`)}finally{_===$&&(_=null),S()}}let R=o("comm-composer-container"),A=o("comm-draft-form"),I=null,x=!1,H=!1,C=!1,w=null,b=null,N=$=>Array.from($.querySelectorAll("input, textarea")),P=($,q)=>{let M=N($).filter(Z=>Z.name===q);if(M.length!==1)throw new Error("Invalid review fields");return M[0]};function J($,q){let M=N($).map(Z=>({input:Z,value:Z.value}));w=$,b=$.querySelector('button[type="submit"]'),$.addEventListener("submit",Z=>{if(H||e||document.hidden){Z.preventDefault();return}for(let W of M)W.input.value=W.value;H=!0,C=!0,q&&(q.disabled=!0),b&&(b.disabled=!0),s("comm-send-status","Submitting through the browser. If the outcome is uncertain, return here and retry this same confirmation.")})}let ee=o("comm-confirm-form");if(ee&&J(ee,o("comm-edit-button")),A?.addEventListener("submit",$=>{C&&$.preventDefault()}),R&&A&&o("compose")){let $=Array.from(R.childNodes),q=A.querySelector('textarea[name="prompt"]'),M=A.querySelector('button[type="submit"]');A.addEventListener("submit",async Z=>{if(!q||(Z.preventDefault(),I||C||e||document.hidden))return;let W=q.value.replace(/\r\n?/g,`
545
- `);if(!W.trim()||new TextEncoder().encode(W.replace(/\n/g,`\r
546
- `)).length>65536){s("comm-composer-notice","Enter a nonblank prompt of at most 64 KiB UTF-8.");return}let ae=t,be=new AbortController;I=be,x=!1,M&&(M.disabled=!0),s("comm-composer-notice","Reviewing prompt\u2026");try{let ne=new URL(A.action,window.location.href),D=o("compose")?.dataset.base;if(!D||ne.origin!==new URL(window.location.href).origin||ne.pathname!==`${D}/review`||ne.search||ne.hash)throw new Error("Unexpected review destination");let j=()=>{let G=new URLSearchParams;for(let ye of N(A))ye.name&&!ye.disabled&&G.append(ye.name,ye.value.replace(/\r\n|\r|\n/g,`\r
547
- `));return G.toString()},K;try{K=await d(ne.href,"html",be,j())}catch(G){if((G instanceof Error?G.status:void 0)!==409||!n(ae))throw G;s("comm-composer-notice","Session renewing\u2026");let at=await d(window.location.href,"html",be);if(!n(ae))return;let tt=new DOMParser().parseFromString(at,"text/html").getElementById("comm-draft-form"),gt="";try{tt&&(gt=P(tt,"csrf").value)}catch{}if(!gt)throw G;P(A,"csrf").value=gt,K=await d(ne.href,"html",be,j())}if(!n(ae))return;let re=new DOMParser().parseFromString(K,"text/html").getElementById("comm-confirm-form");if(!re)throw new Error("Review unavailable; use the native review form after reloading");let te=new URL(re.getAttribute("action")??"",ne.href),ue=P(re,"confirmation").value;if(re.method.toLowerCase()!=="post"||te.origin!==ne.origin||te.pathname!==`${D}/prompts`||te.search||te.hash||!ue||ue.length>4096||P(re,"prompt").value!==W)throw new Error("Review did not match the exact prompt");let xe=i("div");xe.id="comm-review-panel",xe.append(i("p","Review prompt to math:Lead"),i("pre",W));let Se=document.createElement("form");Se.id="comm-confirm-form",Se.method="post",Se.action=te.href;let Y=document.createElement("input");Y.type="hidden",Y.name="confirmation",Y.value=ue;let Te=document.createElement("textarea");Te.name="prompt",Te.hidden=!0,Te.value=W;let Je=document.createElement("button");Je.type="submit",Je.id="comm-confirm-submit",Je.textContent="Confirm and queue";let Be=document.createElement("button");Be.type="button",Be.id="comm-edit-button",Be.textContent="Edit prompt";let Pt=i("p");Pt.id="comm-send-status",Pt.setAttribute("role","status"),Se.append(Y,Te,Je),xe.append(Se,Be,Pt),Be.addEventListener("click",()=>{C||Be.disabled||(q.value=W,R.replaceChildren(...$),w=null)}),J(Se,Be),R.replaceChildren(xe)}catch(ne){n(ae)&&s("comm-composer-notice",`Review unavailable: ${ne instanceof Error?ne.message:String(ne)}. Draft retained; retry review or reload to renew the form. The native flow also works without JavaScript.`)}finally{I===be&&(I=null,M&&!e&&!document.hidden&&(M.disabled=!1),!e&&!document.hidden&&x&&s("comm-composer-notice","Review interrupted; draft retained. Review again when ready."))}})}function oe(){I&&(x=!0),t++,clearTimeout(g);for(let $ of r)$.abort()}let V=()=>{if(!I&&!C){let $=A?.querySelector('button[type="submit"]');$&&($.disabled=!1),x&&s("comm-composer-notice","Review interrupted; draft retained. Review again when ready.")}S()},se=()=>{document.hidden?oe():V()},k=()=>{e=!0,oe()},O=$=>{$.persisted&&(e=!1,w&&H&&(H=!1,b&&(b.disabled=!1,b.textContent="Retry this same confirmation"),s("comm-send-status","Outcome may be uncertain. Retry only this same confirmation, or check the inbox.")),V())};return document.addEventListener("visibilitychange",se),window.addEventListener("pagehide",k),window.addEventListener("pageshow",O),S(),()=>{k(),document.removeEventListener("visibilitychange",se),window.removeEventListener("pagehide",k),window.removeEventListener("pageshow",O)}}var ka=`(function () {
544
+ WHERE a.target = ? AND d.status = ? ORDER BY d.decided_at DESC`).all(t.affects,r):e.prepare("SELECT * FROM decisions WHERE status = ? ORDER BY decided_at DESC").all(r),o=e.prepare("SELECT target FROM decision_affects WHERE decision_id = ? ORDER BY target");return n.map(s=>({...s,affects:o.all(s.id).map(i=>i.target)}))}function pE(e){return e.prepare("SELECT * FROM asks WHERE status = 'open' ORDER BY raised_at ASC").all()}function hE(e,t){return e.prepare("SELECT * FROM asks WHERE id = ?").get(t)??null}function gE(e){return e.prepare("SELECT * FROM blocked WHERE status = 'open' ORDER BY raised_at ASC").all()}function yD(){let e=!1,t=0,r=new Set,n=$=>!e&&!document.hidden&&$===t,o=$=>document.getElementById($),s=($,q)=>{let U=o($);U&&(U.textContent=q)},i=($,q="")=>{let U=document.createElement($);return U.textContent=q,U},a=$=>$!==null&&typeof $=="object"&&!Array.isArray($),c=$=>Number.isSafeInteger($)&&Number($)>0,l=$=>typeof $=="string"&&Number.isFinite(Date.parse($)),u=$=>$===null||l($);async function d($,q,U,Z){r.add(U);let G,ae,be=new Promise((j,K)=>{G=()=>{ae?.cancel().catch(()=>{}),K(new Error("Request cancelled or timed out"))},U.signal.addEventListener("abort",G,{once:!0})}),ne=setTimeout(()=>U.abort(),15e3),D=async()=>{U.signal.throwIfAborted();let j=await fetch($,{method:Z===void 0?"GET":"POST",signal:U.signal,credentials:"same-origin",cache:"no-store",redirect:"error",headers:{Accept:q==="json"?"application/json":"text/html",...Z===void 0?{}:{"Content-Type":"application/x-www-form-urlencoded"}},...Z===void 0?{}:{body:Z}});if(U.signal.throwIfAborted(),j.status!==200||j.redirected||!j.headers.get("content-type")?.includes(q==="json"?"application/json":"text/html")){let ue;if(q==="html"&&!j.redirected&&j.headers.get("content-type")?.includes("text/html")){let Se=await j.text().catch(()=>""),Y=/<h1>[^<]*<\/h1>\s*<p>([^<]*)<\/p>/.exec(Se);Y&&Y[1]&&(ue=Y[1].replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'"))}else j.body?.cancel().catch(()=>{});let xe=new Error(ue??"Unexpected server response");throw xe.status=j.status,xe}let K=j.body?.getReader();if(ae=K,!K)throw new Error("Missing response body");let z=new TextDecoder,re=0,te="";try{for(;;){let ue=await K.read();if(U.signal.throwIfAborted(),ue.done)break;if(re+=ue.value.byteLength,re>(q==="json"?262144:2e6))throw new Error("Response exceeds safety limit");te+=z.decode(ue.value,{stream:!0})}return te+z.decode()}catch(ue){throw K.cancel().catch(()=>{}),ue}};try{return await Promise.race([D(),be])}finally{clearTimeout(ne),U.signal.removeEventListener("abort",G),r.delete(U)}}function m($,q){if(!a($)||$.id!==q||!l($.createdAt)||!u($.pulledAt)||!u($.answeredAt))throw new Error("Invalid queue state");let U=$.lifecycle,Z=$.lifecycleBasis,G=$.answer;if(!(U==="queued"?Z==="dispatched":U==="processing"?Z==="confirmed"||Z==="dispatched":U==="finished"&&["answer","merged","informational"].includes(String(Z))))throw new Error("Invalid lifecycle evidence");if(Z==="answer"){if(!a(G)||!c(G.id)||G.prompt_queue_id!==q||typeof G.answer_text!="string"||!l(G.answered_at)||G.answered_at!==$.answeredAt||!l(G.created_at)||typeof G.truncated!="boolean")throw new Error("Invalid correlated answer");let be=new TextEncoder().encode(G.answer_text).length;if(!Number.isSafeInteger(G.byteLength)||G.byteLength!==be||be>65536||!Number.isSafeInteger(G.totalBytes)||Number(G.totalBytes)<be||(G.truncated?Number(G.totalBytes)<=be:G.totalBytes!==be))throw new Error("Invalid response coverage")}else if(G!==null||$.answeredAt!==null)throw new Error("Unexpected answer");if(U==="queued"&&$.pulledAt!==null)throw new Error("Unexpected handling time");return $}let f=o("comm-state"),p=Number(f?.dataset.queueId),h=f?.dataset.mount??"",g,_=null,E=0,y=f?.dataset.lifecycle==="finished";function S(){if(clearTimeout(g),!(!f||!c(p)||e||document.hidden||y||_)){if(E>=60){s("comm-poll-notice","Automatic checks paused after 60 reads. Use Refresh state to check again.");return}g=setTimeout(()=>void T(),Math.min(1e3*1.5**E,1e4))}}async function T(){if(!f||_||e||document.hidden||y||E>=60)return;let $=new AbortController,q=t;_=$,E++;try{let U=await d(`${h}/api/queue/${p}/state`,"json",$);if(!n(q))return;let Z=m(JSON.parse(U),p),G=Z.lifecycleBasis,ae=Z.answer,be=Z.lifecycle==="queued"?"Queued":Z.lifecycle==="processing"?"Processing":G==="merged"?"Combined":G==="informational"?"Informational":"Replied",ne=Z.lifecycle==="queued"?"Queued \u2014 waiting for handling":Z.lifecycle==="processing"?G==="confirmed"?"Processing \u2014 picked up by inbox":"Processing \u2014 delivery attempted; read not confirmed":G==="merged"?"Finished \u2014 combined with another prompt":G==="informational"?"Finished \u2014 informational, no answer expected":"Finished \u2014 answer recorded",D=G==="merged"?"No separate answer: prompt combined into another prompt.":"No answer expected: this was an informational send.",j=f.dataset.sender??"sender not recorded",K=f.dataset.recipient??"inbox not recorded",z=ae?`Answer recorded in the ${K} inbox for prompt #${p} from ${j}.`:Z.lifecycle==="finished"?D:`No answer recorded for prompt #${p} from ${j} to ${K}.`,re=i("span",be);re.className=`status-chip status-${Z.lifecycle==="finished"?ae?"replied":"muted":Z.lifecycle}`,re.title=ne,f.replaceChildren(re,i("span",` \xB7 ${ne}`)),f.dataset.lifecycle=Z.lifecycle,f.dataset.lifecycleBasis=G,s("comm-receipt-summary",ae?"An answer is recorded below.":Z.lifecycle==="finished"?D:"No answer recorded yet."),s("comm-response-status",z),s("comm-response-none",!ae&&Z.lifecycle!=="finished"?"No correlated answer recorded yet. Refresh to check again.":""),s("comm-response-meta",ae?`Recorded ${ae.answered_at} \xB7 answer #${ae.id} to prompt #${ae.prompt_queue_id}`:""),s("comm-response",ae?.answer_text??"");let te=o("comm-response");te&&(te.hidden=!ae),s("comm-response-truncation",ae?ae.truncated?`Truncated: ${ae.byteLength} of ${ae.totalBytes} bytes. No continuation endpoint is available.`:`${ae.byteLength} bytes returned.`:""),s("comm-reply-time",ae?.answered_at??"not recorded"),s("comm-handling-observation",`Latest handling evidence: ${Z.pulledAt??"not recorded"}${Z.pulledAt?G==="confirmed"?" (picked up)":G==="dispatched"?" (delivery attempted)":" (transport or pickup time)":""}`),s("comm-poll-notice",`State checked ${new Date().toISOString()}.`),y=Z.lifecycle==="finished"}catch(U){n(q)&&s("comm-poll-notice",`State unavailable; displayed records may be stale. ${U instanceof Error?U.message:String(U)}. Use Refresh state.`)}finally{_===$&&(_=null),S()}}let R=o("comm-composer-container"),A=o("comm-draft-form"),I=null,x=!1,H=!1,C=!1,w=null,b=null,N=$=>Array.from($.querySelectorAll("input, textarea")),M=($,q)=>{let U=N($).filter(Z=>Z.name===q);if(U.length!==1)throw new Error("Invalid review fields");return U[0]};function W($,q){let U=N($).map(Z=>({input:Z,value:Z.value}));w=$,b=$.querySelector('button[type="submit"]'),$.addEventListener("submit",Z=>{if(H||e||document.hidden){Z.preventDefault();return}for(let G of U)G.input.value=G.value;H=!0,C=!0,q&&(q.disabled=!0),b&&(b.disabled=!0),s("comm-send-status","Submitting through the browser. If the outcome is uncertain, return here and retry this same confirmation.")})}let ee=o("comm-confirm-form");if(ee&&W(ee,o("comm-edit-button")),A?.addEventListener("submit",$=>{C&&$.preventDefault()}),R&&A&&o("compose")){let $=Array.from(R.childNodes),q=A.querySelector('textarea[name="prompt"]'),U=A.querySelector('button[type="submit"]');A.addEventListener("submit",async Z=>{if(!q||(Z.preventDefault(),I||C||e||document.hidden))return;let G=q.value.replace(/\r\n?/g,`
545
+ `);if(!G.trim()||new TextEncoder().encode(G.replace(/\n/g,`\r
546
+ `)).length>65536){s("comm-composer-notice","Enter a nonblank prompt of at most 64 KiB UTF-8.");return}let ae=t,be=new AbortController;I=be,x=!1,U&&(U.disabled=!0),s("comm-composer-notice","Reviewing prompt\u2026");try{let ne=new URL(A.action,window.location.href),D=o("compose")?.dataset.base;if(!D||ne.origin!==new URL(window.location.href).origin||ne.pathname!==`${D}/review`||ne.search||ne.hash)throw new Error("Unexpected review destination");let j=()=>{let V=new URLSearchParams;for(let ye of N(A))ye.name&&!ye.disabled&&V.append(ye.name,ye.value.replace(/\r\n|\r|\n/g,`\r
547
+ `));return V.toString()},K;try{K=await d(ne.href,"html",be,j())}catch(V){if((V instanceof Error?V.status:void 0)!==409||!n(ae))throw V;s("comm-composer-notice","Session renewing\u2026");let at=await d(window.location.href,"html",be);if(!n(ae))return;let tt=new DOMParser().parseFromString(at,"text/html").getElementById("comm-draft-form"),gt="";try{tt&&(gt=M(tt,"csrf").value)}catch{}if(!gt)throw V;M(A,"csrf").value=gt,K=await d(ne.href,"html",be,j())}if(!n(ae))return;let re=new DOMParser().parseFromString(K,"text/html").getElementById("comm-confirm-form");if(!re)throw new Error("Review unavailable; use the native review form after reloading");let te=new URL(re.getAttribute("action")??"",ne.href),ue=M(re,"confirmation").value;if(re.method.toLowerCase()!=="post"||te.origin!==ne.origin||te.pathname!==`${D}/prompts`||te.search||te.hash||!ue||ue.length>4096||M(re,"prompt").value!==G)throw new Error("Review did not match the exact prompt");let xe=i("div");xe.id="comm-review-panel",xe.append(i("p","Review prompt to math:Lead"),i("pre",G));let Se=document.createElement("form");Se.id="comm-confirm-form",Se.method="post",Se.action=te.href;let Y=document.createElement("input");Y.type="hidden",Y.name="confirmation",Y.value=ue;let Te=document.createElement("textarea");Te.name="prompt",Te.hidden=!0,Te.value=G;let Je=document.createElement("button");Je.type="submit",Je.id="comm-confirm-submit",Je.textContent="Confirm and queue";let Be=document.createElement("button");Be.type="button",Be.id="comm-edit-button",Be.textContent="Edit prompt";let Pt=i("p");Pt.id="comm-send-status",Pt.setAttribute("role","status"),Se.append(Y,Te,Je),xe.append(Se,Be,Pt),Be.addEventListener("click",()=>{C||Be.disabled||(q.value=G,R.replaceChildren(...$),w=null)}),W(Se,Be),R.replaceChildren(xe)}catch(ne){n(ae)&&s("comm-composer-notice",`Review unavailable: ${ne instanceof Error?ne.message:String(ne)}. Draft retained; retry review or reload to renew the form. The native flow also works without JavaScript.`)}finally{I===be&&(I=null,U&&!e&&!document.hidden&&(U.disabled=!1),!e&&!document.hidden&&x&&s("comm-composer-notice","Review interrupted; draft retained. Review again when ready."))}})}function oe(){I&&(x=!0),t++,clearTimeout(g);for(let $ of r)$.abort()}let J=()=>{if(!I&&!C){let $=A?.querySelector('button[type="submit"]');$&&($.disabled=!1),x&&s("comm-composer-notice","Review interrupted; draft retained. Review again when ready.")}S()},se=()=>{document.hidden?oe():J()},k=()=>{e=!0,oe()},O=$=>{$.persisted&&(e=!1,w&&H&&(H=!1,b&&(b.disabled=!1,b.textContent="Retry this same confirmation"),s("comm-send-status","Outcome may be uncertain. Retry only this same confirmation, or check the inbox.")),J())};return document.addEventListener("visibilitychange",se),window.addEventListener("pagehide",k),window.addEventListener("pageshow",O),S(),()=>{k(),document.removeEventListener("visibilitychange",se),window.removeEventListener("pagehide",k),window.removeEventListener("pageshow",O)}}var ka=`(function () {
548
548
  function __name(value) { return value; }
549
549
  return (${yD.toString()})();
550
- })();`;var _E=$e("","","").match(/<style>([\s\S]*?)<\/style>/),SD=Zu("sha256").update(_E?_E[1]:"").digest("base64"),vD=Zu("sha256").update(ka).digest("base64"),AD=`default-src 'none'; style-src 'sha256-${SD}'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'; script-src 'sha256-${vD}'; connect-src 'self'`,Xu="lmbee_comm_browser",$D=64*1024,kD=256*1024,io=class extends Error{};function wE(e){let t=new cn,{context:r}=e,n=(e.mountPath??"").replace(/\/$/,"");if(n&&(!/^\/[A-Za-z0-9_./~-]+$/.test(n)||n.startsWith("//")))throw new Error("Invalid mount path");let o=`${n}/comm/math`,s=e.now??Date.now,i=Qu(32),a=new Map,c=k=>Zu("sha256").update(k).digest("hex"),l=k=>ED("sha256",i).update(k).digest("base64url"),u=k=>{let O=Buffer.from(JSON.stringify(k)).toString("base64url");return`${O}.${l(O)}`};function d(k){let O=k.split(".");if(O.length!==2||k.length>4096)throw new Error("Invalid confirmation. Review the prompt again.");let $=Buffer.from(l(O[0])),q=Buffer.from(O[1]);if($.length!==q.length||!bD($,q))throw new Error("Invalid confirmation. Review the prompt again.");return JSON.parse(Buffer.from(O[0],"base64url").toString("utf8"))}function m(k,O=!1){let $=(k.req.header("cookie")??"").split(";").map(M=>M.trim()).filter(M=>M.startsWith(`${Xu}=`));if($.length===1)try{let M=d($[0].slice(Xu.length+1));if(typeof M.browser=="string"&&/^[a-f0-9]{48}$/.test(M.browser))return M.browser}catch{}if(!O)throw new Error("Browser confirmation expired. Open the Math inbox and review again.");let q=Qu(24).toString("hex");return k.header("Set-Cookie",`${Xu}=${u({browser:q})}; Path=${o}; HttpOnly; SameSite=Strict${new URL(k.req.url).protocol==="https:"?"; Secure":""}`),q}function f(){let k=r.teams.find(O=>O.name==="math");if(!k||!B(k)||k.leadAlias!=="Lead")throw new Error("The local math Lead inbox is unavailable.");return`${Q(k)}:Lead`}function p(k){return k==="merged"||k==="informational"||k==="retracted"}function h(k){return k.answeredAt?`<a href="${o}/prompts/${k.id}#comm-response">Answer to #${k.id}</a> \xB7 ${fe(k.answeredAt)}`:k.lifecycleBasis==="merged"?"No separate answer (merged)":k.lifecycleBasis==="informational"?"No answer expected (informational)":k.lifecycleBasis==="retracted"?`No answer expected (retracted): ${v(k.retracted_reason??"no reason recorded")}`:"No answer recorded"}function g(k){for(let O of k.split(`
551
- `)){let $=O.trim();if($)return $}return""}let _=80,E=2e3;function y(k,O){return k.length>O?`${k.slice(0,O)}\u2026`:k}function S(k){let O=g(k);return O?y(O,_):"(empty prompt)"}function T(k){return y(k.trim(),E)}function R(k){let O=Ur(r,k),$=`Prompt #${k}`;return!O||O.status!=="available"||O.text===null?`<a href="${o}/prompts/${k}">${v($)}</a>`:`<a href="${o}/prompts/${k}" title="${v(T(O.text))}">${v(S(O.text))}</a>`}function A(k){return k.lifecycle==="queued"?"queued":k.lifecycle==="processing"?"processing":p(k.lifecycleBasis)?"muted":"replied"}function I(k){return k.lifecycle==="queued"?"Queued":k.lifecycle==="processing"?"Processing":k.lifecycleBasis==="merged"?"Combined":k.lifecycleBasis==="informational"?"Informational":k.lifecycleBasis==="retracted"?"Retracted":"Replied"}function x(k){return`<span class="status-chip status-${A(k)}" title="${v(H(k))}">${v(I(k))}</span>`}function H(k){return k.lifecycle==="queued"?"Queued \u2014 waiting for handling":k.lifecycle==="finished"?k.lifecycleBasis==="merged"?"Finished \u2014 combined with another prompt":k.lifecycleBasis==="informational"?"Finished \u2014 informational, no answer expected":k.lifecycleBasis==="retracted"?"Finished \u2014 retracted, no answer expected":"Finished \u2014 answer recorded":k.lifecycleBasis==="confirmed"?"Processing \u2014 picked up by inbox":"Processing \u2014 delivery attempted; read not confirmed"}function C(k){if(k==="operator")return"Operator";let O=Sn(k);if(O){let q=r.teams.find(M=>{if(!B(M))return!1;try{return Q(M)===O.teamfilePath}catch{return!1}});return q?`<a href="${v(`${n}/sessions/${encodeURIComponent(q.name)}/${encodeURIComponent(O.alias)}`)}" title="${v(k)}">${v(`${q.name}:${O.alias}`)}</a>`:`<span title="${v(k)}">${v(`${TD(O.teamfilePath)}:${O.alias}`)}</span>`}let $=r.teams.find(q=>q.name===k);return $&&B($)?`<a href="${v(`${n}/sessions/${encodeURIComponent($.name)}/${encodeURIComponent($.leadAlias)}`)}" title="${v(`Current configured lead for inbox ${k}`)}">${v(`${$.name}:${$.leadAlias}`)}</a>`:`${v(k)}${$?" (remote inbox)":" (not in the current team list)"}`}function w(){let k=r.teams.find(O=>O.name==="math");if(!k||!B(k))return'<section aria-label="Assigned work"><h2>Assigned work</h2><p>Math\u2019s current local actor is unavailable, so its assigned work cannot be resolved.</p></section>';try{let O=kr(r.db.db,{owner:{team:Q(k),alias:k.leadAlias},limit:5});return`<section aria-label="Assigned work"><h2>Assigned work</h2><p>Work owned by ${C("math")}. Open an item to follow its epic, parent task, or subtasks.</p>${O.rows.length?`<ul>${O.rows.map($=>`<li><a href="${n}/tasks/${$.id}">${v(`${$.kind} #${$.id}: ${$.title}`)}</a> \u2014 ${v($.status)}</li>`).join("")}</ul><p>Up to five assigned items shown.</p>`:"<p>No assigned work returned for this actor.</p>"}</section>`}catch{return'<section aria-label="Assigned work"><h2>Assigned work</h2><p>Current work ownership is unavailable. Prompt and answer records below remain readable.</p></section>'}}let b="<details><summary>About these records</summary><p>Actor links open each team\u2019s current configured lead; records identify inboxes and sender labels, not exact historical sessions. Assigned work is current ownership, not proof of execution or a prompt\u2019s topic. A delivery attempt does not confirm the inbox read a prompt. A recorded answer does not establish delivery back to the sender or task success.</p></details>";function N(k,O,$,q=200){return k.html($e(O,`${$}<script>${ka}</script>`,n,{},[ka]),q)}function P(k,O="",$=""){return`<div id="comm-composer-container"><p id="comm-composer-notice">${v($)}</p><form id="comm-draft-form" method="post" action="${o}/review"><input type="hidden" name="csrf" value="${v(u({browser:k,purpose:"review"}))}"><label for="prompt">Prompt for math Lead (maximum 64 KiB UTF-8)</label><textarea id="prompt" name="prompt" rows="8" required>
552
- ${v(O)}</textarea><button type="submit">Review prompt</button></form></div>`}function J(k,O){return`<form method="post" action="${o}/prompts"><input type="hidden" name="confirmation" value="${v(O)}"><textarea name="prompt" hidden>
553
- ${v(k)}</textarea><button type="submit">Retry this same confirmation</button></form>`}let ee=500;function oe(k){let O=k.req.query("ask");if(O!==void 0&&/^[1-9]\d*$/.test(O)){try{let q=$a(),M;try{M=hE(q,Number(O))}finally{q.close()}if(M){let Z=M.downstream?v(M.downstream):"Not recorded";return`<div id="comm-reply-context" aria-label="Replying to"><p><strong>Replying to ask:</strong> ${v(M.subject)}</p><p>${v(M.reason)}</p><p><strong>Downstream:</strong> ${Z}</p></div>`}}catch{}return""}let $=k.req.query("reply_to");if($!==void 0&&/^[1-9]\d*$/.test($)){let q=to(r,Number($));if(q){let M=Ur(r,q.id),Z=M?.status==="available"&&M.text!==null?y(M.text.trim(),ee):"(preview unavailable)";return`<div id="comm-reply-context" aria-label="Replying to"><p><strong>Replying to</strong> a prompt from ${C(q.from_id)}, ${fe(q.created_ts)}:</p><pre>${v(Z)}</pre></div>`}}return""}async function V(k){if(!k.req.header("content-type")?.toLowerCase().startsWith("application/x-www-form-urlencoded"))throw new Error("Expected a browser form.");let O=k.req.raw.body?.getReader();if(!O)throw new Error("Missing form.");let $=0,q=[];for(;;){let{done:Z,value:W}=await O.read();if(Z)break;if($+=W.byteLength,$>kD)throw await O.cancel(),new Error("Form exceeds the size limit.");q.push(W)}let M=new URLSearchParams(Buffer.concat(q).toString("utf8"));for(let Z of M.keys())if(M.getAll(Z).length!==1)throw new Error("Duplicate form field.");return M}function se(k){let O=k.get("prompt")??"";if(!O.trim()||Buffer.byteLength(O)>$D)throw new Error("Enter a nonblank prompt of at most 64 KiB UTF-8.");return O}return t.use("/comm/math/*",async(k,O)=>{k.header("Cache-Control","no-store"),k.header("Content-Security-Policy",AD),k.header("Referrer-Policy","same-origin"),k.header("X-Content-Type-Options","nosniff");let $=new URL(k.req.url),q=`${$.protocol}//${k.req.header("host")??$.host}`,M=k.req.header("sec-fetch-site");if(!e.allowedOrigins.includes(q)||M&&M!=="same-origin"&&M!=="none"||k.req.header("origin")!==void 0&&k.req.header("origin")!==q||k.req.method==="POST"&&k.req.header("origin")!==q)return N(k,"Request rejected","<p>Use this browser\u2019s local Math inbox page.</p>",403);await O()}),t.get("/comm/math",k=>{let O="<p>Sending is not enabled on this surface.</p>";if(e.enabled)try{f(),O=P(m(k,!0))}catch(M){O=`<p>${v(M.message)}</p>`}let $=k.req.query("after");if($!==void 0&&(!/^[1-9]\d*$/.test($)||!Number.isSafeInteger(Number($))))return N(k,"Invalid page","<p>Invalid prompt cursor.</p>",400);let q=ba(r,{toId:"math",limit:20,...$?{after:Number($)}:{}});return N(k,"Math inbox",`<p>Prompts to ${C("math")} and the answers recorded against them. Select a prompt to follow the exchange; use assigned work to explore the tasks this actor owns.</p>${b}<p><a href="${o}">Refresh inbox</a> \xB7 <a href="#compose">Write a prompt</a> \xB7 <a href="${n}/sessions/math/Lead">Math session</a></p><section id="compose" aria-label="Write a prompt" data-mount="${v(n)}" data-base="${v(o)}"><h2>Write a prompt</h2><p>Start a new prompt to ${C("math")}. Review the exact text before queueing it.</p>${oe(k)}${O}</section>${w()}<section id="history" aria-label="Prompts and answers"><h2>Incoming prompts and answers</h2><p>Only prompts addressed to Math appear here. <a href="${n}/sessions/math/Lead#comm-sequence">See incoming and outgoing exchanges</a> in the session timeline.</p><p>Newest 20 matching prompts first. Queued means waiting; processing records a pull or dispatch attempt; finished means an answer was recorded, an informational send expected no answer, or prompts from the same sender to the same recipient were combined to avoid separate deliveries. Finished for a combined prompt does not mean separate work was done, and no separate answer is expected. The combined prompt ID is not recorded, so no link is available.</p><table><thead><tr><th>Prompt</th><th>Actors</th><th>Handling</th><th>Queued</th><th>Answer</th></tr></thead><tbody>${q.rows.map(M=>`<tr data-queue-id="${M.id}"><td>${R(M.id)}</td><td>${C(M.from_id)} \u2192 ${C(M.to_id)}</td><td>${x(M)} \xB7 ${v(H(M))}</td><td>${fe(M.created_ts)}</td><td>${h(M)}</td></tr>`).join("")}</tbody></table><p>Task links for these prompts: not recorded.</p>${q.meta.next_cursor?`<a href="${o}?after=${q.meta.next_cursor}">Older prompts</a>`:""}</section>`)}),t.post("/comm/math/review",async k=>{if(!e.enabled)return N(k,"Sending unavailable","<p>Sending is not enabled.</p>",403);let O="",$="";try{let q=await V(k);O=q.get("prompt")??"";let M;try{M=m(k)}catch(ae){throw new io(ae.message)}$=M;let Z;try{Z=d(q.get("csrf")??"")}catch(ae){throw new io(ae.message)}if(Z.browser!==M||Z.purpose!=="review")throw new io("Review form no longer matches this browser session. Reloading will renew it.");O=se(q);let W={browser:M,digest:c(O),target:f(),key:`localweb:${Qu(24).toString("hex")}`,expires:s()+3e5};return N(k,"Review prompt to math",`<div id="comm-review-panel"><p>New prompt: Operator \u2192 ${C("math")}. Task link: none.</p><p>Queue one prompt for math to handle on its next pull. Processing may wait; the agent may use its existing file/network permissions.</p><p>Recipient: <a href="${v(`${n}/sessions/math/Lead`)}" title="${v(W.target)}">math:Lead</a></p><pre id="comm-review-preview">
554
- ${v(O)}</pre><form id="comm-confirm-form" method="post" action="${o}/prompts"><input type="hidden" name="confirmation" value="${v(u(W))}"><textarea name="prompt" hidden>
555
- ${v(O)}</textarea><button id="comm-confirm-submit" type="submit">Confirm and queue</button></form><button type="button" id="comm-edit-button">Edit prompt</button><p id="comm-send-status" role="status"></p><details><summary>Edit prompt</summary>${P(M,O)}</details><p>Confirmation expires in five minutes. If a submission result is uncertain, retry this same confirmation; do not create a new prompt.</p></div>`)}catch(q){let M=q instanceof io?409:400;return N(k,"Review unavailable",`<p>${v(q.message)}</p>${$?P($,O):`<pre>
556
- ${v(O)}</pre>`}<a href="${o}">Math inbox</a>`,M)}}),t.post("/comm/math/prompts",async k=>{if(!e.enabled)return N(k,"Sending unavailable","<p>Sending is not enabled.</p>",403);let O="",$="",q=!1;try{let M=await V(k);O=M.get("prompt")??"",$=M.get("confirmation")??"";let Z=m(k);O=se(M);let W=d($);if(W.browser!==Z||W.digest!==c(O)||!Number.isFinite(W.expires)||!/^localweb:[a-f0-9]{48}$/.test(W.key))throw new Error("Confirmation does not match this browser and prompt.");let ae=r.db.db.prepare("SELECT id, admission_fingerprint FROM queue WHERE dedupe_key = ?").get(W.key);if(ae){if(ae.admission_fingerprint!==c(`math\0${O}`))throw new Error("Confirmation conflicts with an existing admission.");return k.redirect(`${o}/prompts/${ae.id}`,303)}if(W.expires<s()||W.target!==f())throw new Error("Confirmation expired or changed. Check the inbox before reviewing again; a previous uncertain admission may already exist.");q=!0;let be=s()-6e4;for(let[j,K]of a)K.start<be&&a.delete(j);let ne=a.get(Z)??{start:s(),count:0};if(ne.count>=10)return N(k,"Please wait",`<p>Ten prompts were queued this minute. Wait before retrying this unchanged confirmation.</p><pre>
557
- ${v(O)}</pre>${J(O,$)}`,429);let D=Aa(r.db.db,r.teams,{to:"math",prompt:O,dedupeKey:W.key});return D.replayed||(ne.count++,a.set(Z,ne)),k.redirect(`${o}/prompts/${D.queueId}`,303)}catch(M){return N(k,"Prompt not confirmed",`<p>${v(M.message)}</p><pre>
558
- ${v(O)}</pre>${q?J(O,$):""}<p>No new confirmation key was issued. For an uncertain result, retain the original confirmation and check the inbox before sending again. A server restart invalidates pending confirmations; known receipt URLs remain readable.</p><a href="${o}">Math inbox</a>`,400)}}),t.get("/comm/math/prompts/:id",k=>{let O=k.req.param("id"),$=Number(O);if(!/^[1-9]\d*$/.test(O)||!Number.isSafeInteger($))return N(k,"Not found","<p>Invalid prompt ID.</p>",404);let q=to(r,$);if(!q||q.to_id!=="math")return N(k,"Not found","<p>No Math inbox prompt at this address.</p>",404);let M=hs(r,$),Z=Ur(r,$),W=M.answer,ae=M.lifecycle==="finished"&&p(M.lifecycleBasis),be=v(q.retracted_reason??"no reason recorded"),ne=M.lifecycleBasis==="informational"?"This was an informational send; no answer is expected.":M.lifecycleBasis==="retracted"?`This prompt was retracted by its sender: ${be}. No answer is expected.`:"This prompt was combined into another prompt. The combined prompt ID is not recorded, so no link is available.",D=M.lifecycleBasis==="informational"?"No answer expected: this was an informational send.":M.lifecycleBasis==="retracted"?`No answer expected: this prompt was retracted. Reason: ${be}.`:"No separate answer: prompt combined into another prompt.";if(W&&W.prompt_queue_id!==$)return N(k,"Answer unavailable","<p>Answer correlation mismatch.</p>",503);let j="";if(e.enabled)try{f(),j=`<section id="compose" aria-label="Write a prompt" data-mount="${v(n)}" data-base="${v(o)}"><h2>Write another prompt</h2><p>Start a new prompt to ${C("math")}. Review the exact text before queueing it.</p>${P(m(k,!0))}</section>`}catch{}return N(k,`Math prompt #${$}`,`<p>Prompt #${$}: ${C(q.from_id)} \u2192 ${C(q.to_id)}. <span id="comm-receipt-summary">${W?"An answer is recorded below.":ae?ne:"No answer recorded yet."}</span></p>${b}<p>Work: no task association is recorded for this prompt. <a href="#assigned-work">Browse Math\u2019s current assigned work</a>.</p><p id="comm-state" role="status" aria-live="polite" data-sender="${v(q.from_id)}" data-recipient="${v(q.to_id)}" data-queue-id="${$}" data-mount="${v(n)}" data-lifecycle="${M.lifecycle}" data-lifecycle-basis="${M.lifecycleBasis}">${x(M)} \xB7 ${v(H(M))}</p><p><a href="${o}/prompts/${$}">Refresh state</a> \xB7 <a href="${o}">Math inbox</a></p>${j}<section aria-label="Prompt and answer sequence"><h2>Prompt and answer sequence</h2><article data-queue-id="${$}" data-event="request"><h3>Prompt text</h3><p>${C(q.from_id)} \u2192 ${C(q.to_id)} \xB7 queued ${fe(M.createdAt)}</p><details><summary>Prompt times</summary><p id="comm-handling-observation">Delivery attempted ${q.sent_ts?fe(q.sent_ts):"not recorded"} \xB7 Picked up ${q.retrieved_ts?fe(q.retrieved_ts):"not recorded"} </p><p>Answer recorded <span id="comm-reply-time">${W?fe(W.answered_at):"not recorded"}</span></p></details>${Z?.status==="available"?`<pre>
559
- ${v(Z.text)}</pre><p>${Z.truncated?"Preview truncated.":"Saved prompt text; availability may change."}</p>`:"<p>Prompt preview unavailable.</p>"}</article><article data-queue-id="${$}" data-event="response"><h3>Answer</h3><p id="comm-poll-notice" role="status" aria-live="polite">Live updates while this page is visible.</p><p id="comm-response-status">${ae?D:`${W?"Answer recorded":"Waiting for an answer"} in the ${C(q.to_id)} inbox for prompt #${$} from ${C(q.from_id)}.`}</p>${W?`<p id="comm-response-meta">Recorded ${fe(W.answered_at)} \xB7 answer #${W.id} to prompt #${W.prompt_queue_id}</p><pre id="comm-response">
560
- ${v(W.answer_text)}</pre><p id="comm-response-truncation">${W.truncated?`Truncated: ${W.byteLength} of ${W.totalBytes} bytes. No continuation endpoint is available.`:`${W.byteLength} bytes returned.`}</p>`:`<p id="comm-response-meta"></p><pre id="comm-response" hidden></pre><p id="comm-response-truncation"></p><p id="comm-response-none">${ae?"":"No correlated answer recorded yet. Refresh to check again."}</p>`}</article></section><div id="assigned-work">${w()}</div>`)}),t}import{basename as xD}from"node:path";var ed=50,RD=e=>e.trim().toLowerCase().replace(/[\s_]+/g,"-"),td=e=>["blocked","error","on-hold","rate-limited"].includes(RD(e));function SE(e){if(!/^[1-9]\d*$/.test(e)||!Number.isSafeInteger(Number(e)))throw new L("INVALID_ARGUMENT","Invalid positive integer ID");return Number(e)}function ND(e){let t={},r=new Set(["q","project","status","kind","team","attention","sort","page"]);for(let[n,o]of new URL(e).searchParams){if(!r.has(n)||Object.hasOwn(t,n)||o.length>256||/[\x00-\x1f\x7f]/.test(o))throw new L("INVALID_ARGUMENT","Invalid or duplicate task filter");t[n]=o}if(t.page&&SE(t.page)>Ie)throw new L("INVALID_ARGUMENT","Page exceeds safety limit");if(t.attention&&t.attention!=="1")throw new L("INVALID_ARGUMENT","attention must be 1");if(t.sort&&!["id","updated"].includes(t.sort))throw new L("INVALID_ARGUMENT","Unknown task sort");if(t.kind&&!["epic","task","subtask"].includes(t.kind))throw new L("INVALID_ARGUMENT","Unknown task kind");return t}function yE(e,t){let r=new URLSearchParams(Object.entries(t).filter(([,n])=>n!==""));return e+(r.size?`?${r}`:"")}function ID(e,t,r,n){let o=e.filter(f=>(!t.q||`${f.id} ${f.title} ${f.description} ${f.requirements} ${f.acceptance_criteria}`.toLowerCase().includes(t.q.toLowerCase()))&&(!t.attention||td(f.status))&&(!n||f.owner_team_path===n));o.sort(t.sort==="updated"?(f,p)=>Date.parse(p.updated_at)-Date.parse(f.updated_at)||f.id-p.id:(f,p)=>f.id-p.id);let s=Number(t.page||1),i=o.slice((s-1)*ed,s*ed),a=new Map(e.map(f=>[f.id,f])),c=f=>{if(f===null)return;let p=a.get(f)??r(f);return a.set(f,p),p},l=new Map(i.map(f=>[f.id,{...f,context:!1}]));for(let f of i){let p=c(f.parent_id),h=new Set([f.id]);for(;p&&!h.has(p.id);)h.add(p.id),l.has(p.id)||l.set(p.id,{...p,context:!0}),p=c(p.parent_id)}let u=new Map;for(let f of l.values()){let p=f.parent_id!==null&&l.has(f.parent_id)?f.parent_id:null,h=u.get(p)??[];h.push(f),u.set(p,h)}let d=[],m=f=>{for(let p of u.get(f)??[])d.push(p),m(p.id)};return m(null),{rows:d,total:o.length,pageNumber:s,more:o.length>s*ed,byId:a}}function ao(e,t){return Ne(`${t}/tasks/${e.id}`,`#${e.id} ${e.title}`)}function vE(e,t,r){if(e.owner_team_path===null)return"Unassigned";let n=`${xD(e.owner_team_path)}:${e.owner_alias}`,o=`${e.owner_team_path}:${e.owner_alias}`,s=t.get(e.owner_team_path);return s&&e.owner_alias?`<a href="${v(`${r}/sessions/${encodeURIComponent(s)}/${encodeURIComponent(e.owner_alias)}`)}" title="${v(o)}">${v(n)}</a>`:`<span title="${v(o)}">${v(n)}</span>`}function AE(e){if(e.blocked_on!==null){let t=e.blocked_on==="operator"?"Operator":e.blocked_on;return`<span class="status-chip status-processing" title="blocked_on names who this task is waiting on; independent of the recorded status text">Blocked on ${v(t)}</span>`}if(e.hold_until!==null){let t=Date.parse(e.hold_until)<=Date.now(),r=e.hold_reason?` \u2014 ${v(e.hold_reason)}`:"";return t?`<span class="status-chip status-processing" title="Hold expired ${v(e.hold_until)}; not auto-cleared, needs the owning team to resolve it">Hold expired, evidence due${r}</span>`:`<span class="status-chip status-muted">On hold until ${fe(e.hold_until)}${r}</span>`}return"\u2014"}function EE(e,t,r,n,o="Task ledger"){return so(["Task / hierarchy","Project","Recorded status","Blocked / hold","Recorded owner","Updated","Presentation"],e.map(s=>{let i=[],a=s.parent_id===null?void 0:t.get(s.parent_id),c=new Set([s.id]);for(;a&&!c.has(a.id);)c.add(a.id),i.unshift(a),a=a.parent_id===null?void 0:t.get(a.parent_id);let l=i.map(u=>ao(u,r)).join(" / ");return[`${l?`${l}<br>`:""}${ao(s,r)}${s.context?" <strong>(ancestor context)</strong>":""}<br>${v(s.kind)}`,v(s.project),v(s.status),AE(s),vE(s,n,r),fe(s.updated_at),s.kind==="epic"?"Not applicable":s.delivered_ts?`First presented ${fe(s.delivered_ts)}`:"Not recorded"]}),o)}function bE(e,t,r){let n=["q","project","status"].map(i=>`<label>${{q:"Search",project:"Project",status:"Exact recorded status"}[i]}<input name="${i}" value="${v(e[i]??"")}" maxlength="256"></label>`).join(""),o=(i,a,c)=>`<label>${a}<select name="${i}">${c.map(([l,u])=>`<option value="${v(l)}"${e[i]===l?" selected":""}>${v(u)}</option>`).join("")}</select></label>`,s=[["",`All teams (${t.length} own work in this scope)`],...t.map(i=>[i,i])];return`<form method="get" action="${v(r)}/tasks">${n}${o("kind","Kind",[["","All kinds"],["epic","Epic"],["task","Task"],["subtask","Subtask"]])}${o("team","Owning team",s)}${o("sort","Sort",[["id","ID"],["updated","Updated"]])}<label>Attention only<input type="checkbox" name="attention" value="1"${e.attention?" checked":""}></label><button>Filter tasks</button> ${Ne(`${r}/tasks`,"Clear filters")}</form>`}function TE(e){return`<p>${e.total} entities in this scope: ${e.by_kind.epic??0} epics, ${e.by_kind.task??0} tasks, ${e.by_kind.subtask??0} subtasks.</p>`}function $E(e,t,r=""){let n=r.replace(/\/$/,""),o=(i,a,c,l=200)=>De(i,$e(a,c,n,{"data-page":"tasks"}),l),s=(i,a)=>{let c=a instanceof L?a.code==="NOT_FOUND"?404:a.code==="DB_BUSY"?503:a.code==="STORAGE_ERROR"?500:a.code==="CONFLICT"?409:400:500;return o(i,"Tasks unavailable",`<p>${v(a instanceof Error?a.message:String(a))}</p>${Ne(`${n}/tasks`,"Task ledger")}`,c)};e.get("/tasks",i=>{try{let a=ND(i.req.url),c;if(a.team){let p=t.teams.find(h=>h.name===a.team&&B(h));if(!p||!B(p))throw new L("INVALID_ARGUMENT","Unknown local owning team");c=Q(p)}let l=kr(t.db.db,{...a.project?{project:a.project}:{},...a.kind?{kind:a.kind}:{},...a.status?{status:a.status}:{},limit:Ie}),u=qr(t.teams),d=[...new Set(l.rows.map(p=>p.owner_team_path).filter(p=>p!==null).map(p=>u.get(p)).filter(p=>p!==void 0))].sort();if(l.meta.next_cursor!==null)return o(i,"Tasks",'<p class="warning">This scope exceeds 10,000 entities. Choose a project, kind, or status to narrow it; an incomplete board is not shown.</p>'+bE(a,d,n),503);let m=ID(l.rows,a,p=>xr(t.db.db,p),c),f=`<nav aria-label="Task pages">${m.pageNumber>1?Ne(yE(`${n}/tasks`,{...a,page:String(m.pageNumber-1)}),"Previous page"):""} ${m.more?Ne(yE(`${n}/tasks`,{...a,page:String(m.pageNumber+1)}),"Next page"):""}</nav>`;return o(i,"Tasks",'<p data-testid="page-intro">Epics group tasks, and tasks can contain subtasks; follow a title to read its details and children. Status and owner are recorded values; Updated means content activity; Attention means blocked, error, on-hold, or rate-limited; First presentation means when the item was first shown to an agent to work on, not completion. Blocked / hold is separate from the recorded status text: it shows when a task is structurally waiting on a specific team or operator, or deliberately parked until a date, even while its own status reads as ordinary active work.</p>'+TE({total:l.rows.length,by_kind:l.rows.reduce((p,h)=>(p[h.kind]=(p[h.kind]??0)+1,p),{})})+bE(a,d,n)+`<p>${m.total} matching entities. Page ${m.pageNumber}, up to 50 matches plus labeled ancestor context; presentation does not mean completion.</p>`+f+EE(m.rows,m.byId,n,u)+f)}catch(a){return s(i,a)}}),e.get("/tasks/:id",i=>{try{let a=SE(i.req.param("id")),c=xr(t.db.db,a),l=Rr(t.db.db,a),u=[],d=c.parent_id,m=new Set([a]);for(;d!==null&&!m.has(d);){m.add(d);let T=xr(t.db.db,d);u.unshift(T),d=T.parent_id}let f=qr(t.teams),p=new Map([...u,c,...l.children].map(T=>[T.id,T])),h=T=>T.length?`<ul>${T.map(R=>`<li>${ao(R,n)} \u2014 ${v(R.status)}</li>`).join("")}</ul>`:"<p>None recorded.</p>",g=`<nav aria-label="Breadcrumb">${Ne(`${n}/tasks`,"Task ledger")} / ${u.map(T=>Ne(`${n}/tasks/${T.id}`,`#${T.id} ${T.title} (status: ${T.status})`)).join(" / ")}${u.length?" / ":""}<span aria-current="page">#${c.id} ${v(c.title)}</span></nav>`,_=u.at(-1),E=u.find(T=>T.kind==="epic"),S=`<p data-testid="work-context">${c.kind==="epic"?"This is an epic with no parent.":c.kind==="task"?E?`This is a task in epic ${ao(E,n)}.`:"This is a task with no parent epic.":`This is a subtask${_?` of task ${ao(_,n)}`:""}${E?`, part of epic ${ao(E,n)}.`:"; no parent epic is recorded."}`}</p><p data-testid="page-intro">This page describes one work item and its recorded status and owner. Follow the breadcrumb to its parent or epic, or a child title to drill down; Updated records content activity, not completion.</p>`+g+`<p>Kind: ${v(c.kind)}; project: ${v(c.project)}; recorded status: <strong>${v(c.status)}</strong>.</p><p>Recorded owner: ${vE(c,f,n)}.</p><p>Blocked / hold: ${AE(c)}</p>`+["description","requirements","acceptance_criteria"].map(T=>`<h2>${{description:"Description",requirements:"Requirements",acceptance_criteria:"Acceptance criteria"}[T]}</h2><pre>${v(c[T]||"Not supplied")}</pre>`).join("")+TE(Nr(t.db.db,{id:a}))+"<h2>Children</h2>"+EE(l.children,p,n,f,"Immediate children")+"<h2>Depends on</h2>"+h(c.dependencies.outgoing)+"<h2>Required by</h2>"+h(c.dependencies.incoming)+`<h2>Times</h2><p>Created ${fe(c.created_at)}; updated ${fe(c.updated_at)}.</p><p>First presentation: ${c.kind==="epic"?"Not applicable":c.delivered_ts?fe(c.delivered_ts):"Not recorded"}. Presentation does not mean completion.</p>`;return o(i,`Task #${c.id}: ${c.title}`,S)}catch(a){return s(i,a)}})}import{basename as LD}from"node:path";var kE=50,xE='<p data-testid="page-intro">A cron job is work scheduled to run automatically; this page reviews its saved configuration and recorded results. An unresolved escalated run is waiting for a person to help, while execution uncertain means the process has not been confirmed stopped.</p>',CD={ok:"OK (last-fire bookkeeping)",error:"Error",skipped_overlap:"Skipped: earlier execution still guarded",skipped_stale:"Skipped: scheduled window too old",reconciled:"Process gone; outcome unknown",blocked_escalation:"Skipped: unresolved escalation at last check"},st=e=>e===null?"Not recorded":fe(e),Ze=e=>e===null?"Not configured":v(e),RE=e=>e.last_fire_status===null?"Not recorded":`${v(CD[e.last_fire_status]??e.last_fire_status)} <small>(${v(e.last_fire_status)})</small>`;function NE(e){let t=e.req.queries("after");if(t===void 0)return 0;let r=t[0]??"";if(t.length!==1||!/^(0|[1-9]\d*)$/.test(r)||!Number.isSafeInteger(Number(r)))throw new U("INVALID_ARGUMENT","after must be a nonnegative integer");return Number(r)}function IE(e,t,r){if(e.session_teamfile===null||e.session_alias===null)return"Not configured";let n=`${e.session_teamfile}:${e.session_alias}`,o=`${LD(e.session_teamfile)}:${e.session_alias}`,s=t.get(e.session_teamfile);return s?`<a href="${v(`${r}/sessions/${encodeURIComponent(s)}/${encodeURIComponent(e.session_alias)}`)}" title="${v(n)}">${v(o)}</a>`:`<span title="${v(n)}">${v(o)}</span> (not in the current local registry)`}function LE(e,t){let r=[];return(e.last_fire_status==="error"||e.last_fire_error)&&r.push("Recorded fire error"),e.last_fire_status==="blocked_escalation"&&r.push("Last check blocked by escalation"),e.last_fire_status==="reconciled"&&r.push("Previous execution outcome unknown"),t?.status==="escalated"&&t.escalation_resolved_at===null&&r.push(`Run #${t.id}: escalated \u2014 waiting for a person`),t?.execution_state==="uncertain"&&r.push(`Run #${t.id}: execution uncertain`),t?.status==="failed"&&r.push(`Run #${t.id}: failed; execution still guarded`),r}function rd(e){return`<dl>${e.map(([t,r])=>`<dt>${v(t)}</dt><dd>${r}</dd>`).join("")}</dl>`}function OD(e){if(e===null)return"<p>No artifacts recorded.</p>";try{let t=JSON.parse(e);if(Array.isArray(t)&&t.every(r=>typeof r=="string"))return t.length?`<ul>${t.map(r=>`<li>${v(r)}</li>`).join("")}</ul>`:"<p>No artifacts recorded.</p>"}catch{}return`<pre>${v(e)}</pre>`}function DD(e){let t=e.status==="escalated",r=t&&e.escalation_resolved_at===null,n=e.status==="failed"||r||e.execution_state==="uncertain",o=`${e.status}${t?r?" \u2014 waiting for a person":" \u2014 escalation resolved":""}`,s=t||e.escalation_reason!==null||e.escalation_resolved_at!==null?"<h4>Escalation</h4>"+rd([["Reason",Ze(e.escalation_reason)],["Requested action",Ze(e.escalation_action)],["Owner",Ze(e.escalation_owner)],["Resolved at",st(e.escalation_resolved_at)],["Resolution",Ze(e.escalation_resolution)],["Resolved by",Ze(e.escalation_resolution_actor)],["Resolution note",Ze(e.escalation_resolution_note)]]):"";return`<article id="run-${e.id}"${n?' class="warning"':""}><h3>Run #${e.id}: ${v(o)}</h3>`+rd([["Execution state",v(e.execution_state)],["Trigger",v(e.trigger_kind)],["Created",st(e.created_at)],["Started",st(e.started_at)],["Finished",st(e.finished_at)],["Result reported",st(e.reported_at)],["Last updated",st(e.updated_at)],["Execution reference",Ze(e.execution_identity)],["Process ID",Ze(e.pid)],["Execution uncertainty reason",Ze(e.execution_uncertain_reason)],["Execution confirmed gone",st(e.execution_gone_at)],["Confirmation note",Ze(e.execution_confirmation_note)]])+`<h4>Summary</h4><pre>${v(e.summary??"No summary recorded.")}</pre><h4>Artifacts (recorded paths or references)</h4>`+OD(e.artifacts)+s+"</article>"}function CE(e,t,r=""){let n=r.replace(/\/$/,""),o=(a,c,l,u=200)=>De(a,$e(c,l,n),u),s=(a,c)=>{let l=c instanceof U?c.code==="NOT_FOUND"?404:c.code==="DB_BUSY"?503:c.code==="INVALID_ARGUMENT"?400:500:500;return o(a,"Cron review unavailable",`<p>${v(c instanceof Error?c.message:String(c))}</p>${Ne(`${n}/cron`,"Cron jobs")}`,l)},i=(a,c,l)=>`<nav aria-label="Cron pages">${c?Ne(a,"First page"):""} ${l!==null?Ne(`${a}?after=${l}`,"Next page"):""}</nav>`;e.get("/cron",a=>{try{let c=NE(a),l=Ji(t.db.db,{limit:kE,after:c}),u=qr(t.teams),d=l.rows.map(f=>({job:f,flags:LE(f,fr(t.db.db,f.id))})),m=(f,p)=>so(["Job","Schedule / timezone","Action kind","Enabled","Last fire status","Last fired","Scheduler last looked at","Last fire error","Session"],f.map(({job:h,flags:g})=>[Ne(`${n}/cron/${h.id}`,`#${h.id} ${h.title}`)+(g.length?`<p class="warning"><strong>${g.map(v).join("<br>")}</strong></p>`:""),`<code>${v(h.schedule_expr)}</code><br>${v(h.timezone??"Host-local timezone")}`,v(h.action_kind),h.enabled?"Enabled":"Disabled",RE(h),st(h.last_fired_ts),st(h.last_checked_ts),h.last_fire_error===null?"None recorded":`<pre>${v(h.last_fire_error)}</pre>`,IE(h,u,n)]),p);return o(a,"Cron jobs",xE+"<p>Saved jobs, up to 50 per page in ID order. Times below are stored scheduler records; OK is not proof of successful AI work. A retained error can predate a later skipped check.</p><h2>Failures and review flags</h2>"+m(d.filter(f=>f.flags.length>0),"Jobs with review flags on this page")+"<h2>Other jobs</h2>"+m(d.filter(f=>f.flags.length===0),"Other jobs on this page")+i(`${n}/cron`,c,l.meta.next_cursor))}catch(c){return s(a,c)}}),e.get("/cron/:id",a=>{try{let c=a.req.param("id");if(!/^[1-9]\d*$/.test(c)||!Number.isSafeInteger(Number(c)))throw new U("INVALID_ARGUMENT","Invalid positive job ID");let l=NE(a),u=Le(t.db.db,Number(c)),d=Hi(t.db.db,{jobId:u.id,limit:kE,after:l}),m=fr(t.db.db,u.id),f=LE(u,m),p=rd([["Title",v(u.title)],["Schedule expression",`<code>${v(u.schedule_expr)}</code>`],["Timezone",v(u.timezone??"Host-local timezone")],["Action kind",v(u.action_kind)],["Enabled",u.enabled?"Enabled":"Disabled"],["Provider",Ze(u.provider)],["Model",Ze(u.model)],["Working directory",Ze(u.working_directory)],["Escalation owner",Ze(u.escalation_owner)],["Session",IE(u,qr(t.teams),n)],["Session teamfile",Ze(u.session_teamfile)],["Session alias",Ze(u.session_alias)],["Session seeded at",st(u.session_seeded_at)],["Session generation",v(u.session_generation)],["Scheduler last looked at",st(u.last_checked_ts)],["Last fired",st(u.last_fired_ts)],["Last fire status",RE(u)],["Last fire error",u.last_fire_error===null?"None recorded":`<pre>${v(u.last_fire_error)}</pre>`],["Recorded execution since",st(u.running_since_ts)],["Recorded systemd unit",Ze(u.running_systemd_unit)],["Created",st(u.created_at)],["Updated",st(u.updated_at)],["Revision",v(u.revision)]]),h=m?`<p>${Ne(`${n}/cron/${u.id}?after=${m.id-1}#run-${m.id}`,`Inspect guarded run #${m.id}`)} \u2014 ${v(m.status)}, execution ${v(m.execution_state)}.</p>`:"",g=l?"<p>No more run records after this cursor.</p>":"<p>No run history recorded. Command or script jobs may have last-fire records without run history; an empty history is not itself an error.</p>";return o(a,`Cron job #${u.id}: ${u.title}`,xE+`<p>${Ne(`${n}/cron`,"All cron jobs")}</p>`+(f.length?`<p class="warning"><strong>${f.map(v).join("<br>")}</strong></p>`:"")+h+"<h2>Configuration</h2>"+p+`<h3>Action payload (command, script, prompt, or enqueue data)</h3><pre>${v(u.action_payload)}</pre><h2>Run history</h2><p>Up to 50 recorded runs, oldest ID first. Outcome and process state are separate: active is recorded as active, uncertain is not confirmed stopped, and gone is confirmed stopped.</p>`+(d.rows.length?d.rows.map(DD).join(""):g)+i(`${n}/cron/${u.id}`,l,d.next_cursor))}catch(c){return s(a,c)}})}function MD(e,t){return t===null&&e.retracted_ts===null&&(e.status==="pending"||e.status==="escalating"||e.status==="sent"||e.status==="retrieved")}var DE=64*1024;async function PD(e){if(!e.req.header("content-type")?.toLowerCase().startsWith("application/x-www-form-urlencoded"))throw new L("INVALID_ARGUMENT","Expected a browser form.");let t=e.req.raw.body?.getReader();if(!t)throw new L("INVALID_ARGUMENT","Missing form.");let r=0,n=[];for(;;){let{done:i,value:a}=await t.read();if(i)break;if(r+=a.byteLength,r>DE)throw await t.cancel(),new L("INVALID_ARGUMENT","Form exceeds the size limit.");n.push(a)}let s=new URLSearchParams(Buffer.concat(n).toString("utf8")).getAll("answer");if(s.length!==1)throw new L("INVALID_ARGUMENT","Missing or duplicate answer field.");return s[0]}function ME(e,t){let r=[t.from_id,t.to_id,t.escalation_only,t.to_alias],o=e.prepare("SELECT MIN(id) AS id FROM queue WHERE from_id = ? AND to_id = ? AND escalation_only = ? AND to_alias IS ? AND id > ? AND status != 'merged'").get(...r,t.id).id??Number.MAX_SAFE_INTEGER;return e.prepare("SELECT * FROM queue WHERE from_id = ? AND to_id = ? AND escalation_only = ? AND to_alias IS ? AND status = 'merged' AND id > ? AND id < ?").all(...r,t.id,o)}function PE(e,t){let r=[];t.retracted_ts!==null&&t.retracted_reason&&r.push(t.retracted_reason);let n=ME(e,t);for(let o of n)o.retracted_ts!==null&&o.retracted_reason&&r.push(o.retracted_reason);return r}function nd(e,t=Date.now()){return ss(e,t).map(n=>{let o=n.row,s=un(e,o),i=os(e,o),a=n.ageMs>=cs||s>=2&&o.sent_ts===null,c=PE(e,o);return{row:o,constituentCount:s,retractedCount:i,urgent:a,retractedReasons:c}})}function UE(e){return e===1?"1 of 1":`${e} merged into this one`}function UD(e){return e==="merged"||e==="informational"||e==="retracted"}function FD(e){return e.lifecycle==="queued"?"queued":e.lifecycle==="processing"?"processing":UD(e.lifecycleBasis)?"muted":"replied"}function qD(e){return e.lifecycle==="queued"?"Queued":e.lifecycle==="processing"?"Processing":e.lifecycleBasis==="merged"?"Combined":e.lifecycleBasis==="informational"?"Informational":e.lifecycleBasis==="retracted"?"Retracted":"Replied"}function FE(e){return`<span class="status-chip status-${FD(e)}" title="${v(od(e))}">${v(qD(e))}</span>`}function od(e){return e.lifecycle==="queued"?"Queued \u2014 waiting for handling":e.lifecycle==="processing"?e.lifecycleBasis==="confirmed"?"Processing \u2014 picked up by inbox":"Processing \u2014 delivery attempted; read not confirmed":e.lifecycle==="finished"?e.lifecycleBasis==="retracted"?"Finished \u2014 retracted":e.lifecycleBasis==="merged"?"Finished \u2014 combined with another prompt":e.lifecycleBasis==="informational"?"Finished \u2014 informational, no answer expected":"Finished \u2014 answer recorded":`${e.lifecycle} (${e.lifecycleBasis})`}function jD(e){return`<dl>${e.map(([t,r])=>`<dt>${v(t)}</dt><dd>${r}</dd>`).join("")}</dl>`}function HD(e){return e.length===0?"<p>No standing decisions recorded.</p>":e.map(t=>{let r=t.would_change_it?`<p><strong>Would change this:</strong> ${v(t.would_change_it)}</p>`:"<p><strong>Would change this:</strong> Not recorded.</p>",n=t.affects.length>0?t.affects.map(v).join(", "):"Not recorded";return`<article aria-label="Decision #${t.id}"><h3>${v(t.subject)}</h3><p>${v(t.decision)}</p>${r}<details><summary>Reasoning</summary><p>${v(t.reasoning)}</p></details><p>Decided by ${v(t.decided_by)}, ${fe(t.decided_at)}. Affects: ${n}.</p></article>`}).join("")}function BD(e){return e.length===0?"<p>Nothing blocking math right now.</p>":e.map(t=>`<article aria-label="Blocked #${t.id}"><h3>!!! ${v(t.title)}</h3><p>Category: ${v(t.category)}.</p>${t.detail?`<p>${v(t.detail)}</p>`:""}<p>Raised by ${v(t.raised_by)}, ${fe(t.raised_at)}.</p></article>`).join("")}function WD(e,t){return e.length===0?"<p>No open judgment calls for the operator.</p>":e.map(r=>{let n=r.downstream?`<p><strong>Downstream:</strong> ${v(r.downstream)}</p>`:"<p><strong>Downstream:</strong> Not recorded.</p>";return`<article aria-label="Ask #${r.id}"><h3>${v(r.subject)}</h3><p>${v(r.reason)}</p>${n}<p>Status: Open. Raised by ${v(r.raised_by)}, ${fe(r.raised_at)}.</p><p><a href="${v(t)}/comm/math?ask=${r.id}#compose">Discuss this with math</a></p></article>`}).join("")}function OE(e,t,r,n){if(e.length===0)return`<p>No ${t.toLowerCase()}.</p>`;let o=["Prompt","From","Age","Constituents","Retractions","Lifecycle"],s=e.map(i=>{let a=i.row,c=Oe(n,a.id),l=xt(a,c),u=`<a href="${v(r)}/operator/${a.id}">#${a.id}</a>`,d=v(a.from_id),m=fe(a.created_ts),f=UE(i.constituentCount),p=i.retractedCount>0?`${i.retractedCount} retracted${i.retractedReasons.length>0?`: ${i.retractedReasons.map(g=>`\u201C${v(g)}\u201D`).join("; ")}`:""}`:"\u2014",h=`${FE(l)} \xB7 ${v(od(l))}`;return[u,d,m,f,p,h]});return so(o,s,t)}function qE(e,t,r=""){let n=r.replace(/\/$/,"");e.get("/operator",o=>{try{let s=nd(t.db.db,Date.now()),i=s.filter(g=>g.urgent),a=s.filter(g=>!g.urgent),c='<p data-testid="page-intro">What needs the operator, what math has already decided for them to review, and a way to reach math directly. Blocked means math is technically incapable of proceeding (re-auth, billing, account identity) -- rare and urgent. Escalations are requests a team sent that genuinely need a decision, shown whether or not anyone is currently monitoring them; urgent means waiting over four hours, or never delivered despite repeated sends. Constituents counts how many separate escalations were folded into one message; Retractions counts how many of those the sender has since withdrawn, with their stated reason. Asks are judgment calls only the operator can make, routine, not urgent -- problem statement, then what it affects downstream, then who raised it. Decisions are rulings math has already made, for review, not approval.</p>',l=`<section class="warning" aria-label="Urgent escalations"><h2>Urgent escalations</h2>${OE(i,"Urgent escalations",n,t.db.db)}</section>`,u=`<section aria-label="Routine escalations"><h2>Routine escalations</h2>${OE(a,"Routine escalations",n,t.db.db)}</section>`,d=`<section aria-label="Send a message"><h2>Send a message</h2><p>Start a new request to math. This reuses the same queue and composer as <a href="${v(n)}/comm/math">the Math inbox</a> -- one write path, not a second one.</p><p><a href="${v(n)}/comm/math#compose">Write a message to math</a></p></section>`,m,f,p;try{let g=$a(),_,E,y;try{_=gE(g),E=pE(g),y=fE(g)}finally{g.close()}m=`<section class="warning" aria-label="Blocked"><h2>Blocked</h2>${BD(_)}</section>`,f=`<section aria-label="Asks"><h2>Asks</h2>${WD(E,n)}</section>`,p=`<section aria-label="Decisions"><h2>Decisions</h2><p>Rulings math has already made, in force now (superseded and reversed decisions are excluded). Nothing here waits on you -- read, and ping math if you disagree.</p>${HD(y)}</section>`}catch(g){let _=`<p class="warning">lmteam data unavailable: ${v(g instanceof Error?g.message:String(g))}</p>`;m=`<section class="warning" aria-label="Blocked"><h2>Blocked</h2>${_}</section>`,f=`<section aria-label="Asks"><h2>Asks</h2>${_}</section>`,p=`<section aria-label="Decisions"><h2>Decisions</h2>${_}</section>`}let h=`${c}${m}${l}${f}${d}${u}${p}`;return De(o,$e("Operator inbox",h,n,{"data-page":"operator"},[],!0))}catch(s){return De(o,$e("Operator inbox unavailable",`<p>${v(s instanceof Error?s.message:String(s))}</p>`,n,{},[],!0),500)}}),e.get("/operator/:id",o=>{let s=o.req.param("id"),i=Number(s);if(!s||!/^[1-9]\d*$/.test(s)||!Number.isSafeInteger(i))return De(o,$e("Invalid escalation ID",`<p>Invalid escalation ID.</p><p><a href="${v(n)}/operator">Operator inbox</a></p>`,n,{},[],!0),400);try{let a=vr(t.db.db,i);if(!a||a.to_id!=="operator")return De(o,$e("Not found",`<p>No operator escalation at this address.</p><p><a href="${v(n)}/operator">Operator inbox</a></p>`,n,{},[],!0),404);let c=Ur(t,i),l=Oe(t.db.db,i),u=xt(a,l),d=un(t.db.db,a),m=os(t.db.db,a),f=PE(t.db.db,a),p=[["From",v(a.from_id)],["To",v(a.to_id)],["Queued",fe(a.created_ts)],["Lifecycle",`${FE(u)} \xB7 ${v(od(u))}`],["Constituents",v(UE(d))],["Delivery attempted",a.sent_ts?fe(a.sent_ts):"not recorded"],["Picked up",a.retrieved_ts?fe(a.retrieved_ts):"not recorded"],["Subject",a.subject_id?v(a.subject_id):"none"]];m>0&&p.push(["Retractions",`${m} retracted${f.length>0?`: ${f.map(S=>`\u201C${v(S)}\u201D`).join("; ")}`:""}`]),a.retracted_ts!==null&&(p.push(["Retracted at",fe(a.retracted_ts)]),p.push(["Retraction reason",v(a.retracted_reason??"(none)")]));let h="";c?.status==="available"?h=`<pre>${v(c.text)}</pre><p>${c.truncated?`Preview truncated (${c.byteLength} bytes).`:`Full content (${c.byteLength} bytes).`}</p>`:h=`<p>Prompt preview unavailable (${v(c?.status??"missing")}).</p>`;let g="";l?g=`<section><h2>Answer</h2><p>Recorded ${fe(l.answered_at)}</p><pre>${v(l.answer_text)}</pre></section>`:MD(a,l)&&(g=`<section aria-label="Answer"><h2>Answer</h2><form method="post" action="${v(n)}/operator/${i}/answer"><label for="answer">Answer text</label><textarea id="answer" name="answer" rows="8" maxlength="${DE}" required></textarea><button>Send answer</button></form></section>`);let _=ME(t.db.db,a),E="";_.length>0&&(E=`<section><h3>Merged constituents (${_.length})</h3><p>Additional escalations folded into this message:</p><ul>${_.map(S=>`<li><a href="${v(n)}/operator/${S.id}">#${S.id}</a> from ${v(S.from_id)} (queued ${fe(S.created_ts)})${S.retracted_ts?` \u2014 <strong>Retracted</strong>: \u201C${v(S.retracted_reason)}\u201D`:""}</li>`).join("")}</ul></section>`);let y=`<p><a href="${v(n)}/operator">Operator inbox</a></p>
550
+ })();`;var _E=$e("","","").match(/<style>([\s\S]*?)<\/style>/),SD=Zu("sha256").update(_E?_E[1]:"").digest("base64"),vD=Zu("sha256").update(ka).digest("base64"),AD=`default-src 'none'; style-src 'sha256-${SD}'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'; script-src 'sha256-${vD}'; connect-src 'self'`,Xu="lmbee_comm_browser",$D=64*1024,kD=256*1024,io=class extends Error{};function wE(e){let t=new cn,{context:r}=e,n=(e.mountPath??"").replace(/\/$/,"");if(n&&(!/^\/[A-Za-z0-9_./~-]+$/.test(n)||n.startsWith("//")))throw new Error("Invalid mount path");let o=`${n}/comm/math`,s=e.now??Date.now,i=Qu(32),a=new Map,c=k=>Zu("sha256").update(k).digest("hex"),l=k=>ED("sha256",i).update(k).digest("base64url"),u=k=>{let O=Buffer.from(JSON.stringify(k)).toString("base64url");return`${O}.${l(O)}`};function d(k){let O=k.split(".");if(O.length!==2||k.length>4096)throw new Error("Invalid confirmation. Review the prompt again.");let $=Buffer.from(l(O[0])),q=Buffer.from(O[1]);if($.length!==q.length||!bD($,q))throw new Error("Invalid confirmation. Review the prompt again.");return JSON.parse(Buffer.from(O[0],"base64url").toString("utf8"))}function m(k,O=!1){let $=(k.req.header("cookie")??"").split(";").map(U=>U.trim()).filter(U=>U.startsWith(`${Xu}=`));if($.length===1)try{let U=d($[0].slice(Xu.length+1));if(typeof U.browser=="string"&&/^[a-f0-9]{48}$/.test(U.browser))return U.browser}catch{}if(!O)throw new Error("Browser confirmation expired. Open the Math inbox and review again.");let q=Qu(24).toString("hex");return k.header("Set-Cookie",`${Xu}=${u({browser:q})}; Path=${o}; HttpOnly; SameSite=Strict${new URL(k.req.url).protocol==="https:"?"; Secure":""}`),q}function f(){let k=r.teams.find(O=>O.name==="math");if(!k||!B(k)||k.leadAlias!=="Lead")throw new Error("The local math Lead inbox is unavailable.");return`${Q(k)}:Lead`}function p(k){return k==="merged"||k==="informational"||k==="retracted"}function h(k){return k.answeredAt?`<a href="${o}/prompts/${k.id}#comm-response">Answer to #${k.id}</a> \xB7 ${fe(k.answeredAt)}`:k.lifecycleBasis==="merged"?"No separate answer (merged)":k.lifecycleBasis==="informational"?"No answer expected (informational)":k.lifecycleBasis==="retracted"?`No answer expected (retracted): ${v(k.retracted_reason??"no reason recorded")}`:"No answer recorded"}function g(k){for(let O of k.split(`
551
+ `)){let $=O.trim();if($)return $}return""}let _=80,E=2e3;function y(k,O){return k.length>O?`${k.slice(0,O)}\u2026`:k}function S(k){let O=g(k);return O?y(O,_):"(empty prompt)"}function T(k){return y(k.trim(),E)}function R(k){let O=Ur(r,k),$=`Prompt #${k}`;return!O||O.status!=="available"||O.text===null?`<a href="${o}/prompts/${k}">${v($)}</a>`:`<a href="${o}/prompts/${k}" title="${v(T(O.text))}">${v(S(O.text))}</a>`}function A(k){return k.lifecycle==="queued"?"queued":k.lifecycle==="processing"?"processing":p(k.lifecycleBasis)?"muted":"replied"}function I(k){return k.lifecycle==="queued"?"Queued":k.lifecycle==="processing"?"Processing":k.lifecycleBasis==="merged"?"Combined":k.lifecycleBasis==="informational"?"Informational":k.lifecycleBasis==="retracted"?"Retracted":"Replied"}function x(k){return`<span class="status-chip status-${A(k)}" title="${v(H(k))}">${v(I(k))}</span>`}function H(k){return k.lifecycle==="queued"?"Queued \u2014 waiting for handling":k.lifecycle==="finished"?k.lifecycleBasis==="merged"?"Finished \u2014 combined with another prompt":k.lifecycleBasis==="informational"?"Finished \u2014 informational, no answer expected":k.lifecycleBasis==="retracted"?"Finished \u2014 retracted, no answer expected":"Finished \u2014 answer recorded":k.lifecycleBasis==="confirmed"?"Processing \u2014 picked up by inbox":"Processing \u2014 delivery attempted; read not confirmed"}function C(k){if(k==="operator")return"Operator";let O=Sn(k);if(O){let q=r.teams.find(U=>{if(!B(U))return!1;try{return Q(U)===O.teamfilePath}catch{return!1}});return q?`<a href="${v(`${n}/sessions/${encodeURIComponent(q.name)}/${encodeURIComponent(O.alias)}`)}" title="${v(k)}">${v(`${q.name}:${O.alias}`)}</a>`:`<span title="${v(k)}">${v(`${TD(O.teamfilePath)}:${O.alias}`)}</span>`}let $=r.teams.find(q=>q.name===k);return $&&B($)?`<a href="${v(`${n}/sessions/${encodeURIComponent($.name)}/${encodeURIComponent($.leadAlias)}`)}" title="${v(`Current configured lead for inbox ${k}`)}">${v(`${$.name}:${$.leadAlias}`)}</a>`:`${v(k)}${$?" (remote inbox)":" (not in the current team list)"}`}function w(){let k=r.teams.find(O=>O.name==="math");if(!k||!B(k))return'<section aria-label="Assigned work"><h2>Assigned work</h2><p>Math\u2019s current local actor is unavailable, so its assigned work cannot be resolved.</p></section>';try{let O=kr(r.db.db,{owner:{team:Q(k),alias:k.leadAlias},limit:5});return`<section aria-label="Assigned work"><h2>Assigned work</h2><p>Work owned by ${C("math")}. Open an item to follow its epic, parent task, or subtasks.</p>${O.rows.length?`<ul>${O.rows.map($=>`<li><a href="${n}/tasks/${$.id}">${v(`${$.kind} #${$.id}: ${$.title}`)}</a> \u2014 ${v($.status)}</li>`).join("")}</ul><p>Up to five assigned items shown.</p>`:"<p>No assigned work returned for this actor.</p>"}</section>`}catch{return'<section aria-label="Assigned work"><h2>Assigned work</h2><p>Current work ownership is unavailable. Prompt and answer records below remain readable.</p></section>'}}let b="<details><summary>About these records</summary><p>Actor links open each team\u2019s current configured lead; records identify inboxes and sender labels, not exact historical sessions. Assigned work is current ownership, not proof of execution or a prompt\u2019s topic. A delivery attempt does not confirm the inbox read a prompt. A recorded answer does not establish delivery back to the sender or task success.</p></details>";function N(k,O,$,q=200){return k.html($e(O,`${$}<script>${ka}</script>`,n,{},[ka]),q)}function M(k,O="",$=""){return`<div id="comm-composer-container"><p id="comm-composer-notice">${v($)}</p><form id="comm-draft-form" method="post" action="${o}/review"><input type="hidden" name="csrf" value="${v(u({browser:k,purpose:"review"}))}"><label for="prompt">Prompt for math Lead (maximum 64 KiB UTF-8)</label><textarea id="prompt" name="prompt" rows="8" required>
552
+ ${v(O)}</textarea><button type="submit">Review prompt</button></form></div>`}function W(k,O){return`<form method="post" action="${o}/prompts"><input type="hidden" name="confirmation" value="${v(O)}"><textarea name="prompt" hidden>
553
+ ${v(k)}</textarea><button type="submit">Retry this same confirmation</button></form>`}let ee=500;function oe(k){let O=k.req.query("ask");if(O!==void 0&&/^[1-9]\d*$/.test(O)){try{let q=$a(),U;try{U=hE(q,Number(O))}finally{q.close()}if(U){let Z=U.downstream?v(U.downstream):"Not recorded";return`<div id="comm-reply-context" aria-label="Replying to"><p><strong>Replying to ask:</strong> ${v(U.subject)}</p><p>${v(U.reason)}</p><p><strong>Downstream:</strong> ${Z}</p></div>`}}catch{}return""}let $=k.req.query("reply_to");if($!==void 0&&/^[1-9]\d*$/.test($)){let q=to(r,Number($));if(q){let U=Ur(r,q.id),Z=U?.status==="available"&&U.text!==null?y(U.text.trim(),ee):"(preview unavailable)";return`<div id="comm-reply-context" aria-label="Replying to"><p><strong>Replying to</strong> a prompt from ${C(q.from_id)}, ${fe(q.created_ts)}:</p><pre>${v(Z)}</pre></div>`}}return""}async function J(k){if(!k.req.header("content-type")?.toLowerCase().startsWith("application/x-www-form-urlencoded"))throw new Error("Expected a browser form.");let O=k.req.raw.body?.getReader();if(!O)throw new Error("Missing form.");let $=0,q=[];for(;;){let{done:Z,value:G}=await O.read();if(Z)break;if($+=G.byteLength,$>kD)throw await O.cancel(),new Error("Form exceeds the size limit.");q.push(G)}let U=new URLSearchParams(Buffer.concat(q).toString("utf8"));for(let Z of U.keys())if(U.getAll(Z).length!==1)throw new Error("Duplicate form field.");return U}function se(k){let O=k.get("prompt")??"";if(!O.trim()||Buffer.byteLength(O)>$D)throw new Error("Enter a nonblank prompt of at most 64 KiB UTF-8.");return O}return t.use("/comm/math/*",async(k,O)=>{k.header("Cache-Control","no-store"),k.header("Content-Security-Policy",AD),k.header("Referrer-Policy","same-origin"),k.header("X-Content-Type-Options","nosniff");let $=new URL(k.req.url),q=`${$.protocol}//${k.req.header("host")??$.host}`,U=k.req.header("sec-fetch-site");if(!e.allowedOrigins.includes(q)||U&&U!=="same-origin"&&U!=="none"||k.req.header("origin")!==void 0&&k.req.header("origin")!==q||k.req.method==="POST"&&k.req.header("origin")!==q)return N(k,"Request rejected","<p>Use this browser\u2019s local Math inbox page.</p>",403);await O()}),t.get("/comm/math",k=>{let O="<p>Sending is not enabled on this surface.</p>";if(e.enabled)try{f(),O=M(m(k,!0))}catch(U){O=`<p>${v(U.message)}</p>`}let $=k.req.query("after");if($!==void 0&&(!/^[1-9]\d*$/.test($)||!Number.isSafeInteger(Number($))))return N(k,"Invalid page","<p>Invalid prompt cursor.</p>",400);let q=ba(r,{toId:"math",limit:20,...$?{after:Number($)}:{}});return N(k,"Math inbox",`<p>Prompts to ${C("math")} and the answers recorded against them. Select a prompt to follow the exchange; use assigned work to explore the tasks this actor owns.</p>${b}<p><a href="${o}">Refresh inbox</a> \xB7 <a href="#compose">Write a prompt</a> \xB7 <a href="${n}/sessions/math/Lead">Math session</a></p><section id="compose" aria-label="Write a prompt" data-mount="${v(n)}" data-base="${v(o)}"><h2>Write a prompt</h2><p>Start a new prompt to ${C("math")}. Review the exact text before queueing it.</p>${oe(k)}${O}</section>${w()}<section id="history" aria-label="Prompts and answers"><h2>Incoming prompts and answers</h2><p>Only prompts addressed to Math appear here. <a href="${n}/sessions/math/Lead#comm-sequence">See incoming and outgoing exchanges</a> in the session timeline.</p><p>Newest 20 matching prompts first. Queued means waiting; processing records a pull or dispatch attempt; finished means an answer was recorded, an informational send expected no answer, or prompts from the same sender to the same recipient were combined to avoid separate deliveries. Finished for a combined prompt does not mean separate work was done, and no separate answer is expected. The combined prompt ID is not recorded, so no link is available.</p><table><thead><tr><th>Prompt</th><th>Actors</th><th>Handling</th><th>Queued</th><th>Answer</th></tr></thead><tbody>${q.rows.map(U=>`<tr data-queue-id="${U.id}"><td>${R(U.id)}</td><td>${C(U.from_id)} \u2192 ${C(U.to_id)}</td><td>${x(U)} \xB7 ${v(H(U))}</td><td>${fe(U.created_ts)}</td><td>${h(U)}</td></tr>`).join("")}</tbody></table><p>Task links for these prompts: not recorded.</p>${q.meta.next_cursor?`<a href="${o}?after=${q.meta.next_cursor}">Older prompts</a>`:""}</section>`)}),t.post("/comm/math/review",async k=>{if(!e.enabled)return N(k,"Sending unavailable","<p>Sending is not enabled.</p>",403);let O="",$="";try{let q=await J(k);O=q.get("prompt")??"";let U;try{U=m(k)}catch(ae){throw new io(ae.message)}$=U;let Z;try{Z=d(q.get("csrf")??"")}catch(ae){throw new io(ae.message)}if(Z.browser!==U||Z.purpose!=="review")throw new io("Review form no longer matches this browser session. Reloading will renew it.");O=se(q);let G={browser:U,digest:c(O),target:f(),key:`localweb:${Qu(24).toString("hex")}`,expires:s()+3e5};return N(k,"Review prompt to math",`<div id="comm-review-panel"><p>New prompt: Operator \u2192 ${C("math")}. Task link: none.</p><p>Queue one prompt for math to handle on its next pull. Processing may wait; the agent may use its existing file/network permissions.</p><p>Recipient: <a href="${v(`${n}/sessions/math/Lead`)}" title="${v(G.target)}">math:Lead</a></p><pre id="comm-review-preview">
554
+ ${v(O)}</pre><form id="comm-confirm-form" method="post" action="${o}/prompts"><input type="hidden" name="confirmation" value="${v(u(G))}"><textarea name="prompt" hidden>
555
+ ${v(O)}</textarea><button id="comm-confirm-submit" type="submit">Confirm and queue</button></form><button type="button" id="comm-edit-button">Edit prompt</button><p id="comm-send-status" role="status"></p><details><summary>Edit prompt</summary>${M(U,O)}</details><p>Confirmation expires in five minutes. If a submission result is uncertain, retry this same confirmation; do not create a new prompt.</p></div>`)}catch(q){let U=q instanceof io?409:400;return N(k,"Review unavailable",`<p>${v(q.message)}</p>${$?M($,O):`<pre>
556
+ ${v(O)}</pre>`}<a href="${o}">Math inbox</a>`,U)}}),t.post("/comm/math/prompts",async k=>{if(!e.enabled)return N(k,"Sending unavailable","<p>Sending is not enabled.</p>",403);let O="",$="",q=!1;try{let U=await J(k);O=U.get("prompt")??"",$=U.get("confirmation")??"";let Z=m(k);O=se(U);let G=d($);if(G.browser!==Z||G.digest!==c(O)||!Number.isFinite(G.expires)||!/^localweb:[a-f0-9]{48}$/.test(G.key))throw new Error("Confirmation does not match this browser and prompt.");let ae=r.db.db.prepare("SELECT id, admission_fingerprint FROM queue WHERE dedupe_key = ?").get(G.key);if(ae){if(ae.admission_fingerprint!==c(`math\0${O}`))throw new Error("Confirmation conflicts with an existing admission.");return k.redirect(`${o}/prompts/${ae.id}`,303)}if(G.expires<s()||G.target!==f())throw new Error("Confirmation expired or changed. Check the inbox before reviewing again; a previous uncertain admission may already exist.");q=!0;let be=s()-6e4;for(let[j,K]of a)K.start<be&&a.delete(j);let ne=a.get(Z)??{start:s(),count:0};if(ne.count>=10)return N(k,"Please wait",`<p>Ten prompts were queued this minute. Wait before retrying this unchanged confirmation.</p><pre>
557
+ ${v(O)}</pre>${W(O,$)}`,429);let D=Aa(r.db.db,r.teams,{to:"math",prompt:O,dedupeKey:G.key});return D.replayed||(ne.count++,a.set(Z,ne)),k.redirect(`${o}/prompts/${D.queueId}`,303)}catch(U){return N(k,"Prompt not confirmed",`<p>${v(U.message)}</p><pre>
558
+ ${v(O)}</pre>${q?W(O,$):""}<p>No new confirmation key was issued. For an uncertain result, retain the original confirmation and check the inbox before sending again. A server restart invalidates pending confirmations; known receipt URLs remain readable.</p><a href="${o}">Math inbox</a>`,400)}}),t.get("/comm/math/prompts/:id",k=>{let O=k.req.param("id"),$=Number(O);if(!/^[1-9]\d*$/.test(O)||!Number.isSafeInteger($))return N(k,"Not found","<p>Invalid prompt ID.</p>",404);let q=to(r,$);if(!q||q.to_id!=="math")return N(k,"Not found","<p>No Math inbox prompt at this address.</p>",404);let U=hs(r,$),Z=Ur(r,$),G=U.answer,ae=U.lifecycle==="finished"&&p(U.lifecycleBasis),be=v(q.retracted_reason??"no reason recorded"),ne=U.lifecycleBasis==="informational"?"This was an informational send; no answer is expected.":U.lifecycleBasis==="retracted"?`This prompt was retracted by its sender: ${be}. No answer is expected.`:"This prompt was combined into another prompt. The combined prompt ID is not recorded, so no link is available.",D=U.lifecycleBasis==="informational"?"No answer expected: this was an informational send.":U.lifecycleBasis==="retracted"?`No answer expected: this prompt was retracted. Reason: ${be}.`:"No separate answer: prompt combined into another prompt.";if(G&&G.prompt_queue_id!==$)return N(k,"Answer unavailable","<p>Answer correlation mismatch.</p>",503);let j="";if(e.enabled)try{f(),j=`<section id="compose" aria-label="Write a prompt" data-mount="${v(n)}" data-base="${v(o)}"><h2>Write another prompt</h2><p>Start a new prompt to ${C("math")}. Review the exact text before queueing it.</p>${M(m(k,!0))}</section>`}catch{}return N(k,`Math prompt #${$}`,`<p>Prompt #${$}: ${C(q.from_id)} \u2192 ${C(q.to_id)}. <span id="comm-receipt-summary">${G?"An answer is recorded below.":ae?ne:"No answer recorded yet."}</span></p>${b}<p>Work: no task association is recorded for this prompt. <a href="#assigned-work">Browse Math\u2019s current assigned work</a>.</p><p id="comm-state" role="status" aria-live="polite" data-sender="${v(q.from_id)}" data-recipient="${v(q.to_id)}" data-queue-id="${$}" data-mount="${v(n)}" data-lifecycle="${U.lifecycle}" data-lifecycle-basis="${U.lifecycleBasis}">${x(U)} \xB7 ${v(H(U))}</p><p><a href="${o}/prompts/${$}">Refresh state</a> \xB7 <a href="${o}">Math inbox</a></p>${j}<section aria-label="Prompt and answer sequence"><h2>Prompt and answer sequence</h2><article data-queue-id="${$}" data-event="request"><h3>Prompt text</h3><p>${C(q.from_id)} \u2192 ${C(q.to_id)} \xB7 queued ${fe(U.createdAt)}</p><details><summary>Prompt times</summary><p id="comm-handling-observation">Delivery attempted ${q.sent_ts?fe(q.sent_ts):"not recorded"} \xB7 Picked up ${q.retrieved_ts?fe(q.retrieved_ts):"not recorded"} </p><p>Answer recorded <span id="comm-reply-time">${G?fe(G.answered_at):"not recorded"}</span></p></details>${Z?.status==="available"?`<pre>
559
+ ${v(Z.text)}</pre><p>${Z.truncated?"Preview truncated.":"Saved prompt text; availability may change."}</p>`:"<p>Prompt preview unavailable.</p>"}</article><article data-queue-id="${$}" data-event="response"><h3>Answer</h3><p id="comm-poll-notice" role="status" aria-live="polite">Live updates while this page is visible.</p><p id="comm-response-status">${ae?D:`${G?"Answer recorded":"Waiting for an answer"} in the ${C(q.to_id)} inbox for prompt #${$} from ${C(q.from_id)}.`}</p>${G?`<p id="comm-response-meta">Recorded ${fe(G.answered_at)} \xB7 answer #${G.id} to prompt #${G.prompt_queue_id}</p><pre id="comm-response">
560
+ ${v(G.answer_text)}</pre><p id="comm-response-truncation">${G.truncated?`Truncated: ${G.byteLength} of ${G.totalBytes} bytes. No continuation endpoint is available.`:`${G.byteLength} bytes returned.`}</p>`:`<p id="comm-response-meta"></p><pre id="comm-response" hidden></pre><p id="comm-response-truncation"></p><p id="comm-response-none">${ae?"":"No correlated answer recorded yet. Refresh to check again."}</p>`}</article></section><div id="assigned-work">${w()}</div>`)}),t}import{basename as xD}from"node:path";var ed=50,RD=e=>e.trim().toLowerCase().replace(/[\s_]+/g,"-"),td=e=>["blocked","error","on-hold","rate-limited"].includes(RD(e));function SE(e){if(!/^[1-9]\d*$/.test(e)||!Number.isSafeInteger(Number(e)))throw new L("INVALID_ARGUMENT","Invalid positive integer ID");return Number(e)}function ND(e){let t={},r=new Set(["q","project","status","kind","team","attention","sort","page"]);for(let[n,o]of new URL(e).searchParams){if(!r.has(n)||Object.hasOwn(t,n)||o.length>256||/[\x00-\x1f\x7f]/.test(o))throw new L("INVALID_ARGUMENT","Invalid or duplicate task filter");t[n]=o}if(t.page&&SE(t.page)>Ie)throw new L("INVALID_ARGUMENT","Page exceeds safety limit");if(t.attention&&t.attention!=="1")throw new L("INVALID_ARGUMENT","attention must be 1");if(t.sort&&!["id","updated"].includes(t.sort))throw new L("INVALID_ARGUMENT","Unknown task sort");if(t.kind&&!["epic","task","subtask"].includes(t.kind))throw new L("INVALID_ARGUMENT","Unknown task kind");return t}function yE(e,t){let r=new URLSearchParams(Object.entries(t).filter(([,n])=>n!==""));return e+(r.size?`?${r}`:"")}function ID(e,t,r,n){let o=e.filter(f=>(!t.q||`${f.id} ${f.title} ${f.description} ${f.requirements} ${f.acceptance_criteria}`.toLowerCase().includes(t.q.toLowerCase()))&&(!t.attention||td(f.status))&&(!n||f.owner_team_path===n));o.sort(t.sort==="updated"?(f,p)=>Date.parse(p.updated_at)-Date.parse(f.updated_at)||f.id-p.id:(f,p)=>f.id-p.id);let s=Number(t.page||1),i=o.slice((s-1)*ed,s*ed),a=new Map(e.map(f=>[f.id,f])),c=f=>{if(f===null)return;let p=a.get(f)??r(f);return a.set(f,p),p},l=new Map(i.map(f=>[f.id,{...f,context:!1}]));for(let f of i){let p=c(f.parent_id),h=new Set([f.id]);for(;p&&!h.has(p.id);)h.add(p.id),l.has(p.id)||l.set(p.id,{...p,context:!0}),p=c(p.parent_id)}let u=new Map;for(let f of l.values()){let p=f.parent_id!==null&&l.has(f.parent_id)?f.parent_id:null,h=u.get(p)??[];h.push(f),u.set(p,h)}let d=[],m=f=>{for(let p of u.get(f)??[])d.push(p),m(p.id)};return m(null),{rows:d,total:o.length,pageNumber:s,more:o.length>s*ed,byId:a}}function ao(e,t){return Ne(`${t}/tasks/${e.id}`,`#${e.id} ${e.title}`)}function vE(e,t,r){if(e.owner_team_path===null)return"Unassigned";let n=`${xD(e.owner_team_path)}:${e.owner_alias}`,o=`${e.owner_team_path}:${e.owner_alias}`,s=t.get(e.owner_team_path);return s&&e.owner_alias?`<a href="${v(`${r}/sessions/${encodeURIComponent(s)}/${encodeURIComponent(e.owner_alias)}`)}" title="${v(o)}">${v(n)}</a>`:`<span title="${v(o)}">${v(n)}</span>`}function AE(e){if(e.blocked_on!==null){let t=e.blocked_on==="operator"?"Operator":e.blocked_on;return`<span class="status-chip status-processing" title="blocked_on names who this task is waiting on; independent of the recorded status text">Blocked on ${v(t)}</span>`}if(e.hold_until!==null){let t=Date.parse(e.hold_until)<=Date.now(),r=e.hold_reason?` \u2014 ${v(e.hold_reason)}`:"";return t?`<span class="status-chip status-processing" title="Hold expired ${v(e.hold_until)}; not auto-cleared, needs the owning team to resolve it">Hold expired, evidence due${r}</span>`:`<span class="status-chip status-muted">On hold until ${fe(e.hold_until)}${r}</span>`}return"\u2014"}function EE(e,t,r,n,o="Task ledger"){return so(["Task / hierarchy","Project","Recorded status","Blocked / hold","Recorded owner","Updated","Presentation"],e.map(s=>{let i=[],a=s.parent_id===null?void 0:t.get(s.parent_id),c=new Set([s.id]);for(;a&&!c.has(a.id);)c.add(a.id),i.unshift(a),a=a.parent_id===null?void 0:t.get(a.parent_id);let l=i.map(u=>ao(u,r)).join(" / ");return[`${l?`${l}<br>`:""}${ao(s,r)}${s.context?" <strong>(ancestor context)</strong>":""}<br>${v(s.kind)}`,v(s.project),v(s.status),AE(s),vE(s,n,r),fe(s.updated_at),s.kind==="epic"?"Not applicable":s.delivered_ts?`First presented ${fe(s.delivered_ts)}`:"Not recorded"]}),o)}function bE(e,t,r){let n=["q","project","status"].map(i=>`<label>${{q:"Search",project:"Project",status:"Exact recorded status"}[i]}<input name="${i}" value="${v(e[i]??"")}" maxlength="256"></label>`).join(""),o=(i,a,c)=>`<label>${a}<select name="${i}">${c.map(([l,u])=>`<option value="${v(l)}"${e[i]===l?" selected":""}>${v(u)}</option>`).join("")}</select></label>`,s=[["",`All teams (${t.length} own work in this scope)`],...t.map(i=>[i,i])];return`<form method="get" action="${v(r)}/tasks">${n}${o("kind","Kind",[["","All kinds"],["epic","Epic"],["task","Task"],["subtask","Subtask"]])}${o("team","Owning team",s)}${o("sort","Sort",[["id","ID"],["updated","Updated"]])}<label>Attention only<input type="checkbox" name="attention" value="1"${e.attention?" checked":""}></label><button>Filter tasks</button> ${Ne(`${r}/tasks`,"Clear filters")}</form>`}function TE(e){return`<p>${e.total} entities in this scope: ${e.by_kind.epic??0} epics, ${e.by_kind.task??0} tasks, ${e.by_kind.subtask??0} subtasks.</p>`}function $E(e,t,r=""){let n=r.replace(/\/$/,""),o=(i,a,c,l=200)=>De(i,$e(a,c,n,{"data-page":"tasks"}),l),s=(i,a)=>{let c=a instanceof L?a.code==="NOT_FOUND"?404:a.code==="DB_BUSY"?503:a.code==="STORAGE_ERROR"?500:a.code==="CONFLICT"?409:400:500;return o(i,"Tasks unavailable",`<p>${v(a instanceof Error?a.message:String(a))}</p>${Ne(`${n}/tasks`,"Task ledger")}`,c)};e.get("/tasks",i=>{try{let a=ND(i.req.url),c;if(a.team){let p=t.teams.find(h=>h.name===a.team&&B(h));if(!p||!B(p))throw new L("INVALID_ARGUMENT","Unknown local owning team");c=Q(p)}let l=kr(t.db.db,{...a.project?{project:a.project}:{},...a.kind?{kind:a.kind}:{},...a.status?{status:a.status}:{},limit:Ie}),u=qr(t.teams),d=[...new Set(l.rows.map(p=>p.owner_team_path).filter(p=>p!==null).map(p=>u.get(p)).filter(p=>p!==void 0))].sort();if(l.meta.next_cursor!==null)return o(i,"Tasks",'<p class="warning">This scope exceeds 10,000 entities. Choose a project, kind, or status to narrow it; an incomplete board is not shown.</p>'+bE(a,d,n),503);let m=ID(l.rows,a,p=>xr(t.db.db,p),c),f=`<nav aria-label="Task pages">${m.pageNumber>1?Ne(yE(`${n}/tasks`,{...a,page:String(m.pageNumber-1)}),"Previous page"):""} ${m.more?Ne(yE(`${n}/tasks`,{...a,page:String(m.pageNumber+1)}),"Next page"):""}</nav>`;return o(i,"Tasks",'<p data-testid="page-intro">Epics group tasks, and tasks can contain subtasks; follow a title to read its details and children. Status and owner are recorded values; Updated means content activity; Attention means blocked, error, on-hold, or rate-limited; First presentation means when the item was first shown to an agent to work on, not completion. Blocked / hold is separate from the recorded status text: it shows when a task is structurally waiting on a specific team or operator, or deliberately parked until a date, even while its own status reads as ordinary active work.</p>'+TE({total:l.rows.length,by_kind:l.rows.reduce((p,h)=>(p[h.kind]=(p[h.kind]??0)+1,p),{})})+bE(a,d,n)+`<p>${m.total} matching entities. Page ${m.pageNumber}, up to 50 matches plus labeled ancestor context; presentation does not mean completion.</p>`+f+EE(m.rows,m.byId,n,u)+f)}catch(a){return s(i,a)}}),e.get("/tasks/:id",i=>{try{let a=SE(i.req.param("id")),c=xr(t.db.db,a),l=Rr(t.db.db,a),u=[],d=c.parent_id,m=new Set([a]);for(;d!==null&&!m.has(d);){m.add(d);let T=xr(t.db.db,d);u.unshift(T),d=T.parent_id}let f=qr(t.teams),p=new Map([...u,c,...l.children].map(T=>[T.id,T])),h=T=>T.length?`<ul>${T.map(R=>`<li>${ao(R,n)} \u2014 ${v(R.status)}</li>`).join("")}</ul>`:"<p>None recorded.</p>",g=`<nav aria-label="Breadcrumb">${Ne(`${n}/tasks`,"Task ledger")} / ${u.map(T=>Ne(`${n}/tasks/${T.id}`,`#${T.id} ${T.title} (status: ${T.status})`)).join(" / ")}${u.length?" / ":""}<span aria-current="page">#${c.id} ${v(c.title)}</span></nav>`,_=u.at(-1),E=u.find(T=>T.kind==="epic"),S=`<p data-testid="work-context">${c.kind==="epic"?"This is an epic with no parent.":c.kind==="task"?E?`This is a task in epic ${ao(E,n)}.`:"This is a task with no parent epic.":`This is a subtask${_?` of task ${ao(_,n)}`:""}${E?`, part of epic ${ao(E,n)}.`:"; no parent epic is recorded."}`}</p><p data-testid="page-intro">This page describes one work item and its recorded status and owner. Follow the breadcrumb to its parent or epic, or a child title to drill down; Updated records content activity, not completion.</p>`+g+`<p>Kind: ${v(c.kind)}; project: ${v(c.project)}; recorded status: <strong>${v(c.status)}</strong>.</p><p>Recorded owner: ${vE(c,f,n)}.</p><p>Blocked / hold: ${AE(c)}</p>`+["description","requirements","acceptance_criteria"].map(T=>`<h2>${{description:"Description",requirements:"Requirements",acceptance_criteria:"Acceptance criteria"}[T]}</h2><pre>${v(c[T]||"Not supplied")}</pre>`).join("")+TE(Nr(t.db.db,{id:a}))+"<h2>Children</h2>"+EE(l.children,p,n,f,"Immediate children")+"<h2>Depends on</h2>"+h(c.dependencies.outgoing)+"<h2>Required by</h2>"+h(c.dependencies.incoming)+`<h2>Times</h2><p>Created ${fe(c.created_at)}; updated ${fe(c.updated_at)}.</p><p>First presentation: ${c.kind==="epic"?"Not applicable":c.delivered_ts?fe(c.delivered_ts):"Not recorded"}. Presentation does not mean completion.</p>`;return o(i,`Task #${c.id}: ${c.title}`,S)}catch(a){return s(i,a)}})}import{basename as LD}from"node:path";var kE=50,xE='<p data-testid="page-intro">A cron job is work scheduled to run automatically; this page reviews its saved configuration and recorded results. An unresolved escalated run is waiting for a person to help, while execution uncertain means the process has not been confirmed stopped.</p>',CD={ok:"OK (last-fire bookkeeping)",error:"Error",skipped_overlap:"Skipped: earlier execution still guarded",skipped_stale:"Skipped: scheduled window too old",reconciled:"Process gone; outcome unknown",blocked_escalation:"Skipped: unresolved escalation at last check"},st=e=>e===null?"Not recorded":fe(e),Ze=e=>e===null?"Not configured":v(e),RE=e=>e.last_fire_status===null?"Not recorded":`${v(CD[e.last_fire_status]??e.last_fire_status)} <small>(${v(e.last_fire_status)})</small>`;function NE(e){let t=e.req.queries("after");if(t===void 0)return 0;let r=t[0]??"";if(t.length!==1||!/^(0|[1-9]\d*)$/.test(r)||!Number.isSafeInteger(Number(r)))throw new P("INVALID_ARGUMENT","after must be a nonnegative integer");return Number(r)}function IE(e,t,r){if(e.session_teamfile===null||e.session_alias===null)return"Not configured";let n=`${e.session_teamfile}:${e.session_alias}`,o=`${LD(e.session_teamfile)}:${e.session_alias}`,s=t.get(e.session_teamfile);return s?`<a href="${v(`${r}/sessions/${encodeURIComponent(s)}/${encodeURIComponent(e.session_alias)}`)}" title="${v(n)}">${v(o)}</a>`:`<span title="${v(n)}">${v(o)}</span> (not in the current local registry)`}function LE(e,t){let r=[];return(e.last_fire_status==="error"||e.last_fire_error)&&r.push("Recorded fire error"),e.last_fire_status==="blocked_escalation"&&r.push("Last check blocked by escalation"),e.last_fire_status==="reconciled"&&r.push("Previous execution outcome unknown"),t?.status==="escalated"&&t.escalation_resolved_at===null&&r.push(`Run #${t.id}: escalated \u2014 waiting for a person`),t?.execution_state==="uncertain"&&r.push(`Run #${t.id}: execution uncertain`),t?.status==="failed"&&r.push(`Run #${t.id}: failed; execution still guarded`),r}function rd(e){return`<dl>${e.map(([t,r])=>`<dt>${v(t)}</dt><dd>${r}</dd>`).join("")}</dl>`}function OD(e){if(e===null)return"<p>No artifacts recorded.</p>";try{let t=JSON.parse(e);if(Array.isArray(t)&&t.every(r=>typeof r=="string"))return t.length?`<ul>${t.map(r=>`<li>${v(r)}</li>`).join("")}</ul>`:"<p>No artifacts recorded.</p>"}catch{}return`<pre>${v(e)}</pre>`}function DD(e){let t=e.status==="escalated",r=t&&e.escalation_resolved_at===null,n=e.status==="failed"||r||e.execution_state==="uncertain",o=`${e.status}${t?r?" \u2014 waiting for a person":" \u2014 escalation resolved":""}`,s=t||e.escalation_reason!==null||e.escalation_resolved_at!==null?"<h4>Escalation</h4>"+rd([["Reason",Ze(e.escalation_reason)],["Requested action",Ze(e.escalation_action)],["Owner",Ze(e.escalation_owner)],["Resolved at",st(e.escalation_resolved_at)],["Resolution",Ze(e.escalation_resolution)],["Resolved by",Ze(e.escalation_resolution_actor)],["Resolution note",Ze(e.escalation_resolution_note)]]):"";return`<article id="run-${e.id}"${n?' class="warning"':""}><h3>Run #${e.id}: ${v(o)}</h3>`+rd([["Execution state",v(e.execution_state)],["Trigger",v(e.trigger_kind)],["Created",st(e.created_at)],["Started",st(e.started_at)],["Finished",st(e.finished_at)],["Result reported",st(e.reported_at)],["Last updated",st(e.updated_at)],["Execution reference",Ze(e.execution_identity)],["Process ID",Ze(e.pid)],["Execution uncertainty reason",Ze(e.execution_uncertain_reason)],["Execution confirmed gone",st(e.execution_gone_at)],["Confirmation note",Ze(e.execution_confirmation_note)]])+`<h4>Summary</h4><pre>${v(e.summary??"No summary recorded.")}</pre><h4>Artifacts (recorded paths or references)</h4>`+OD(e.artifacts)+s+"</article>"}function CE(e,t,r=""){let n=r.replace(/\/$/,""),o=(a,c,l,u=200)=>De(a,$e(c,l,n),u),s=(a,c)=>{let l=c instanceof P?c.code==="NOT_FOUND"?404:c.code==="DB_BUSY"?503:c.code==="INVALID_ARGUMENT"?400:500:500;return o(a,"Cron review unavailable",`<p>${v(c instanceof Error?c.message:String(c))}</p>${Ne(`${n}/cron`,"Cron jobs")}`,l)},i=(a,c,l)=>`<nav aria-label="Cron pages">${c?Ne(a,"First page"):""} ${l!==null?Ne(`${a}?after=${l}`,"Next page"):""}</nav>`;e.get("/cron",a=>{try{let c=NE(a),l=Ji(t.db.db,{limit:kE,after:c}),u=qr(t.teams),d=l.rows.map(f=>({job:f,flags:LE(f,fr(t.db.db,f.id))})),m=(f,p)=>so(["Job","Schedule / timezone","Action kind","Enabled","Last fire status","Last fired","Scheduler last looked at","Last fire error","Session"],f.map(({job:h,flags:g})=>[Ne(`${n}/cron/${h.id}`,`#${h.id} ${h.title}`)+(g.length?`<p class="warning"><strong>${g.map(v).join("<br>")}</strong></p>`:""),`<code>${v(h.schedule_expr)}</code><br>${v(h.timezone??"Host-local timezone")}`,v(h.action_kind),h.enabled?"Enabled":"Disabled",RE(h),st(h.last_fired_ts),st(h.last_checked_ts),h.last_fire_error===null?"None recorded":`<pre>${v(h.last_fire_error)}</pre>`,IE(h,u,n)]),p);return o(a,"Cron jobs",xE+"<p>Saved jobs, up to 50 per page in ID order. Times below are stored scheduler records; OK is not proof of successful AI work. A retained error can predate a later skipped check.</p><h2>Failures and review flags</h2>"+m(d.filter(f=>f.flags.length>0),"Jobs with review flags on this page")+"<h2>Other jobs</h2>"+m(d.filter(f=>f.flags.length===0),"Other jobs on this page")+i(`${n}/cron`,c,l.meta.next_cursor))}catch(c){return s(a,c)}}),e.get("/cron/:id",a=>{try{let c=a.req.param("id");if(!/^[1-9]\d*$/.test(c)||!Number.isSafeInteger(Number(c)))throw new P("INVALID_ARGUMENT","Invalid positive job ID");let l=NE(a),u=Le(t.db.db,Number(c)),d=Hi(t.db.db,{jobId:u.id,limit:kE,after:l}),m=fr(t.db.db,u.id),f=LE(u,m),p=rd([["Title",v(u.title)],["Schedule expression",`<code>${v(u.schedule_expr)}</code>`],["Timezone",v(u.timezone??"Host-local timezone")],["Action kind",v(u.action_kind)],["Enabled",u.enabled?"Enabled":"Disabled"],["Provider",Ze(u.provider)],["Model",Ze(u.model)],["Working directory",Ze(u.working_directory)],["Escalation owner",Ze(u.escalation_owner)],["Session",IE(u,qr(t.teams),n)],["Session teamfile",Ze(u.session_teamfile)],["Session alias",Ze(u.session_alias)],["Session seeded at",st(u.session_seeded_at)],["Session generation",v(u.session_generation)],["Scheduler last looked at",st(u.last_checked_ts)],["Last fired",st(u.last_fired_ts)],["Last fire status",RE(u)],["Last fire error",u.last_fire_error===null?"None recorded":`<pre>${v(u.last_fire_error)}</pre>`],["Recorded execution since",st(u.running_since_ts)],["Recorded systemd unit",Ze(u.running_systemd_unit)],["Created",st(u.created_at)],["Updated",st(u.updated_at)],["Revision",v(u.revision)]]),h=m?`<p>${Ne(`${n}/cron/${u.id}?after=${m.id-1}#run-${m.id}`,`Inspect guarded run #${m.id}`)} \u2014 ${v(m.status)}, execution ${v(m.execution_state)}.</p>`:"",g=l?"<p>No more run records after this cursor.</p>":"<p>No run history recorded. Command or script jobs may have last-fire records without run history; an empty history is not itself an error.</p>";return o(a,`Cron job #${u.id}: ${u.title}`,xE+`<p>${Ne(`${n}/cron`,"All cron jobs")}</p>`+(f.length?`<p class="warning"><strong>${f.map(v).join("<br>")}</strong></p>`:"")+h+"<h2>Configuration</h2>"+p+`<h3>Action payload (command, script, prompt, or enqueue data)</h3><pre>${v(u.action_payload)}</pre><h2>Run history</h2><p>Up to 50 recorded runs, oldest ID first. Outcome and process state are separate: active is recorded as active, uncertain is not confirmed stopped, and gone is confirmed stopped.</p>`+(d.rows.length?d.rows.map(DD).join(""):g)+i(`${n}/cron/${u.id}`,l,d.next_cursor))}catch(c){return s(a,c)}})}function MD(e,t){return t===null&&e.retracted_ts===null&&(e.status==="pending"||e.status==="escalating"||e.status==="sent"||e.status==="retrieved")}var DE=64*1024;async function PD(e){if(!e.req.header("content-type")?.toLowerCase().startsWith("application/x-www-form-urlencoded"))throw new L("INVALID_ARGUMENT","Expected a browser form.");let t=e.req.raw.body?.getReader();if(!t)throw new L("INVALID_ARGUMENT","Missing form.");let r=0,n=[];for(;;){let{done:i,value:a}=await t.read();if(i)break;if(r+=a.byteLength,r>DE)throw await t.cancel(),new L("INVALID_ARGUMENT","Form exceeds the size limit.");n.push(a)}let s=new URLSearchParams(Buffer.concat(n).toString("utf8")).getAll("answer");if(s.length!==1)throw new L("INVALID_ARGUMENT","Missing or duplicate answer field.");return s[0]}function ME(e,t){let r=[t.from_id,t.to_id,t.escalation_only,t.to_alias],o=e.prepare("SELECT MIN(id) AS id FROM queue WHERE from_id = ? AND to_id = ? AND escalation_only = ? AND to_alias IS ? AND id > ? AND status != 'merged'").get(...r,t.id).id??Number.MAX_SAFE_INTEGER;return e.prepare("SELECT * FROM queue WHERE from_id = ? AND to_id = ? AND escalation_only = ? AND to_alias IS ? AND status = 'merged' AND id > ? AND id < ?").all(...r,t.id,o)}function PE(e,t){let r=[];t.retracted_ts!==null&&t.retracted_reason&&r.push(t.retracted_reason);let n=ME(e,t);for(let o of n)o.retracted_ts!==null&&o.retracted_reason&&r.push(o.retracted_reason);return r}function nd(e,t=Date.now()){return ss(e,t).map(n=>{let o=n.row,s=un(e,o),i=os(e,o),a=n.ageMs>=cs||s>=2&&o.sent_ts===null,c=PE(e,o);return{row:o,constituentCount:s,retractedCount:i,urgent:a,retractedReasons:c}})}function UE(e){return e===1?"1 of 1":`${e} merged into this one`}function UD(e){return e==="merged"||e==="informational"||e==="retracted"}function FD(e){return e.lifecycle==="queued"?"queued":e.lifecycle==="processing"?"processing":UD(e.lifecycleBasis)?"muted":"replied"}function qD(e){return e.lifecycle==="queued"?"Queued":e.lifecycle==="processing"?"Processing":e.lifecycleBasis==="merged"?"Combined":e.lifecycleBasis==="informational"?"Informational":e.lifecycleBasis==="retracted"?"Retracted":"Replied"}function FE(e){return`<span class="status-chip status-${FD(e)}" title="${v(od(e))}">${v(qD(e))}</span>`}function od(e){return e.lifecycle==="queued"?"Queued \u2014 waiting for handling":e.lifecycle==="processing"?e.lifecycleBasis==="confirmed"?"Processing \u2014 picked up by inbox":"Processing \u2014 delivery attempted; read not confirmed":e.lifecycle==="finished"?e.lifecycleBasis==="retracted"?"Finished \u2014 retracted":e.lifecycleBasis==="merged"?"Finished \u2014 combined with another prompt":e.lifecycleBasis==="informational"?"Finished \u2014 informational, no answer expected":"Finished \u2014 answer recorded":`${e.lifecycle} (${e.lifecycleBasis})`}function jD(e){return`<dl>${e.map(([t,r])=>`<dt>${v(t)}</dt><dd>${r}</dd>`).join("")}</dl>`}function HD(e){return e.length===0?"<p>No standing decisions recorded.</p>":e.map(t=>{let r=t.would_change_it?`<p><strong>Would change this:</strong> ${v(t.would_change_it)}</p>`:"<p><strong>Would change this:</strong> Not recorded.</p>",n=t.affects.length>0?t.affects.map(v).join(", "):"Not recorded";return`<article aria-label="Decision #${t.id}"><h3>${v(t.subject)}</h3><p>${v(t.decision)}</p>${r}<details><summary>Reasoning</summary><p>${v(t.reasoning)}</p></details><p>Decided by ${v(t.decided_by)}, ${fe(t.decided_at)}. Affects: ${n}.</p></article>`}).join("")}function BD(e){return e.length===0?"<p>Nothing blocking math right now.</p>":e.map(t=>`<article aria-label="Blocked #${t.id}"><h3>!!! ${v(t.title)}</h3><p>Category: ${v(t.category)}.</p>${t.detail?`<p>${v(t.detail)}</p>`:""}<p>Raised by ${v(t.raised_by)}, ${fe(t.raised_at)}.</p></article>`).join("")}function WD(e,t){return e.length===0?"<p>No open judgment calls for the operator.</p>":e.map(r=>{let n=r.downstream?`<p><strong>Downstream:</strong> ${v(r.downstream)}</p>`:"<p><strong>Downstream:</strong> Not recorded.</p>";return`<article aria-label="Ask #${r.id}"><h3>${v(r.subject)}</h3><p>${v(r.reason)}</p>${n}<p>Status: Open. Raised by ${v(r.raised_by)}, ${fe(r.raised_at)}.</p><p><a href="${v(t)}/comm/math?ask=${r.id}#compose">Discuss this with math</a></p></article>`}).join("")}function OE(e,t,r,n){if(e.length===0)return`<p>No ${t.toLowerCase()}.</p>`;let o=["Prompt","From","Age","Constituents","Retractions","Lifecycle"],s=e.map(i=>{let a=i.row,c=Oe(n,a.id),l=xt(a,c),u=`<a href="${v(r)}/operator/${a.id}">#${a.id}</a>`,d=v(a.from_id),m=fe(a.created_ts),f=UE(i.constituentCount),p=i.retractedCount>0?`${i.retractedCount} retracted${i.retractedReasons.length>0?`: ${i.retractedReasons.map(g=>`\u201C${v(g)}\u201D`).join("; ")}`:""}`:"\u2014",h=`${FE(l)} \xB7 ${v(od(l))}`;return[u,d,m,f,p,h]});return so(o,s,t)}function qE(e,t,r=""){let n=r.replace(/\/$/,"");e.get("/operator",o=>{try{let s=nd(t.db.db,Date.now()),i=s.filter(g=>g.urgent),a=s.filter(g=>!g.urgent),c='<p data-testid="page-intro">What needs the operator, what math has already decided for them to review, and a way to reach math directly. Blocked means math is technically incapable of proceeding (re-auth, billing, account identity) -- rare and urgent. Escalations are requests a team sent that genuinely need a decision, shown whether or not anyone is currently monitoring them; urgent means waiting over four hours, or never delivered despite repeated sends. Constituents counts how many separate escalations were folded into one message; Retractions counts how many of those the sender has since withdrawn, with their stated reason. Asks are judgment calls only the operator can make, routine, not urgent -- problem statement, then what it affects downstream, then who raised it. Decisions are rulings math has already made, for review, not approval.</p>',l=`<section class="warning" aria-label="Urgent escalations"><h2>Urgent escalations</h2>${OE(i,"Urgent escalations",n,t.db.db)}</section>`,u=`<section aria-label="Routine escalations"><h2>Routine escalations</h2>${OE(a,"Routine escalations",n,t.db.db)}</section>`,d=`<section aria-label="Send a message"><h2>Send a message</h2><p>Start a new request to math. This reuses the same queue and composer as <a href="${v(n)}/comm/math">the Math inbox</a> -- one write path, not a second one.</p><p><a href="${v(n)}/comm/math#compose">Write a message to math</a></p></section>`,m,f,p;try{let g=$a(),_,E,y;try{_=gE(g),E=pE(g),y=fE(g)}finally{g.close()}m=`<section class="warning" aria-label="Blocked"><h2>Blocked</h2>${BD(_)}</section>`,f=`<section aria-label="Asks"><h2>Asks</h2>${WD(E,n)}</section>`,p=`<section aria-label="Decisions"><h2>Decisions</h2><p>Rulings math has already made, in force now (superseded and reversed decisions are excluded). Nothing here waits on you -- read, and ping math if you disagree.</p>${HD(y)}</section>`}catch(g){let _=`<p class="warning">lmteam data unavailable: ${v(g instanceof Error?g.message:String(g))}</p>`;m=`<section class="warning" aria-label="Blocked"><h2>Blocked</h2>${_}</section>`,f=`<section aria-label="Asks"><h2>Asks</h2>${_}</section>`,p=`<section aria-label="Decisions"><h2>Decisions</h2>${_}</section>`}let h=`${c}${m}${l}${f}${d}${u}${p}`;return De(o,$e("Operator inbox",h,n,{"data-page":"operator"},[],!0))}catch(s){return De(o,$e("Operator inbox unavailable",`<p>${v(s instanceof Error?s.message:String(s))}</p>`,n,{},[],!0),500)}}),e.get("/operator/:id",o=>{let s=o.req.param("id"),i=Number(s);if(!s||!/^[1-9]\d*$/.test(s)||!Number.isSafeInteger(i))return De(o,$e("Invalid escalation ID",`<p>Invalid escalation ID.</p><p><a href="${v(n)}/operator">Operator inbox</a></p>`,n,{},[],!0),400);try{let a=vr(t.db.db,i);if(!a||a.to_id!=="operator")return De(o,$e("Not found",`<p>No operator escalation at this address.</p><p><a href="${v(n)}/operator">Operator inbox</a></p>`,n,{},[],!0),404);let c=Ur(t,i),l=Oe(t.db.db,i),u=xt(a,l),d=un(t.db.db,a),m=os(t.db.db,a),f=PE(t.db.db,a),p=[["From",v(a.from_id)],["To",v(a.to_id)],["Queued",fe(a.created_ts)],["Lifecycle",`${FE(u)} \xB7 ${v(od(u))}`],["Constituents",v(UE(d))],["Delivery attempted",a.sent_ts?fe(a.sent_ts):"not recorded"],["Picked up",a.retrieved_ts?fe(a.retrieved_ts):"not recorded"],["Subject",a.subject_id?v(a.subject_id):"none"]];m>0&&p.push(["Retractions",`${m} retracted${f.length>0?`: ${f.map(S=>`\u201C${v(S)}\u201D`).join("; ")}`:""}`]),a.retracted_ts!==null&&(p.push(["Retracted at",fe(a.retracted_ts)]),p.push(["Retraction reason",v(a.retracted_reason??"(none)")]));let h="";c?.status==="available"?h=`<pre>${v(c.text)}</pre><p>${c.truncated?`Preview truncated (${c.byteLength} bytes).`:`Full content (${c.byteLength} bytes).`}</p>`:h=`<p>Prompt preview unavailable (${v(c?.status??"missing")}).</p>`;let g="";l?g=`<section><h2>Answer</h2><p>Recorded ${fe(l.answered_at)}</p><pre>${v(l.answer_text)}</pre></section>`:MD(a,l)&&(g=`<section aria-label="Answer"><h2>Answer</h2><form method="post" action="${v(n)}/operator/${i}/answer"><label for="answer">Answer text</label><textarea id="answer" name="answer" rows="8" maxlength="${DE}" required></textarea><button>Send answer</button></form></section>`);let _=ME(t.db.db,a),E="";_.length>0&&(E=`<section><h3>Merged constituents (${_.length})</h3><p>Additional escalations folded into this message:</p><ul>${_.map(S=>`<li><a href="${v(n)}/operator/${S.id}">#${S.id}</a> from ${v(S.from_id)} (queued ${fe(S.created_ts)})${S.retracted_ts?` \u2014 <strong>Retracted</strong>: \u201C${v(S.retracted_reason)}\u201D`:""}</li>`).join("")}</ul></section>`);let y=`<p><a href="${v(n)}/operator">Operator inbox</a></p>
561
561
  <p data-testid="page-intro">One escalation addressed to the operator. Constituents counts how many separate escalations were folded into this message; Retractions, if shown, counts how many of those the sender has since withdrawn, with their stated reason.</p>
562
562
  <section aria-label="Escalation metadata"><h2>Metadata</h2>${jD(p)}</section>
563
563
  <article aria-label="Prompt content"><h2>Prompt content</h2>${h}</article>
@@ -586,12 +586,12 @@ ${s?`<p>This timeline shows incoming and outgoing exchanges. ${s} opens requests
586
586
  // tsx preserves names using an injected helper; keep serialized source self-contained.
587
587
  function __name(value) { return value; }
588
588
  return (${VD.toString()})();
589
- })();</script>`}function VD(){let e=document.getElementById("session-detail"),{team:t="",alias:r="",mount:n="",history:o="",canonicalTeamfile:s="",commEnabled:i="false",commPageEnabled:a="false"}=e.dataset,c=D=>document.getElementById(D),l=(D,j)=>{c(D).textContent=j},u=(D,j)=>{let K=document.createElement(D);return K.textContent=j,K},d=new Map,m=!1,f=0,p,h=null,g=0,_=0,E=null,y=null,S=D=>!m&&!document.hidden&&D===f,T=()=>{},R=[],A=!1;function I(D){let j=u("span",D),K=R.find(z=>z.name===D);if(!K){let z=A?"Recorded label; current actor unresolved":"Recorded label; current team list unavailable";return j.title=`${D} \u2014 ${z}`,/[\\/]/.test(D)&&(j.textContent=D.split(/[\\/]/).at(-1).replace(/\.lmctl(?=:|$)/,"")),j}if(K.channel==="lmmail")return j.textContent+=" (remote inbox)",j;if(K.channel==="local"&&K.leadAlias&&D!=="operator"){let z=u("a",`${K.name}:${K.leadAlias}`);z.title="Current configured inbox lead; not a historical sender session",j.textContent="",z.href=`${n}/sessions/${encodeURIComponent(K.name)}/${encodeURIComponent(K.leadAlias)}`,j.append(z)}return j}function x(D,j){let K=u("span","");return K.append(I(D),u("span"," \u2192 "),I(j)),K}let H=D=>`${n}/sessions/${encodeURIComponent(t)}/${encodeURIComponent(r)}?queue=${D}`,C=D=>D instanceof Error?D.message:String(D);async function w(D,j){let K=new AbortController;d.set(K,j===void 0);let z=setTimeout(()=>K.abort(),15e3);try{let re=await fetch(D,{method:j===void 0?"GET":"POST",signal:K.signal,credentials:"same-origin",cache:"no-store",redirect:"error",headers:{Accept:"application/json",...j===void 0?{}:{"Content-Type":"application/json"}},...j===void 0?{}:{body:JSON.stringify(j)}});if(!re.ok)throw new Error(`HTTP ${re.status}; request unsuccessful`);if(!re.headers.get("content-type")?.includes("application/json"))throw new Error("Expected JSON response");let te=re.body.getReader(),ue=new TextDecoder,xe=0,Se="";for(;;){let Y=await te.read();if(Y.done)break;if(xe+=Y.value.byteLength,xe>2e6)throw await te.cancel(),new Error("Response exceeds 2 MB limit");Se+=ue.decode(Y.value,{stream:!0})}return JSON.parse(Se+ue.decode())}finally{clearTimeout(z),d.delete(K)}}function b(D){return D==="merged"||D==="informational"||D==="retracted"}function N(D,j=!1){if(j){if(D.lifecycle==="queued")return"queued";if(D.lifecycle==="finished")return D.lifecycleBasis==="merged"?"finished \xB7 merged into an earlier message":D.lifecycleBasis==="informational"?"finished \xB7 informational, no reply expected":D.lifecycleBasis==="retracted"?"finished \xB7 retracted, no reply expected":"finished \xB7 reply recorded";if(D.lifecycle==="processing")return D.lifecycleBasis==="confirmed"?"processing \xB7 picked up":"processing \xB7 attempted"}if(D.lifecycle==="finished")return D.lifecycleBasis==="merged"?"finished \u2014 merged into an earlier message, no separate response":D.lifecycleBasis==="informational"?"finished \u2014 informational, no response expected":D.lifecycleBasis==="retracted"?"finished \u2014 retracted, no response expected":"finished \u2014 response recorded";if(D.lifecycle==="queued")return"queued \u2014 waiting for handling";if(D.lifecycle==="processing")return D.lifecycleBasis==="confirmed"?"processing \u2014 picked up by inbox":"processing \u2014 delivery attempted; read not confirmed";throw new Error("Unknown lifecycle in owner response")}let P=null,J=D=>D!==null&&typeof D=="object"&&!Array.isArray(D),ee=(D,j)=>typeof D=="string"&&D.trim()?D:j,oe=!1;async function V(){if(!oe||P===f||m||document.hidden)return;let D=f;P=D,c("session-refresh").disabled=!0;try{let j=await w(o);if(!S(D))return;if(!J(j)||!Array.isArray(j.messages))throw new Error("Recent messages were not supplied by the history source");let K=j.messages.slice(-20).map(z=>{let re=J(z)?z:{},te=re.content==null?"Message content not recorded.":typeof re.content=="string"?re.content:JSON.stringify(re.content),ue=u("article","");return ue.append(u("h3",ee(re.role,"Unknown role")),u("p",ee(re.timestamp,"Time not recorded.")),u("pre",te)),ue});c("session-history").dataset.state="ready",c("session-history").replaceChildren(...K.length?K:[u("p","No recent messages returned.")]),l("session-history-status",`Latest ${K.length} messages.${j.truncated===!0?" Older messages are not shown.":""}`),l("session-source",`Provider ${ee(j.provider,"not recorded")}; session ${ee(j.sessionId,"not recorded")}. Optional bounded provider tail. ${j.truncated===!0?"Older output truncated. ":""}Fetched ${new Date().toISOString()}.`)}catch(j){S(D)&&(c("session-history").dataset.state="error",c("session-history").children.length===0&&c("session-history").replaceChildren(u("p","Recent messages unavailable.")),l("session-history-status","Recent messages unavailable. Try Refresh transcript."),l("session-source",`History unavailable; previous content may be stale. ${C(j)}`))}finally{P===D&&(P=null),S(D)&&(c("session-refresh").disabled=!1)}}async function se(){if(!s||m||document.hidden)return;let D=f;try{let j=new URLSearchParams({ownerTeam:s,ownerAlias:r,limit:"20"}),K=await w(`${n}/api/tasks?${j}`);if(!S(D))return;if(!Array.isArray(K.rows))throw new Error("Invalid task response");c("session-tasks").replaceChildren(u("p","Up to 20 assigned work items."),...K.rows.slice(0,20).map(z=>{let re=u("a",`#${z.id} ${z.title} \u2014 ${z.kind}, ${z.status}`);re.href=`${n}/tasks/${Number(z.id)}`;let te=u("p","");if(te.append(re),Number.isSafeInteger(z.parent_id)&&z.parent_id>0){let ue=u("a",` Parent work item #${z.parent_id}`);ue.href=`${n}/tasks/${z.parent_id}`,te.append(ue)}return te}),...K.rows.length?[]:[u("p","No recorded assignment for this session.")])}catch(j){S(D)&&l("session-tasks",`Assigned work unavailable: ${C(j)}`)}}async function k(){if(E===g||h===null||m||document.hidden)return;E=g;let D=h,j=g,K=f;try{let z=await w(`${n}/api/queue/${D}/state`);if(j!==g||!S(K))return;if(z.id!==D)throw new Error("Queue identity mismatch");if(z.lifecycle==="finished"&&!b(z.lifecycleBasis)&&!z.answer)throw new Error("Finished state has no correlated response");if(z.answer&&z.answer.prompt_queue_id!==D)throw new Error("Answer correlation mismatch");c("comm-state").dataset.queueId=String(D),c("comm-state").dataset.lifecycle=z.lifecycle,c("comm-state").dataset.lifecycleBasis=z.lifecycleBasis,l("comm-state",`Queue #${D}: ${N(z)}. Created ${z.createdAt}. Last checked ${new Date().toISOString()}.`),z.answer?l("comm-response",`${z.answer.answer_text}
589
+ })();</script>`}function VD(){let e=document.getElementById("session-detail"),{team:t="",alias:r="",mount:n="",history:o="",canonicalTeamfile:s="",commEnabled:i="false",commPageEnabled:a="false"}=e.dataset,c=D=>document.getElementById(D),l=(D,j)=>{c(D).textContent=j},u=(D,j)=>{let K=document.createElement(D);return K.textContent=j,K},d=new Map,m=!1,f=0,p,h=null,g=0,_=0,E=null,y=null,S=D=>!m&&!document.hidden&&D===f,T=()=>{},R=[],A=!1;function I(D){let j=u("span",D),K=R.find(z=>z.name===D);if(!K){let z=A?"Recorded label; current actor unresolved":"Recorded label; current team list unavailable";return j.title=`${D} \u2014 ${z}`,/[\\/]/.test(D)&&(j.textContent=D.split(/[\\/]/).at(-1).replace(/\.lmctl(?=:|$)/,"")),j}if(K.channel==="lmmail")return j.textContent+=" (remote inbox)",j;if(K.channel==="local"&&K.leadAlias&&D!=="operator"){let z=u("a",`${K.name}:${K.leadAlias}`);z.title="Current configured inbox lead; not a historical sender session",j.textContent="",z.href=`${n}/sessions/${encodeURIComponent(K.name)}/${encodeURIComponent(K.leadAlias)}`,j.append(z)}return j}function x(D,j){let K=u("span","");return K.append(I(D),u("span"," \u2192 "),I(j)),K}let H=D=>`${n}/sessions/${encodeURIComponent(t)}/${encodeURIComponent(r)}?queue=${D}`,C=D=>D instanceof Error?D.message:String(D);async function w(D,j){let K=new AbortController;d.set(K,j===void 0);let z=setTimeout(()=>K.abort(),15e3);try{let re=await fetch(D,{method:j===void 0?"GET":"POST",signal:K.signal,credentials:"same-origin",cache:"no-store",redirect:"error",headers:{Accept:"application/json",...j===void 0?{}:{"Content-Type":"application/json"}},...j===void 0?{}:{body:JSON.stringify(j)}});if(!re.ok)throw new Error(`HTTP ${re.status}; request unsuccessful`);if(!re.headers.get("content-type")?.includes("application/json"))throw new Error("Expected JSON response");let te=re.body.getReader(),ue=new TextDecoder,xe=0,Se="";for(;;){let Y=await te.read();if(Y.done)break;if(xe+=Y.value.byteLength,xe>2e6)throw await te.cancel(),new Error("Response exceeds 2 MB limit");Se+=ue.decode(Y.value,{stream:!0})}return JSON.parse(Se+ue.decode())}finally{clearTimeout(z),d.delete(K)}}function b(D){return D==="merged"||D==="informational"||D==="retracted"}function N(D,j=!1){if(j){if(D.lifecycle==="queued")return"queued";if(D.lifecycle==="finished")return D.lifecycleBasis==="merged"?"finished \xB7 merged into an earlier message":D.lifecycleBasis==="informational"?"finished \xB7 informational, no reply expected":D.lifecycleBasis==="retracted"?"finished \xB7 retracted, no reply expected":"finished \xB7 reply recorded";if(D.lifecycle==="processing")return D.lifecycleBasis==="confirmed"?"processing \xB7 picked up":"processing \xB7 attempted"}if(D.lifecycle==="finished")return D.lifecycleBasis==="merged"?"finished \u2014 merged into an earlier message, no separate response":D.lifecycleBasis==="informational"?"finished \u2014 informational, no response expected":D.lifecycleBasis==="retracted"?"finished \u2014 retracted, no response expected":"finished \u2014 response recorded";if(D.lifecycle==="queued")return"queued \u2014 waiting for handling";if(D.lifecycle==="processing")return D.lifecycleBasis==="confirmed"?"processing \u2014 picked up by inbox":"processing \u2014 delivery attempted; read not confirmed";throw new Error("Unknown lifecycle in owner response")}let M=null,W=D=>D!==null&&typeof D=="object"&&!Array.isArray(D),ee=(D,j)=>typeof D=="string"&&D.trim()?D:j,oe=!1;async function J(){if(!oe||M===f||m||document.hidden)return;let D=f;M=D,c("session-refresh").disabled=!0;try{let j=await w(o);if(!S(D))return;if(!W(j)||!Array.isArray(j.messages))throw new Error("Recent messages were not supplied by the history source");let K=j.messages.slice(-20).map(z=>{let re=W(z)?z:{},te=re.content==null?"Message content not recorded.":typeof re.content=="string"?re.content:JSON.stringify(re.content),ue=u("article","");return ue.append(u("h3",ee(re.role,"Unknown role")),u("p",ee(re.timestamp,"Time not recorded.")),u("pre",te)),ue});c("session-history").dataset.state="ready",c("session-history").replaceChildren(...K.length?K:[u("p","No recent messages returned.")]),l("session-history-status",`Latest ${K.length} messages.${j.truncated===!0?" Older messages are not shown.":""}`),l("session-source",`Provider ${ee(j.provider,"not recorded")}; session ${ee(j.sessionId,"not recorded")}. Optional bounded provider tail. ${j.truncated===!0?"Older output truncated. ":""}Fetched ${new Date().toISOString()}.`)}catch(j){S(D)&&(c("session-history").dataset.state="error",c("session-history").children.length===0&&c("session-history").replaceChildren(u("p","Recent messages unavailable.")),l("session-history-status","Recent messages unavailable. Try Refresh transcript."),l("session-source",`History unavailable; previous content may be stale. ${C(j)}`))}finally{M===D&&(M=null),S(D)&&(c("session-refresh").disabled=!1)}}async function se(){if(!s||m||document.hidden)return;let D=f;try{let j=new URLSearchParams({ownerTeam:s,ownerAlias:r,limit:"20"}),K=await w(`${n}/api/tasks?${j}`);if(!S(D))return;if(!Array.isArray(K.rows))throw new Error("Invalid task response");c("session-tasks").replaceChildren(u("p","Up to 20 assigned work items."),...K.rows.slice(0,20).map(z=>{let re=u("a",`#${z.id} ${z.title} \u2014 ${z.kind}, ${z.status}`);re.href=`${n}/tasks/${Number(z.id)}`;let te=u("p","");if(te.append(re),Number.isSafeInteger(z.parent_id)&&z.parent_id>0){let ue=u("a",` Parent work item #${z.parent_id}`);ue.href=`${n}/tasks/${z.parent_id}`,te.append(ue)}return te}),...K.rows.length?[]:[u("p","No recorded assignment for this session.")])}catch(j){S(D)&&l("session-tasks",`Assigned work unavailable: ${C(j)}`)}}async function k(){if(E===g||h===null||m||document.hidden)return;E=g;let D=h,j=g,K=f;try{let z=await w(`${n}/api/queue/${D}/state`);if(j!==g||!S(K))return;if(z.id!==D)throw new Error("Queue identity mismatch");if(z.lifecycle==="finished"&&!b(z.lifecycleBasis)&&!z.answer)throw new Error("Finished state has no correlated response");if(z.answer&&z.answer.prompt_queue_id!==D)throw new Error("Answer correlation mismatch");c("comm-state").dataset.queueId=String(D),c("comm-state").dataset.lifecycle=z.lifecycle,c("comm-state").dataset.lifecycleBasis=z.lifecycleBasis,l("comm-state",`Queue #${D}: ${N(z)}. Created ${z.createdAt}. Last checked ${new Date().toISOString()}.`),z.answer?l("comm-response",`${z.answer.answer_text}
590
590
  ${z.answer.truncated?`Truncated response; ${z.answer.totalBytes} total bytes. No continuation endpoint available.`:""}`):l("comm-response",z.lifecycleBasis==="merged"?"No separate answer: prompt merged into another prompt.":z.lifecycleBasis==="informational"?"No answer expected: this was an informational prompt.":z.lifecycleBasis==="retracted"?"No answer expected: this prompt was retracted.":"Outcome unknown: no reply recorded. This does not establish failure or unread work."),z.lifecycle!=="finished"&&++_<60?p=setTimeout(()=>void k(),5e3):z.lifecycle!=="finished"&&l("comm-state",`Queue #${D}: observation stalled \u2014 automatic checks paused after 60 reads; last state ${N(z)}. Check again manually. This does not establish execution failure.`)}catch(z){j===g&&S(K)&&l("comm-state",`State check failed; last content may be stale. ${C(z)}. Check again manually.`)}finally{E===j&&(E=null)}}async function O(D,j=!1){if(!Number.isSafeInteger(D)||D<1||m||document.hidden)return;c("comm-reading-panel").hidden=!1,y={id:D,admitted:j},clearTimeout(p),h=null,g++,_=0;let K=g,z=f;delete c("comm-state").dataset.queueId,delete c("comm-state").dataset.lifecycle,delete c("comm-state").dataset.lifecycleBasis,l("comm-context","Loading recorded endpoints. Related task: not recorded; assigned work shown separately."),l("comm-state",`Loading queue #${D}\u2026`),l("comm-response",""),l("comm-preview","Loading request preview\u2026"),c("comm-check").hidden=!1;let re=new URL(location.href);re.searchParams.set("queue",String(D)),window.history.replaceState(null,"",re);try{let te=await w(`${n}/api/queue/${D}`);if(K!==g||!S(z))return;if(te.queue.id!==D)throw new Error("Queue envelope identity mismatch");if(j&&te.queue.to_id!=="math")throw new Error("Admitted receipt is not addressed to math");if(te.queue.to_id!==t&&te.queue.from_id!==t)throw new Error("Queue message does not belong to this team");h=D;let ue=c("comm-context");if(ue.replaceChildren(u("span",`Request #${D}: `),x(te.queue.from_id,te.queue.to_id),u("span",". Expected reply context: "),I(te.queue.to_id),u("span",` inbox for prompt #${D} from `),I(te.queue.from_id),u("span",". Check the response status below; a reply may not be recorded. Related task: not recorded; assigned work shown separately.")),typeof te.queue.retracted_reason=="string"&&te.queue.retracted_reason&&ue.append(u("span",` Retraction reason: ${te.queue.retracted_reason}.`)),a==="true"&&te.queue.to_id==="math"){let Se=u("a","Open full prompt and answer");Se.href=`${n}/comm/math/prompts/${D}`,ue.append(Se)}let xe=await w(`${n}/api/queue/${D}/preview`);if(K!==g||!S(z))return;if(xe.id!==D)throw new Error("Preview identity mismatch");l("comm-preview",xe.status==="available"?`${xe.text??""}${xe.truncated?`
591
- [Prompt preview truncated]`:""}`:`Prompt preview ${xe.status}; content unavailable.`)}catch(te){K===g&&S(z)&&(l("comm-preview",`Prompt preview unavailable: ${C(te)}`),h===null&&l("comm-state","Queue selection unavailable; select a message from this team."))}await k()}let $=null;async function q(){if($===f||m||document.hidden)return;let D=f;$=D,c("comm-refresh").disabled=!0;try{let j=await w(`${n}/api/teams`).catch(()=>null);if(!S(D))return;R=j?.teams??[],A=j!==null;let K=R.find(Y=>Y.name===t),z=K?.channel==="local"&&typeof K.description=="string"?K.description.trim():"";l("session-purpose",j===null?"Team purpose unavailable.":z?`Recorded team description: \u201C${z}\u201D`:"No team purpose recorded.");let re=await Promise.all(["to","from"].map(async Y=>{let Te=await w(`${n}/api/queue/prompts?${Y}=${encodeURIComponent(t)}&limit=20`);if(!Array.isArray(Te.rows))throw new Error("Invalid message list");return Te}));if(!S(D))return;let te=new Map;for(let Y of re)for(let Te of Y.rows.slice(0,20)){if(!Number.isSafeInteger(Te.id)||Te.id<1)throw new Error("Invalid queue identity");if(Te.to_id!==t&&Te.from_id!==t)throw new Error("Message outside current team");let Je=te.get(Te.id);(!Je||Te.lifecycle==="finished"&&Je.lifecycle!=="finished")&&te.set(Te.id,Te)}let ue=Y=>Number.isFinite(Date.parse(Y))?Date.parse(Y):Number.MAX_VALUE,Se=[...te.values()].sort((Y,Te)=>ue(Y.created_ts)-ue(Te.created_ts)||Y.id-Te.id).map(Y=>{let Te=u("li","");Te.dataset.queueId=String(Y.id);let Je=u("a",`Read exchange #${Y.id}`);Je.href=H(Y.id),Je.addEventListener("click",ye=>{ye.defaultPrevented||ye.button!==0||ye.metaKey||ye.ctrlKey||ye.shiftKey||ye.altKey||(ye.preventDefault(),O(Y.id))}),Te.append(Je);let Be=u("div","");Be.dataset.queueId=String(Y.id),Be.dataset.event="request";let Pt=Number.isFinite(Date.parse(Y.created_ts))?Y.created_ts:"Time not recorded; placed last by request ID",G=u("span",Y.lifecycle==="queued"?"Queued":Y.lifecycle==="processing"?"Processing":Y.lifecycleBasis==="merged"?"Combined":Y.lifecycleBasis==="informational"?"Informational":Y.lifecycleBasis==="retracted"?"Retracted":"Replied");if(G.className=`status-chip status-${Y.lifecycle==="queued"?"queued":Y.lifecycle==="processing"?"processing":b(Y.lifecycleBasis)?"muted":"replied"}`,G.title=N(Y),Be.append(u("p",`Request recorded: ${Pt}`),x(Y.from_id,Y.to_id),G),Y.from_id===Y.to_id&&Be.append(u("p","Self-addressed request.")),Y.subject_id!=null&&Be.append(u("p",`Recorded subject label: ${Y.subject_id}`)),Te.append(Be),Y.lifecycle==="finished"&&!b(Y.lifecycleBasis)){let ye=u("div","");ye.dataset.queueId=String(Y.id),ye.dataset.event="response",ye.append(u("span","Answer recorded in "),I(Y.to_id),u("span",` inbox for prompt #${Y.id} from `),I(Y.from_id),u("p",`Recorded reply time: ${Y.answeredAt??"Time not recorded"}`));let at=u("details",""),tt=u("pre","Open to load the recorded reply.");at.append(u("summary","Show reply"),tt);let gt=!1,ze=!1;at.addEventListener("toggle",async()=>{if(!at.open||gt||ze||m||document.hidden)return;let yn=f;ze=!0,tt.textContent="Loading reply\u2026";try{let br=await w(`${n}/api/queue/${Y.id}/state`);if(!S(yn))return;let cr=br.answer;if(br.id!==Y.id||cr===null||cr.prompt_queue_id!==Y.id)throw new Error("Answer identity mismatch");if(typeof cr.answer_text!="string")throw new Error("Reply text unavailable");let rt=Array.from(cr.answer_text);tt.textContent=rt.slice(0,1200).join("")+(rt.length>1200||cr.truncated?`
592
- [Reply excerpt; open the full exchange for available text.]`:""),gt=!0}catch(br){S(yn)&&(tt.textContent=`Reply unavailable: ${C(br)}. Close and reopen to retry.`)}finally{ze=!1}}),ye.append(at),Te.append(ye)}else Te.append(u("p",Y.lifecycleBasis==="merged"?"No separate answer: prompt merged into another prompt.":Y.lifecycleBasis==="informational"?"No answer expected: this was an informational prompt.":Y.lifecycleBasis==="retracted"?`No answer expected: this prompt was retracted. Reason: ${Y.retracted_reason??"no reason recorded"}.`:"Reply: not recorded"));return Te});c("comm-sequence").replaceChildren(...Se.slice(-5)),c("comm-older-sequence").replaceChildren(...Se.slice(0,-5)),c("comm-older").hidden=Se.length<=5,l("comm-older-label",`Show ${Math.max(0,Se.length-5)} older loaded prompts`),l("comm-coverage",`Showing newest ${Math.min(5,Se.length)} of ${te.size} loaded prompts, ordered by arrival, oldest first; answers are grouped with their prompts. ${re.some(Y=>Y.meta.next_cursor!==null)?"This is a limited sample; additional records have not been loaded.":"All prompts from the returned pages are available here."}`)}catch(j){S(D)&&l("comm-coverage",`Message context unavailable; previous events may be stale. ${C(j)}`)}finally{$===D&&($=null),S(D)&&(c("comm-refresh").disabled=!1)}}let M=c("comm-form");if(M&&i==="true"&&t==="math"&&r==="Lead"){let D=c("comm-draft"),j=c("comm-submit"),K=c("comm-confirm"),z=c("comm-edit"),re=null,te=!1,ue=!1,xe="Page paused during admission";T=()=>{m||document.hidden||!re||!ue||(K.disabled=te,te||(l("comm-send-status",`Admission uncertain or failed: ${xe}. Retry preserves the exact prompt and dedupe key. Keep this page open until resolved.`),K.textContent="Retry same prompt safely"))},M.addEventListener("submit",Se=>{if(Se.preventDefault(),!(m||document.hidden||te||re)){if(!D.value.trim()||new TextEncoder().encode(D.value).length>65536){l("comm-send-status","Enter a nonblank prompt of at most 64 KiB UTF-8.");return}re={to:"math",prompt:D.value,dedupeKey:`localweb:${crypto.randomUUID()}`},D.disabled=!0,j.disabled=!0,l("comm-review",`To math, from operator:
593
- ${re.prompt}`),c("comm-review").hidden=!1,K.hidden=!1,z.hidden=!1,l("comm-send-status","Review the exact prompt before confirming.")}}),z.addEventListener("click",()=>{te||ue||(re=null,D.disabled=!1,j.disabled=!1,K.hidden=!0,z.hidden=!0,c("comm-review").hidden=!0)}),K.addEventListener("click",async()=>{if(!re||te||m||document.hidden)return;let Se=f;te=!0,ue=!0,K.disabled=!0,z.hidden=!0,l("comm-send-status","Submitting; waiting for confirmation that the prompt was queued\u2026");try{let Y=await w(`${n}/api/comm/send`,re);if(!S(Se))throw new Error("Page paused before receipt could be shown");if(!Number.isSafeInteger(Y.queueId)||Y.queueId<1)throw new Error("Missing queue receipt");l("comm-send-status",`Accepted as queue #${Y.queueId}${Y.replayed?" (existing prompt recovered)":""}.`),re=null,ue=!1,D.value="",D.disabled=!1,j.disabled=!1,K.hidden=!0,K.textContent="Confirm send to math",c("comm-review").hidden=!0,O(Y.queueId,!0),q()}catch(Y){xe=C(Y)}finally{te=!1,!m&&!document.hidden&&(K.disabled=!1),T()}})}c("session-refresh").addEventListener("click",()=>{oe=!0,l("session-refresh","Refresh transcript"),V()}),c("comm-refresh").addEventListener("click",()=>void q()),c("comm-check").addEventListener("click",()=>{clearTimeout(p),_=0,k()});let Z=D=>{f++,g++,clearTimeout(p),P=null,$=null;for(let[j,K]of d)(D||K)&&j.abort()},W=()=>{m||document.hidden||(oe&&V(),se(),q(),y&&O(y.id,y.admitted),T())},ae=()=>{document.hidden?Z(!1):W()};document.addEventListener("visibilitychange",ae);let be=()=>{m=!0,Z(!0),document.removeEventListener("visibilitychange",ae)};window.addEventListener("pagehide",be),window.addEventListener("pageshow",D=>{D.persisted&&(m=!1,document.addEventListener("visibilitychange",ae),W())}),se(),q();let ne=Number(new URL(location.href).searchParams.get("queue"));return Number.isSafeInteger(ne)&&ne>0&&O(ne),be}function BE(e){let{context:t}=e,r=e.config??pe,n=e.remoteStalledConfig??{},o=e.fetchReport??ke,s=e.send??Vt,i=e.whoami??Ju,a=e.fetchHealth??Gy,c=e.heavyLockStatusPath??zn(),l=e.heavyLockPath??Yn(),u=e.tail??Pi,d=e.tailJson??Ui,m=new cn;if(e.publish===!0){let w=e.passcodeFilePath!==void 0?e.passcodeFilePath:Xn(t.db.path),b=e.readPasscodeAuthority??(()=>w===null?null:H_(w));oE(m,{allowedOrigins:e.allowedOrigins,mountPath:e.mountPath,readAuthority:b,...e.remoteKey!==void 0?{remoteKey:e.remoteKey}:{}})}else m.use("*",async(w,b)=>{w.header("Cache-Control","no-store");let N=w.req.header("origin");if(N!==void 0&&!e.allowedOrigins.includes(N))return w.json({error:"origin not allowed"},403);await b()});m.route("/",wE({context:t,allowedOrigins:e.allowedOrigins,mountPath:e.mountPath,enabled:!0})),jE(m,t,e.mountPath),mE(m,{webDistDir:e.webDistDir,mountPath:e.mountPath}),$E(m,t,e.mountPath),CE(m,t,e.mountPath),qE(m,t,e.mountPath),m.post("/api/jobs/on-demand",async w=>{let b;try{b=await w.req.json()}catch{return w.json({error:"invalid JSON"},400)}if(b===null||typeof b!="object"||Array.isArray(b))return w.json({error:"expected object"},400);let N=b;if(typeof N.db!="string"||typeof N.local_scope!="string"||typeof N.script!="string"||!Array.isArray(N.args)||!N.args.every(P=>typeof P=="string")||N.conversationid!==void 0&&typeof N.conversationid!="string")return w.json({error:"invalid on-demand request"},400);try{let P=await $w(t.db.db,t.db.path,t.teams,{db:N.db,localScope:N.local_scope,script:N.script,args:N.args,...typeof N.conversationid=="string"?{conversationId:N.conversationid}:{}});return w.json(P,202)}catch(P){return w.json({error:P instanceof Error?P.message:String(P)},400)}}),m.get("/api/teams",w=>w.json(Vu(t))),m.get("/api/identities/:key",w=>w.json(Vs(t.teams,w.req.param("key")))),m.get("/api/state",w=>{let b=w.req.query("team");return b!==void 0?w.json(Bu(t,b)):w.req.query("active")!==void 0?w.json(Wu(t)):w.json(Hu(t))}),m.get("/api/status",async w=>{let b=w.req.query("live")==="1"||w.req.query("live")==="true",N=await Gu(t,{live:b,fetchReport:o});return w.json(N)}),m.get("/api/liveness",async w=>{let b=await o(),N=t.teams.map(P=>{let J=B(P)?null:ni(t.db.db,{site:P.peerSite,team:P.name,alias:P.alias});return{team:P.name,running:B(P)?je(P,b):!1,deadReclaimable:B(P)?on(P,b):!1,remoteOutbound:J?{state:J.state,sentTs:J.sent_ts,ackedTs:J.acked_ts,repliedTs:J.replied_ts}:null}});return w.json({report:b,teams:N})}),m.get("/api/stalled",async w=>{let b=await o(),N=dt(c,l,void 0,ee=>{process.stderr.write(`[api/stalled] heavy-lock probe failed, treating conservatively as held: ${ee.message}
594
- `)}),P=await On(t.db.db,t.teams.filter(B),b,N,r,void 0,{readOnly:!0}),J=kw(t.db.db,t.teams.filter(ee=>!B(ee)),n);return w.json({stalled:P,remoteStalled:J})});function f(w){let b=t.teams.find(P=>P.name===w);if(!b)return{error:`unknown team "${w}"`,status:404};if(!B(b))return{error:`team "${w}" is a remote team (channel=lmmail) -- not reachable via lctl`,status:400};let N;try{N=Q(b)}catch(P){return{error:P instanceof Error?P.message:String(P),status:500}}return{teamfilePath:N}}function p(w,b,N,P){return d(w,b,{lines:N?Number(N):20,...P?{since:P}:{}})}let h=(e.mountPath??"").replace(/\/$/,"");m.get("/running",w=>{try{let b=ns(),N=b.report===null?"<p>Activity has not yet been observed; running, dead, and idle counts are unknown.</p>":`<p>Cached observation taken ${b.observedAt?fe(b.observedAt):"at an unknown time"}. Refreshing this page does not run a new activity scan.</p>`,P=b.lastError?`<p class="warning">Observer failed${b.lastErrorAt?` ${fe(b.lastErrorAt)}`:""}: ${v(b.lastError)}. ${b.report?"Showing the last successful observation.":"No successful observation is available."}</p>`:"",J=b.report===null?"":Ky(Vl(b.report),qr(t.teams),h);return De(w,$e("Running","<p>This page loaded just now; activity data comes from a separate scheduled observation and may be older.</p>"+N+P+J,h))}catch(b){return De(w,$e("Running unavailable",`<p>${v(b instanceof Error?b.message:String(b))}</p>`,h),502)}}),m.get("/sessions/:team/:alias",w=>{let b=w.req.param("team"),N=w.req.param("alias"),P=`Session: ${b} / ${N}`,J={"data-page":"session","data-team":b,"data-alias":N},ee=f(b);if("error"in ee)return De(w,$e(P,`<p role="alert">${v(ee.error)}</p>`,h,J),ee.status);let oe=HE(b,N,h,{canonicalTeamfile:ee.teamfilePath,commPageEnabled:!0}),V=Array.from(oe.matchAll(/<script>([\s\S]*?)<\/script>/g),se=>se[1]);return De(w,$e(P,oe,h,J,V))}),m.get("/api/session/:team/:alias",async w=>{let b=w.req.param("team"),N=w.req.param("alias"),P=f(b);if("error"in P)return w.json({error:P.error},P.status);let{teamfilePath:J}=P,ee=w.req.query("since"),oe=w.req.query("limit");try{let V=await p(J,N,oe,ee);return w.json(V)}catch(V){return w.json({error:V instanceof Error?V.message:String(V)},404)}}),m.get("/api/transcript",async w=>{let b=w.req.query("team");if(!b)return w.json({error:"team is required"},400);let N=t.teams.find(V=>V.name===b);if(!N)return w.json({error:`unknown team "${b}"`},404);if(!B(N))return w.json({error:`team "${b}" is a remote team (channel=lmmail) -- not reachable via lctl`},400);let P=w.req.query("alias")??N.leadAlias,J;try{J=Q(N)}catch(V){return w.json({error:V instanceof Error?V.message:String(V)},500)}let ee=w.req.query("lines"),oe=w.req.query("since");try{let V=await u(J,P,{...ee?{lines:Number(ee)}:{},...oe?{since:oe}:{}});return w.json({team:b,alias:P,...V})}catch(V){return w.json({error:V instanceof Error?V.message:String(V)},502)}}),m.get("/api/queue",w=>{let b=w.req.query("to");return w.json(Pu(t,b))}),m.get("/api/queue/stats",w=>{try{let b=A(w.req.query("to"),"to");return w.json(qu(t,b))}catch(b){return _(w,b)}});let g=w=>{try{let b=w.req.query(),N={fromId:A(b.from,"from"),toId:A(b.to,"to"),status:x(b.status),since:H(b.since,"since"),until:H(b.until,"until"),after:y(b.after,"after"),limit:y(b.limit,"limit",200)};return w.json(ba(t,N))}catch(b){return _(w,b)}};m.get("/api/queue/prompts",g),m.get("/api/queue/:id",w=>{let b=Number(w.req.param("id")),N=to(t,b);return N?w.json({queue:N}):w.json(Ae("queue_not_found",`no queue entry ${b}`),404)}),m.get("/api/queue/:id/state",w=>{let b=Number(w.req.param("id")),N=hs(t,b);return N?w.json(N):w.json(Ae("queue_not_found",`no queue entry ${b}`),404)}),m.post("/api/queue/:id/answer",async w=>{try{let b=T(w.req.param("id"),"id"),N=await w.req.json().catch(()=>({})),P=A(N.from,"from"),J=A(N.text,"text");if(P===void 0||J===void 0)return w.json(Ae("invalid_argument","from and text are required"),400);let ee=mn(t.db.db,b,P,J);return w.json({answer:ee},202)}catch(b){return _(w,b)}}),m.get("/api/queue/:id/preview",w=>{try{let b=T(w.req.param("id"),"id"),N=Ur(t,b);return N?w.json(N):w.json(Ae("queue_not_found",`no queue entry ${b}`),404)}catch(b){return _(w,b)}}),m.post("/api/enqueue",async w=>{let b=await w.req.json().catch(()=>({})),N=b.prompt;if(!b.to||!N||!b.from)return w.json({error:"to, prompt, and from are required"},400);if(b.from==="autopilot")return w.json({error:"from: 'autopilot' is reserved for the tool's own automated enqueues"},400);try{let P=e.publish===!0&&b.from==="operator",J=we(t.db.db,t.teams,b.to,N,{from:b.from,...P?{operatorPriority:!0}:{}});return w.json({id:J})}catch(P){return w.json({error:P instanceof Error?P.message:String(P)},400)}}),m.post("/api/comm/send",async w=>{try{let b=await w.req.json().catch(()=>({})),N=A(b.to,"to"),P=A(b.prompt,"prompt"),J=A(b.dedupeKey,"dedupeKey");if(N===void 0||P===void 0||J===void 0)return w.json(Ae("invalid_argument","to, prompt, and dedupeKey are required"),400);let ee=Aa(t.db.db,t.teams,{to:N,prompt:P,dedupeKey:J});return w.json(ee,ee.replayed?200:202)}catch(b){return _(w,b)}}),m.post("/api/queue/deliver",async w=>{let b=await o(),N=Ar(t.db.db,{teams:t.teams,report:b,...e.remoteMail?{remoteMail:e.remoteMail}:{}});return w.json({delivered:N})}),m.post("/api/queue/retrieve",async w=>{let b=await w.req.json().catch(()=>({}));if(!b.to)return w.json({error:"to is required"},400);if(b.id!==void 0&&(!Number.isInteger(b.id)||b.id<=0))return w.json({error:"id must be a positive integer"},400);try{let P=ci(t.db.db,b.to,b.id).map(J=>{let ee;try{ee=JD(J.prompt_file,"utf8")}catch{ee="(could not read prompt file)"}return{...J,content:ee}});return w.json({retrieved:P})}catch(N){return _(w,N)}}),m.get("/api/inbox",w=>{let b=w.req.query("to");return b?w.json(Fu(t,b)):w.json(Ae("to_required","to is required"),400)});function _(w,b){if(b instanceof L){let N=b.code==="NOT_FOUND"?404:b.code==="CONFLICT"?409:b.code==="DB_BUSY"?503:b.code==="STORAGE_ERROR"?500:400;return w.json(Ae(b.code,b.message),N)}return w.json(Ae("internal_error",b instanceof Error?b.message:String(b)),500)}let E=new Set(["epic","task","subtask"]);function y(w,b,N){if(w===void 0)return;let P=Number(w);if(!/^[1-9]\d*$/.test(w)||!Number.isSafeInteger(P)||N!==void 0&&P>N)throw new L("INVALID_ARGUMENT",N!==void 0?`${b} must be a positive integer <= ${N}`:`${b} must be a positive integer`);return P}function S(w,b){if(w===void 0)return;let N=Number(w);if(!/^\d+$/.test(w)||!Number.isSafeInteger(N))throw new L("INVALID_ARGUMENT",`${b} must be a nonnegative integer`);return N}function T(w,b){let N=Number(w);if(!/^[1-9]\d*$/.test(w)||!Number.isSafeInteger(N))throw new L("INVALID_ARGUMENT",`${b} must be a positive integer`);return N}function R(w){if(w!==void 0){if(!E.has(w))throw new L("INVALID_ARGUMENT","kind must be 'epic', 'task', or 'subtask'");return w}}function A(w,b){if(w!==void 0){if(w.trim()==="")throw new L("INVALID_ARGUMENT",`${b} must not be blank`);return w}}function I(w,b){if(w!==void 0){if(w==="1"||w==="true")return!0;if(w==="0"||w==="false")return!1;throw new L("INVALID_ARGUMENT",`${b} must be '1'/'true' or '0'/'false'`)}}function x(w){if(w!==void 0){if(!Dc.includes(w))throw new L("INVALID_ARGUMENT",`status must be one of: ${Dc.join(", ")}`);return w}}function H(w,b){if(w===void 0)return;let N=w.trim()===""?NaN:Date.parse(w);if(Number.isNaN(N))throw new L("INVALID_ARGUMENT",`${b} must be a valid ISO8601 date-time string`);return new Date(N).toISOString()}function C(w,b){let N=A(w,"ownerTeam"),P=A(b,"ownerAlias");if(!(N===void 0&&P===void 0)){if(N===void 0||P===void 0)throw new L("INVALID_ARGUMENT","ownerTeam and ownerAlias must both be given");return{team:N,alias:P}}}return m.get("/api/tasks",w=>{let b=w.req.query();try{let N={project:A(b.project,"project"),kind:R(b.kind),status:A(b.status,"status"),parentId:y(b.parentId,"parentId"),owner:C(b.ownerTeam,b.ownerAlias),unassigned:I(b.unassigned,"unassigned"),limit:y(b.limit,"limit",Ie),after:S(b.after,"after")};return w.json(kr(t.db.db,N))}catch(N){return _(w,N)}}),m.get("/api/tasks/summary",w=>{try{let b=y(w.req.query("id"),"id"),N=A(w.req.query("project"),"project");return w.json(Nr(t.db.db,{id:b,project:N}))}catch(b){return _(w,b)}}),m.get("/api/tasks/:id",w=>{try{let b=T(w.req.param("id"),"id");return w.json(xr(t.db.db,b))}catch(b){return _(w,b)}}),m.get("/api/tasks/:id/tree",w=>{try{let b=T(w.req.param("id"),"id");return w.json(Rr(t.db.db,b))}catch(b){return _(w,b)}}),m.get("/api/tasks/:id/notes",w=>{try{let b=T(w.req.param("id"),"id"),N=S(w.req.query("after"),"after"),P=y(w.req.query("limit"),"limit",Ie);return w.json(Qf(t.db.db,b,{limit:P,after:N}))}catch(b){return _(w,b)}}),m.post("/api/send",async w=>{let b=await w.req.json().catch(()=>({})),N=b.prompt;if(!b.team||!N)return w.json({error:"team and prompt are required"},400);let P=t.teams.find(V=>V.name===b.team);if(!P)return w.json({error:`unknown team "${b.team}"`},404);if(!B(P))return w.json({error:`team "${b.team}" is a remote team (channel=lmmail) -- not reachable via lctl`},400);let J=await s({teamfilePath:Q(P),alias:P.leadAlias},N),ee=Zn(J),oe=Date.now();return ur(t.db.db,P.name,ee.status,oe),nt(t.db.db,P.name,ee.status,oe,{note:"web send"}),w.json({status:ee.status,outcome:J})}),m.get("/api/history",w=>{let b=w.req.query("team"),N=w.req.query("limit"),P=Au(t,b,N);return"error"in P?w.json(P,400):w.json(P)}),m.get("/api/sources",w=>w.json(ju(t))),m.get("/api/mail/status",w=>w.json($u(t))),m.get("/api/subscriptions",async w=>{let{status:b,body:N}=await Vy();return w.json(N,b)}),m.get("/api/whoami",async w=>{let{data:b,exitCode:N}=await i();return"error"in b?w.json(b,N===4?502:400):w.json(b)}),m.get("/api/running",async w=>w.json(await o())),m.get("/api/running/humanized",async w=>w.json(Vl(await o()))),m.get("/api/running/observed",w=>w.json(ns())),m.get("/api/heavy-lock",w=>{try{return w.json(Gl(c,l))}catch(b){if(b instanceof Jn)return w.json(Ae("heavy_lock_probe_failed",b.message),502);throw b}}),m.get("/api/health",async w=>{let b=w.req.query("target");if(!b)return w.json(Ae("target_required","target is required"),400);try{let N=await a(b);return w.json(N)}catch(N){return w.json(Ae("health_fetch_failed",N instanceof Error?N.message:String(N)),502)}}),m.post("/api/sources",async w=>{let b=await w.req.json().catch(()=>({}));if(!b.path)return w.json({error:"path is required"},400);let N=Ta(t,b.path,b.label??void 0);return N.ok?(t.teams=Zr(t.db.db,t.teamsConfPath),w.json({ok:!0})):w.json({error:N.output},400)}),m.delete("/api/sources",w=>{let b=w.req.query("path");return b?(zs(t.db.db,b),t.teams=Zr(t.db.db,t.teamsConfPath),w.json({ok:!0})):w.json({error:"path is required"},400)}),m}function sd(e){return e.teams=Zr(e.db.db,e.teamsConfPath),e.teams}var zD=4173,YD="127.0.0.1";function WE(e){if(process.env.LMBEE_SITE_UUID!==void 0)try{let h=kn(e.context.db.db,void 0,process.env.LMBEE_SITE_UUID);if(e.remoteMail&&e.remoteMail.localSiteId!==h)throw new Error("Remote mail site identity conflicts with the database binding")}catch(h){return Promise.reject(h)}let t=e.port??zD,r=e.hostname??YD,n=e.publish??!1;if(!["127.0.0.1","::1","localhost"].includes(r)&&!n)return Promise.reject(new Error("LocalWeb refuses a non-loopback bind without --publish (which also requires passcode auth)"));let o=r==="::1"?"[::1]":r,s=us(e.context.db.path),i=null;if(s!==null)try{i=_a(s,e.lockOwnerLabel??"lmbee-serve")}catch(h){return Promise.reject(h)}let a=t===0?[]:[`http://${o}:${t}`,`http://localhost:${t}`,`http://[::1]:${t}`],c=e.remoteMail?{client:e.remoteMail.client,localSiteId:e.remoteMail.localSiteId}:void 0,l,u,d,m,f=null,p=null;try{let h=e.passcodeFilePath??Xn(e.context.db.path);n&&h!==null&&wa(h),l=BE({context:e.context,allowedOrigins:a,publish:n,passcodeFilePath:h,...e.config!==void 0?{config:e.config}:{},...e.fetchReport!==void 0?{fetchReport:e.fetchReport}:{},...e.mountPath!==void 0?{mountPath:e.mountPath}:{},...e.webDistDir!==void 0?{webDistDir:e.webDistDir}:{},...c?{remoteMail:c}:{},...e.remoteStalledConfig!==void 0?{remoteStalledConfig:e.remoteStalledConfig}:{}});let g=e.mountPath?.endsWith("/")?e.mountPath.slice(0,-1):e.mountPath;if(g?u=new cn().route(g,l).get(`${g}/`,async _=>{let E=new URL(_.req.url);E.pathname="/",E.search="";let y=await l.fetch(new Request(E,{method:"GET",headers:_.req.raw.headers}));return y.ok?_.redirect(g,302):y}):u=l,d=I_({db:e.context.db.db,getTeams:()=>sd(e.context),...e.intervalMs!==void 0?{intervalMs:e.intervalMs}:{},...e.config!==void 0?{config:e.config}:{},...e.fetchReport!==void 0?{fetchReport:e.fetchReport}:{},...e.maintainerWake!==void 0?{maintainerWake:e.maintainerWake}:{},...e.autoContinue!==void 0?{autoContinue:e.autoContinue}:{},...e.miniplayerVerify!==void 0?{miniplayerVerify:e.miniplayerVerify}:{},...e.hungHolderCheck!==void 0?{hungHolderCheck:e.hungHolderCheck}:{},...e.epicReview!==void 0?{epicReview:e.epicReview}:{},...e.orphanReconciler!==void 0?{orphanReconciler:e.orphanReconciler}:{},...e.hangProbeCollect!==void 0?{hangProbeCollect:e.hangProbeCollect}:{},...e.autoNudgeRedirectReview!==void 0?{autoNudgeRedirectReview:e.autoNudgeRedirectReview}:{},...e.rateLimitCollect!==void 0?{rateLimitCollect:e.rateLimitCollect}:{},...e.rateLimitPolicy!==void 0?{rateLimitPolicy:e.rateLimitPolicy}:{},...e.rateLimitAutomation!==void 0?{rateLimitAutomation:e.rateLimitAutomation}:{},onTick:_=>{process.stderr.write(`[cron] tick: watch=${_.watch.why}, ${_.stalled.length} stalled (${_.stalled.join(", ")||"none"})${_.maintainerWoken?", maintainer woken":""}${_.autoContinued.length?`, auto-continued (${_.autoContinued.join(", ")})`:""}
591
+ [Prompt preview truncated]`:""}`:`Prompt preview ${xe.status}; content unavailable.`)}catch(te){K===g&&S(z)&&(l("comm-preview",`Prompt preview unavailable: ${C(te)}`),h===null&&l("comm-state","Queue selection unavailable; select a message from this team."))}await k()}let $=null;async function q(){if($===f||m||document.hidden)return;let D=f;$=D,c("comm-refresh").disabled=!0;try{let j=await w(`${n}/api/teams`).catch(()=>null);if(!S(D))return;R=j?.teams??[],A=j!==null;let K=R.find(Y=>Y.name===t),z=K?.channel==="local"&&typeof K.description=="string"?K.description.trim():"";l("session-purpose",j===null?"Team purpose unavailable.":z?`Recorded team description: \u201C${z}\u201D`:"No team purpose recorded.");let re=await Promise.all(["to","from"].map(async Y=>{let Te=await w(`${n}/api/queue/prompts?${Y}=${encodeURIComponent(t)}&limit=20`);if(!Array.isArray(Te.rows))throw new Error("Invalid message list");return Te}));if(!S(D))return;let te=new Map;for(let Y of re)for(let Te of Y.rows.slice(0,20)){if(!Number.isSafeInteger(Te.id)||Te.id<1)throw new Error("Invalid queue identity");if(Te.to_id!==t&&Te.from_id!==t)throw new Error("Message outside current team");let Je=te.get(Te.id);(!Je||Te.lifecycle==="finished"&&Je.lifecycle!=="finished")&&te.set(Te.id,Te)}let ue=Y=>Number.isFinite(Date.parse(Y))?Date.parse(Y):Number.MAX_VALUE,Se=[...te.values()].sort((Y,Te)=>ue(Y.created_ts)-ue(Te.created_ts)||Y.id-Te.id).map(Y=>{let Te=u("li","");Te.dataset.queueId=String(Y.id);let Je=u("a",`Read exchange #${Y.id}`);Je.href=H(Y.id),Je.addEventListener("click",ye=>{ye.defaultPrevented||ye.button!==0||ye.metaKey||ye.ctrlKey||ye.shiftKey||ye.altKey||(ye.preventDefault(),O(Y.id))}),Te.append(Je);let Be=u("div","");Be.dataset.queueId=String(Y.id),Be.dataset.event="request";let Pt=Number.isFinite(Date.parse(Y.created_ts))?Y.created_ts:"Time not recorded; placed last by request ID",V=u("span",Y.lifecycle==="queued"?"Queued":Y.lifecycle==="processing"?"Processing":Y.lifecycleBasis==="merged"?"Combined":Y.lifecycleBasis==="informational"?"Informational":Y.lifecycleBasis==="retracted"?"Retracted":"Replied");if(V.className=`status-chip status-${Y.lifecycle==="queued"?"queued":Y.lifecycle==="processing"?"processing":b(Y.lifecycleBasis)?"muted":"replied"}`,V.title=N(Y),Be.append(u("p",`Request recorded: ${Pt}`),x(Y.from_id,Y.to_id),V),Y.from_id===Y.to_id&&Be.append(u("p","Self-addressed request.")),Y.subject_id!=null&&Be.append(u("p",`Recorded subject label: ${Y.subject_id}`)),Te.append(Be),Y.lifecycle==="finished"&&!b(Y.lifecycleBasis)){let ye=u("div","");ye.dataset.queueId=String(Y.id),ye.dataset.event="response",ye.append(u("span","Answer recorded in "),I(Y.to_id),u("span",` inbox for prompt #${Y.id} from `),I(Y.from_id),u("p",`Recorded reply time: ${Y.answeredAt??"Time not recorded"}`));let at=u("details",""),tt=u("pre","Open to load the recorded reply.");at.append(u("summary","Show reply"),tt);let gt=!1,ze=!1;at.addEventListener("toggle",async()=>{if(!at.open||gt||ze||m||document.hidden)return;let yn=f;ze=!0,tt.textContent="Loading reply\u2026";try{let br=await w(`${n}/api/queue/${Y.id}/state`);if(!S(yn))return;let cr=br.answer;if(br.id!==Y.id||cr===null||cr.prompt_queue_id!==Y.id)throw new Error("Answer identity mismatch");if(typeof cr.answer_text!="string")throw new Error("Reply text unavailable");let rt=Array.from(cr.answer_text);tt.textContent=rt.slice(0,1200).join("")+(rt.length>1200||cr.truncated?`
592
+ [Reply excerpt; open the full exchange for available text.]`:""),gt=!0}catch(br){S(yn)&&(tt.textContent=`Reply unavailable: ${C(br)}. Close and reopen to retry.`)}finally{ze=!1}}),ye.append(at),Te.append(ye)}else Te.append(u("p",Y.lifecycleBasis==="merged"?"No separate answer: prompt merged into another prompt.":Y.lifecycleBasis==="informational"?"No answer expected: this was an informational prompt.":Y.lifecycleBasis==="retracted"?`No answer expected: this prompt was retracted. Reason: ${Y.retracted_reason??"no reason recorded"}.`:"Reply: not recorded"));return Te});c("comm-sequence").replaceChildren(...Se.slice(-5)),c("comm-older-sequence").replaceChildren(...Se.slice(0,-5)),c("comm-older").hidden=Se.length<=5,l("comm-older-label",`Show ${Math.max(0,Se.length-5)} older loaded prompts`),l("comm-coverage",`Showing newest ${Math.min(5,Se.length)} of ${te.size} loaded prompts, ordered by arrival, oldest first; answers are grouped with their prompts. ${re.some(Y=>Y.meta.next_cursor!==null)?"This is a limited sample; additional records have not been loaded.":"All prompts from the returned pages are available here."}`)}catch(j){S(D)&&l("comm-coverage",`Message context unavailable; previous events may be stale. ${C(j)}`)}finally{$===D&&($=null),S(D)&&(c("comm-refresh").disabled=!1)}}let U=c("comm-form");if(U&&i==="true"&&t==="math"&&r==="Lead"){let D=c("comm-draft"),j=c("comm-submit"),K=c("comm-confirm"),z=c("comm-edit"),re=null,te=!1,ue=!1,xe="Page paused during admission";T=()=>{m||document.hidden||!re||!ue||(K.disabled=te,te||(l("comm-send-status",`Admission uncertain or failed: ${xe}. Retry preserves the exact prompt and dedupe key. Keep this page open until resolved.`),K.textContent="Retry same prompt safely"))},U.addEventListener("submit",Se=>{if(Se.preventDefault(),!(m||document.hidden||te||re)){if(!D.value.trim()||new TextEncoder().encode(D.value).length>65536){l("comm-send-status","Enter a nonblank prompt of at most 64 KiB UTF-8.");return}re={to:"math",prompt:D.value,dedupeKey:`localweb:${crypto.randomUUID()}`},D.disabled=!0,j.disabled=!0,l("comm-review",`To math, from operator:
593
+ ${re.prompt}`),c("comm-review").hidden=!1,K.hidden=!1,z.hidden=!1,l("comm-send-status","Review the exact prompt before confirming.")}}),z.addEventListener("click",()=>{te||ue||(re=null,D.disabled=!1,j.disabled=!1,K.hidden=!0,z.hidden=!0,c("comm-review").hidden=!0)}),K.addEventListener("click",async()=>{if(!re||te||m||document.hidden)return;let Se=f;te=!0,ue=!0,K.disabled=!0,z.hidden=!0,l("comm-send-status","Submitting; waiting for confirmation that the prompt was queued\u2026");try{let Y=await w(`${n}/api/comm/send`,re);if(!S(Se))throw new Error("Page paused before receipt could be shown");if(!Number.isSafeInteger(Y.queueId)||Y.queueId<1)throw new Error("Missing queue receipt");l("comm-send-status",`Accepted as queue #${Y.queueId}${Y.replayed?" (existing prompt recovered)":""}.`),re=null,ue=!1,D.value="",D.disabled=!1,j.disabled=!1,K.hidden=!0,K.textContent="Confirm send to math",c("comm-review").hidden=!0,O(Y.queueId,!0),q()}catch(Y){xe=C(Y)}finally{te=!1,!m&&!document.hidden&&(K.disabled=!1),T()}})}c("session-refresh").addEventListener("click",()=>{oe=!0,l("session-refresh","Refresh transcript"),J()}),c("comm-refresh").addEventListener("click",()=>void q()),c("comm-check").addEventListener("click",()=>{clearTimeout(p),_=0,k()});let Z=D=>{f++,g++,clearTimeout(p),M=null,$=null;for(let[j,K]of d)(D||K)&&j.abort()},G=()=>{m||document.hidden||(oe&&J(),se(),q(),y&&O(y.id,y.admitted),T())},ae=()=>{document.hidden?Z(!1):G()};document.addEventListener("visibilitychange",ae);let be=()=>{m=!0,Z(!0),document.removeEventListener("visibilitychange",ae)};window.addEventListener("pagehide",be),window.addEventListener("pageshow",D=>{D.persisted&&(m=!1,document.addEventListener("visibilitychange",ae),G())}),se(),q();let ne=Number(new URL(location.href).searchParams.get("queue"));return Number.isSafeInteger(ne)&&ne>0&&O(ne),be}function BE(e){let{context:t}=e,r=e.config??pe,n=e.remoteStalledConfig??{},o=e.fetchReport??ke,s=e.send??Vt,i=e.whoami??Ju,a=e.fetchHealth??Gy,c=e.heavyLockStatusPath??zn(),l=e.heavyLockPath??Yn(),u=e.tail??Pi,d=e.tailJson??Ui,m=new cn;if(e.publish===!0){let w=e.passcodeFilePath!==void 0?e.passcodeFilePath:Xn(t.db.path),b=e.readPasscodeAuthority??(()=>w===null?null:H_(w));oE(m,{allowedOrigins:e.allowedOrigins,mountPath:e.mountPath,readAuthority:b,...e.remoteKey!==void 0?{remoteKey:e.remoteKey}:{}})}else m.use("*",async(w,b)=>{w.header("Cache-Control","no-store");let N=w.req.header("origin");if(N!==void 0&&!e.allowedOrigins.includes(N))return w.json({error:"origin not allowed"},403);await b()});m.route("/",wE({context:t,allowedOrigins:e.allowedOrigins,mountPath:e.mountPath,enabled:!0})),jE(m,t,e.mountPath),mE(m,{webDistDir:e.webDistDir,mountPath:e.mountPath}),$E(m,t,e.mountPath),CE(m,t,e.mountPath),qE(m,t,e.mountPath),m.post("/api/jobs/on-demand",async w=>{let b;try{b=await w.req.json()}catch{return w.json({error:"invalid JSON"},400)}if(b===null||typeof b!="object"||Array.isArray(b))return w.json({error:"expected object"},400);let N=b;if(typeof N.db!="string"||typeof N.local_scope!="string"||typeof N.script!="string"||!Array.isArray(N.args)||!N.args.every(M=>typeof M=="string")||N.conversationid!==void 0&&typeof N.conversationid!="string")return w.json({error:"invalid on-demand request"},400);try{let M=await $w(t.db.db,t.db.path,t.teams,{db:N.db,localScope:N.local_scope,script:N.script,args:N.args,...typeof N.conversationid=="string"?{conversationId:N.conversationid}:{}});return w.json(M,202)}catch(M){if(M instanceof P||M instanceof L){let W=M.code==="INVALID_ARGUMENT"||M.code==="INVALID_SCHEDULE"?400:M.code==="NOT_FOUND"?404:M.code==="CONFLICT"?409:M.code==="DB_BUSY"?503:500;return W===503&&w.header("Retry-After","1"),w.json({error:M.message},W)}return w.json({error:M instanceof Error?M.message:String(M)},500)}}),m.get("/api/teams",w=>w.json(Vu(t))),m.get("/api/identities/:key",w=>w.json(Vs(t.teams,w.req.param("key")))),m.get("/api/state",w=>{let b=w.req.query("team");return b!==void 0?w.json(Bu(t,b)):w.req.query("active")!==void 0?w.json(Wu(t)):w.json(Hu(t))}),m.get("/api/status",async w=>{let b=w.req.query("live")==="1"||w.req.query("live")==="true",N=await Gu(t,{live:b,fetchReport:o});return w.json(N)}),m.get("/api/liveness",async w=>{let b=await o(),N=t.teams.map(M=>{let W=B(M)?null:ni(t.db.db,{site:M.peerSite,team:M.name,alias:M.alias});return{team:M.name,running:B(M)?je(M,b):!1,deadReclaimable:B(M)?on(M,b):!1,remoteOutbound:W?{state:W.state,sentTs:W.sent_ts,ackedTs:W.acked_ts,repliedTs:W.replied_ts}:null}});return w.json({report:b,teams:N})}),m.get("/api/stalled",async w=>{let b=await o(),N=dt(c,l,void 0,ee=>{process.stderr.write(`[api/stalled] heavy-lock probe failed, treating conservatively as held: ${ee.message}
594
+ `)}),M=await On(t.db.db,t.teams.filter(B),b,N,r,void 0,{readOnly:!0}),W=kw(t.db.db,t.teams.filter(ee=>!B(ee)),n);return w.json({stalled:M,remoteStalled:W})});function f(w){let b=t.teams.find(M=>M.name===w);if(!b)return{error:`unknown team "${w}"`,status:404};if(!B(b))return{error:`team "${w}" is a remote team (channel=lmmail) -- not reachable via lctl`,status:400};let N;try{N=Q(b)}catch(M){return{error:M instanceof Error?M.message:String(M),status:500}}return{teamfilePath:N}}function p(w,b,N,M){return d(w,b,{lines:N?Number(N):20,...M?{since:M}:{}})}let h=(e.mountPath??"").replace(/\/$/,"");m.get("/running",w=>{try{let b=ns(),N=b.report===null?"<p>Activity has not yet been observed; running, dead, and idle counts are unknown.</p>":`<p>Cached observation taken ${b.observedAt?fe(b.observedAt):"at an unknown time"}. Refreshing this page does not run a new activity scan.</p>`,M=b.lastError?`<p class="warning">Observer failed${b.lastErrorAt?` ${fe(b.lastErrorAt)}`:""}: ${v(b.lastError)}. ${b.report?"Showing the last successful observation.":"No successful observation is available."}</p>`:"",W=b.report===null?"":Ky(Vl(b.report),qr(t.teams),h);return De(w,$e("Running","<p>This page loaded just now; activity data comes from a separate scheduled observation and may be older.</p>"+N+M+W,h))}catch(b){return De(w,$e("Running unavailable",`<p>${v(b instanceof Error?b.message:String(b))}</p>`,h),502)}}),m.get("/sessions/:team/:alias",w=>{let b=w.req.param("team"),N=w.req.param("alias"),M=`Session: ${b} / ${N}`,W={"data-page":"session","data-team":b,"data-alias":N},ee=f(b);if("error"in ee)return De(w,$e(M,`<p role="alert">${v(ee.error)}</p>`,h,W),ee.status);let oe=HE(b,N,h,{canonicalTeamfile:ee.teamfilePath,commPageEnabled:!0}),J=Array.from(oe.matchAll(/<script>([\s\S]*?)<\/script>/g),se=>se[1]);return De(w,$e(M,oe,h,W,J))}),m.get("/api/session/:team/:alias",async w=>{let b=w.req.param("team"),N=w.req.param("alias"),M=f(b);if("error"in M)return w.json({error:M.error},M.status);let{teamfilePath:W}=M,ee=w.req.query("since"),oe=w.req.query("limit");try{let J=await p(W,N,oe,ee);return w.json(J)}catch(J){return w.json({error:J instanceof Error?J.message:String(J)},404)}}),m.get("/api/transcript",async w=>{let b=w.req.query("team");if(!b)return w.json({error:"team is required"},400);let N=t.teams.find(J=>J.name===b);if(!N)return w.json({error:`unknown team "${b}"`},404);if(!B(N))return w.json({error:`team "${b}" is a remote team (channel=lmmail) -- not reachable via lctl`},400);let M=w.req.query("alias")??N.leadAlias,W;try{W=Q(N)}catch(J){return w.json({error:J instanceof Error?J.message:String(J)},500)}let ee=w.req.query("lines"),oe=w.req.query("since");try{let J=await u(W,M,{...ee?{lines:Number(ee)}:{},...oe?{since:oe}:{}});return w.json({team:b,alias:M,...J})}catch(J){return w.json({error:J instanceof Error?J.message:String(J)},502)}}),m.get("/api/queue",w=>{let b=w.req.query("to");return w.json(Pu(t,b))}),m.get("/api/queue/stats",w=>{try{let b=A(w.req.query("to"),"to");return w.json(qu(t,b))}catch(b){return _(w,b)}});let g=w=>{try{let b=w.req.query(),N={fromId:A(b.from,"from"),toId:A(b.to,"to"),status:x(b.status),since:H(b.since,"since"),until:H(b.until,"until"),after:y(b.after,"after"),limit:y(b.limit,"limit",200)};return w.json(ba(t,N))}catch(b){return _(w,b)}};m.get("/api/queue/prompts",g),m.get("/api/queue/:id",w=>{let b=Number(w.req.param("id")),N=to(t,b);return N?w.json({queue:N}):w.json(Ae("queue_not_found",`no queue entry ${b}`),404)}),m.get("/api/queue/:id/state",w=>{let b=Number(w.req.param("id")),N=hs(t,b);return N?w.json(N):w.json(Ae("queue_not_found",`no queue entry ${b}`),404)}),m.post("/api/queue/:id/answer",async w=>{try{let b=T(w.req.param("id"),"id"),N=await w.req.json().catch(()=>({})),M=A(N.from,"from"),W=A(N.text,"text");if(M===void 0||W===void 0)return w.json(Ae("invalid_argument","from and text are required"),400);let ee=mn(t.db.db,b,M,W);return w.json({answer:ee},202)}catch(b){return _(w,b)}}),m.get("/api/queue/:id/preview",w=>{try{let b=T(w.req.param("id"),"id"),N=Ur(t,b);return N?w.json(N):w.json(Ae("queue_not_found",`no queue entry ${b}`),404)}catch(b){return _(w,b)}}),m.post("/api/enqueue",async w=>{let b=await w.req.json().catch(()=>({})),N=b.prompt;if(!b.to||!N||!b.from)return w.json({error:"to, prompt, and from are required"},400);if(b.from==="autopilot")return w.json({error:"from: 'autopilot' is reserved for the tool's own automated enqueues"},400);try{let M=e.publish===!0&&b.from==="operator",W=we(t.db.db,t.teams,b.to,N,{from:b.from,...M?{operatorPriority:!0}:{}});return w.json({id:W})}catch(M){return w.json({error:M instanceof Error?M.message:String(M)},400)}}),m.post("/api/comm/send",async w=>{try{let b=await w.req.json().catch(()=>({})),N=A(b.to,"to"),M=A(b.prompt,"prompt"),W=A(b.dedupeKey,"dedupeKey");if(N===void 0||M===void 0||W===void 0)return w.json(Ae("invalid_argument","to, prompt, and dedupeKey are required"),400);let ee=Aa(t.db.db,t.teams,{to:N,prompt:M,dedupeKey:W});return w.json(ee,ee.replayed?200:202)}catch(b){return _(w,b)}}),m.post("/api/queue/deliver",async w=>{let b=await o(),N=Ar(t.db.db,{teams:t.teams,report:b,...e.remoteMail?{remoteMail:e.remoteMail}:{}});return w.json({delivered:N})}),m.post("/api/queue/retrieve",async w=>{let b=await w.req.json().catch(()=>({}));if(!b.to)return w.json({error:"to is required"},400);if(b.id!==void 0&&(!Number.isInteger(b.id)||b.id<=0))return w.json({error:"id must be a positive integer"},400);try{let M=ci(t.db.db,b.to,b.id).map(W=>{let ee;try{ee=JD(W.prompt_file,"utf8")}catch{ee="(could not read prompt file)"}return{...W,content:ee}});return w.json({retrieved:M})}catch(N){return _(w,N)}}),m.get("/api/inbox",w=>{let b=w.req.query("to");return b?w.json(Fu(t,b)):w.json(Ae("to_required","to is required"),400)});function _(w,b){if(b instanceof L){let N=b.code==="NOT_FOUND"?404:b.code==="CONFLICT"?409:b.code==="DB_BUSY"?503:b.code==="STORAGE_ERROR"?500:400;return w.json(Ae(b.code,b.message),N)}return w.json(Ae("internal_error",b instanceof Error?b.message:String(b)),500)}let E=new Set(["epic","task","subtask"]);function y(w,b,N){if(w===void 0)return;let M=Number(w);if(!/^[1-9]\d*$/.test(w)||!Number.isSafeInteger(M)||N!==void 0&&M>N)throw new L("INVALID_ARGUMENT",N!==void 0?`${b} must be a positive integer <= ${N}`:`${b} must be a positive integer`);return M}function S(w,b){if(w===void 0)return;let N=Number(w);if(!/^\d+$/.test(w)||!Number.isSafeInteger(N))throw new L("INVALID_ARGUMENT",`${b} must be a nonnegative integer`);return N}function T(w,b){let N=Number(w);if(!/^[1-9]\d*$/.test(w)||!Number.isSafeInteger(N))throw new L("INVALID_ARGUMENT",`${b} must be a positive integer`);return N}function R(w){if(w!==void 0){if(!E.has(w))throw new L("INVALID_ARGUMENT","kind must be 'epic', 'task', or 'subtask'");return w}}function A(w,b){if(w!==void 0){if(w.trim()==="")throw new L("INVALID_ARGUMENT",`${b} must not be blank`);return w}}function I(w,b){if(w!==void 0){if(w==="1"||w==="true")return!0;if(w==="0"||w==="false")return!1;throw new L("INVALID_ARGUMENT",`${b} must be '1'/'true' or '0'/'false'`)}}function x(w){if(w!==void 0){if(!Dc.includes(w))throw new L("INVALID_ARGUMENT",`status must be one of: ${Dc.join(", ")}`);return w}}function H(w,b){if(w===void 0)return;let N=w.trim()===""?NaN:Date.parse(w);if(Number.isNaN(N))throw new L("INVALID_ARGUMENT",`${b} must be a valid ISO8601 date-time string`);return new Date(N).toISOString()}function C(w,b){let N=A(w,"ownerTeam"),M=A(b,"ownerAlias");if(!(N===void 0&&M===void 0)){if(N===void 0||M===void 0)throw new L("INVALID_ARGUMENT","ownerTeam and ownerAlias must both be given");return{team:N,alias:M}}}return m.get("/api/tasks",w=>{let b=w.req.query();try{let N={project:A(b.project,"project"),kind:R(b.kind),status:A(b.status,"status"),parentId:y(b.parentId,"parentId"),owner:C(b.ownerTeam,b.ownerAlias),unassigned:I(b.unassigned,"unassigned"),limit:y(b.limit,"limit",Ie),after:S(b.after,"after")};return w.json(kr(t.db.db,N))}catch(N){return _(w,N)}}),m.get("/api/tasks/summary",w=>{try{let b=y(w.req.query("id"),"id"),N=A(w.req.query("project"),"project");return w.json(Nr(t.db.db,{id:b,project:N}))}catch(b){return _(w,b)}}),m.get("/api/tasks/:id",w=>{try{let b=T(w.req.param("id"),"id");return w.json(xr(t.db.db,b))}catch(b){return _(w,b)}}),m.get("/api/tasks/:id/tree",w=>{try{let b=T(w.req.param("id"),"id");return w.json(Rr(t.db.db,b))}catch(b){return _(w,b)}}),m.get("/api/tasks/:id/notes",w=>{try{let b=T(w.req.param("id"),"id"),N=S(w.req.query("after"),"after"),M=y(w.req.query("limit"),"limit",Ie);return w.json(Qf(t.db.db,b,{limit:M,after:N}))}catch(b){return _(w,b)}}),m.post("/api/send",async w=>{let b=await w.req.json().catch(()=>({})),N=b.prompt;if(!b.team||!N)return w.json({error:"team and prompt are required"},400);let M=t.teams.find(J=>J.name===b.team);if(!M)return w.json({error:`unknown team "${b.team}"`},404);if(!B(M))return w.json({error:`team "${b.team}" is a remote team (channel=lmmail) -- not reachable via lctl`},400);let W=await s({teamfilePath:Q(M),alias:M.leadAlias},N),ee=Zn(W),oe=Date.now();return ur(t.db.db,M.name,ee.status,oe),nt(t.db.db,M.name,ee.status,oe,{note:"web send"}),w.json({status:ee.status,outcome:W})}),m.get("/api/history",w=>{let b=w.req.query("team"),N=w.req.query("limit"),M=Au(t,b,N);return"error"in M?w.json(M,400):w.json(M)}),m.get("/api/sources",w=>w.json(ju(t))),m.get("/api/mail/status",w=>w.json($u(t))),m.get("/api/subscriptions",async w=>{let{status:b,body:N}=await Vy();return w.json(N,b)}),m.get("/api/whoami",async w=>{let{data:b,exitCode:N}=await i();return"error"in b?w.json(b,N===4?502:400):w.json(b)}),m.get("/api/running",async w=>w.json(await o())),m.get("/api/running/humanized",async w=>w.json(Vl(await o()))),m.get("/api/running/observed",w=>w.json(ns())),m.get("/api/heavy-lock",w=>{try{return w.json(Gl(c,l))}catch(b){if(b instanceof Jn)return w.json(Ae("heavy_lock_probe_failed",b.message),502);throw b}}),m.get("/api/health",async w=>{let b=w.req.query("target");if(!b)return w.json(Ae("target_required","target is required"),400);try{let N=await a(b);return w.json(N)}catch(N){return w.json(Ae("health_fetch_failed",N instanceof Error?N.message:String(N)),502)}}),m.post("/api/sources",async w=>{let b=await w.req.json().catch(()=>({}));if(!b.path)return w.json({error:"path is required"},400);let N=Ta(t,b.path,b.label??void 0);return N.ok?(t.teams=Zr(t.db.db,t.teamsConfPath),w.json({ok:!0})):w.json({error:N.output},400)}),m.delete("/api/sources",w=>{let b=w.req.query("path");return b?(zs(t.db.db,b),t.teams=Zr(t.db.db,t.teamsConfPath),w.json({ok:!0})):w.json({error:"path is required"},400)}),m}function sd(e){return e.teams=Zr(e.db.db,e.teamsConfPath),e.teams}var zD=4173,YD="127.0.0.1";function WE(e){if(process.env.LMBEE_SITE_UUID!==void 0)try{let h=kn(e.context.db.db,void 0,process.env.LMBEE_SITE_UUID);if(e.remoteMail&&e.remoteMail.localSiteId!==h)throw new Error("Remote mail site identity conflicts with the database binding")}catch(h){return Promise.reject(h)}let t=e.port??zD,r=e.hostname??YD,n=e.publish??!1;if(!["127.0.0.1","::1","localhost"].includes(r)&&!n)return Promise.reject(new Error("LocalWeb refuses a non-loopback bind without --publish (which also requires passcode auth)"));let o=r==="::1"?"[::1]":r,s=us(e.context.db.path),i=null;if(s!==null)try{i=_a(s,e.lockOwnerLabel??"lmbee-serve")}catch(h){return Promise.reject(h)}let a=t===0?[]:[`http://${o}:${t}`,`http://localhost:${t}`,`http://[::1]:${t}`],c=e.remoteMail?{client:e.remoteMail.client,localSiteId:e.remoteMail.localSiteId}:void 0,l,u,d,m,f=null,p=null;try{let h=e.passcodeFilePath??Xn(e.context.db.path);n&&h!==null&&wa(h),l=BE({context:e.context,allowedOrigins:a,publish:n,passcodeFilePath:h,...e.config!==void 0?{config:e.config}:{},...e.fetchReport!==void 0?{fetchReport:e.fetchReport}:{},...e.mountPath!==void 0?{mountPath:e.mountPath}:{},...e.webDistDir!==void 0?{webDistDir:e.webDistDir}:{},...c?{remoteMail:c}:{},...e.remoteStalledConfig!==void 0?{remoteStalledConfig:e.remoteStalledConfig}:{}});let g=e.mountPath?.endsWith("/")?e.mountPath.slice(0,-1):e.mountPath;if(g?u=new cn().route(g,l).get(`${g}/`,async _=>{let E=new URL(_.req.url);E.pathname="/",E.search="";let y=await l.fetch(new Request(E,{method:"GET",headers:_.req.raw.headers}));return y.ok?_.redirect(g,302):y}):u=l,d=I_({db:e.context.db.db,getTeams:()=>sd(e.context),...e.intervalMs!==void 0?{intervalMs:e.intervalMs}:{},...e.config!==void 0?{config:e.config}:{},...e.fetchReport!==void 0?{fetchReport:e.fetchReport}:{},...e.maintainerWake!==void 0?{maintainerWake:e.maintainerWake}:{},...e.autoContinue!==void 0?{autoContinue:e.autoContinue}:{},...e.miniplayerVerify!==void 0?{miniplayerVerify:e.miniplayerVerify}:{},...e.hungHolderCheck!==void 0?{hungHolderCheck:e.hungHolderCheck}:{},...e.epicReview!==void 0?{epicReview:e.epicReview}:{},...e.orphanReconciler!==void 0?{orphanReconciler:e.orphanReconciler}:{},...e.hangProbeCollect!==void 0?{hangProbeCollect:e.hangProbeCollect}:{},...e.autoNudgeRedirectReview!==void 0?{autoNudgeRedirectReview:e.autoNudgeRedirectReview}:{},...e.rateLimitCollect!==void 0?{rateLimitCollect:e.rateLimitCollect}:{},...e.rateLimitPolicy!==void 0?{rateLimitPolicy:e.rateLimitPolicy}:{},...e.rateLimitAutomation!==void 0?{rateLimitAutomation:e.rateLimitAutomation}:{},onTick:_=>{process.stderr.write(`[cron] tick: watch=${_.watch.why}, ${_.stalled.length} stalled (${_.stalled.join(", ")||"none"})${_.maintainerWoken?", maintainer woken":""}${_.autoContinued.length?`, auto-continued (${_.autoContinued.join(", ")})`:""}
595
595
  `)},onError:_=>{process.stderr.write(`[cron] tick failed: ${_ instanceof Error?_.stack??_.message:String(_)}
596
596
  `)}}),m=Sw({db:e.context.db.db,getTeams:()=>sd(e.context),...e.queueIntervalMs!==void 0?{intervalMs:e.queueIntervalMs}:{},...e.fetchReport!==void 0?{fetchReport:e.fetchReport}:{},...c?{remoteMail:c}:{},...e.deliverImpl!==void 0?{deliverImpl:e.deliverImpl}:{},...e.minMemoryPercent!==void 0?{minMemoryPercent:e.minMemoryPercent}:{},onDeliver:_=>{_>0&&process.stderr.write(`[queue] delivered ${_}
597
597
  `)},onError:_=>{process.stderr.write(`[queue] delivery pass failed: ${_ instanceof Error?_.stack??_.message:String(_)}
@@ -600,16 +600,16 @@ ${re.prompt}`),c("comm-review").hidden=!1,K.hidden=!1,z.hidden=!1,l("comm-send-s
600
600
  `)})})}if(e.execWorker){let _=e.execWorker;p=(_.createExecWorkerImpl??ww)({client:_.client,mailbox:_.mailbox,adminUsers:_.adminUsers,allowUsers:_.allowUsers,allowAnonymous:_.allowAnonymous,..._.pollIntervalMs!==void 0?{pollIntervalMs:_.pollIntervalMs}:{},..._.timeoutCapSeconds!==void 0?{timeoutCapSeconds:_.timeoutCapSeconds}:{}})}}catch(h){throw i?.release(),h}return new Promise((h,g)=>{let _=!1,E;try{E=vp({fetch:u.fetch,port:t,hostname:r},y=>{if(t===0&&a.push(`http://${o}:${y.port}`,`http://localhost:${y.port}`,`http://[::1]:${y.port}`),_=!0,d.start(),m.start(),f&&e.remoteMail){let S=e.remoteMail;(S.ensureMailboxImpl??bw)(S.client,S.mailbox).then(()=>f?.start()).catch(R=>{process.stderr.write(`[mail] mailbox provisioning failed, mail lane stays dormant this run: ${R instanceof Error?R.stack??R.message:String(R)}
601
601
  `),S.onMailError?.(R)})}if(p&&e.execWorker){let S=e.execWorker;(S.ensureExecMailboxImpl??_w)(S.client,S.mailbox).then(()=>p?.start()).catch(R=>{process.stderr.write(`[exec-worker] mailbox provisioning failed, exec stays dormant this run: ${R instanceof Error?R.stack??R.message:String(R)}
602
602
  `)})}h({app:l,scheduler:d,queueScheduler:m,mailScheduler:f,execWorker:p,server:E,port:y.port,hostname:r,close(){d.stop(),m.stop(),f?.stop(),p?.stop(),E.close(),i?.release()},async shutdown(){d.stop(),m.stop(),f?.stop(),p?.stop();let S=new Promise((R,A)=>{E.close(I=>I?A(I):R())}),T=(async()=>{for(;d.isTicking()||m.isDelivering()||(f?.isPolling()??!1);)await new Promise(R=>setTimeout(R,50))})();await Promise.all([S,T,p?.whenIdle()??Promise.resolve()]),i?.release()}})})}catch(y){i?.release(),g(y instanceof Error?y:new Error(String(y)));return}E.on("error",y=>{if(_){process.stderr.write(`[serve] post-bind server error (ignored -- lock/scheduler untouched): ${y instanceof Error?y.stack??y.message:String(y)}
603
- `);return}_=!0,i?.release(),g(y instanceof Error?y:new Error(String(y)))})})}function Tt(e,t=[]){let r=new Set(t),n=[],o={};for(let s=0;s<e.length;s++){let i=e[s];if(i==="-h")o.help=!0;else if(i.startsWith("--")){let a=i.slice(2),c=e[s+1];!r.has(a)&&c!==void 0&&!c.startsWith("--")?(o[a]=c,s++):o[a]=!0}else n.push(i)}return{positionals:n,flags:o}}function fn(e,t){if(e===void 0)return;if(typeof e!="string")return new Error(`${t} requires a numeric value (milliseconds)`);let r=Number(e);return!Number.isFinite(r)||r<0?new Error(`${t} must be a finite, non-negative number of milliseconds, got "${e}"`):r}function co(e,t){if(e===void 0)return;if(typeof e!="string")return new Error(`${t} requires a numeric value`);let r=Number(e);return!Number.isFinite(r)||r<0?new Error(`${t} must be a finite, non-negative number, got "${e}"`):r}import{existsSync as KD,readFileSync as QD,writeFileSync as XD}from"node:fs";var id="lmbee-cron-export",GE=["schema_version","kind","exported_at","exported_from","jobs"],VE=["id","title","schedule_expr","action_kind","action_payload","provider","model","working_directory","escalation_owner","timezone","enabled"],ZD=["provider","model","working_directory","escalation_owner","timezone"];function eM(e){return{id:e.id,title:e.title,schedule_expr:e.schedule_expr,action_kind:e.action_kind,action_payload:e.action_payload,provider:e.provider,model:e.model,working_directory:e.working_directory,escalation_owner:e.escalation_owner,timezone:e.timezone,enabled:!!e.enabled}}function tM(e){return e instanceof Error&&"code"in e&&typeof e.code=="string"&&e.code.startsWith("SQLITE_BUSY")}function rM(e,t){let r;try{r=e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'cron_jobs'").get()!==void 0?e.prepare("SELECT * FROM cron_jobs ORDER BY id").all():[]}catch(n){throw tM(n)?new U("SOURCE_BUSY","source database is locked by another process -- export never waits on locks (busy_timeout = 0); retry shortly",3):n}for(let n of r)if(n.action_kind!=="command"&&n.action_kind!=="script")throw new U("INVALID_ARGUMENT",`cron job ${n.id} "${n.title}" has action_kind "${n.action_kind}" -- export does not carry ${n.action_kind}-kind jobs, so no file was written (import would refuse it; never produce a transferable payload containing one -- re-create the job manually on the target)`);return{schema_version:1,kind:id,exported_at:new Date().toISOString(),exported_from:t,jobs:r.map(eM)}}function nM(e,t,r){let n=rM(e,r);try{XD(t,`${JSON.stringify(n,null,2)}
604
- `,{flag:"wx"})}catch(o){throw o&&typeof o=="object"&&"code"in o&&o.code==="EEXIST"?new U("INVALID_ARGUMENT",`export path already exists: ${t} (rm it first; there is no --force)`):new U("INVALID_ARGUMENT",`cannot write export to ${t}: ${o instanceof Error?o.message:String(o)}`)}return n}function oM(e){let t=No(e);ic(t);let r=new wt(t,{readonly:!0,fileMustExist:!0});return r.pragma("busy_timeout = 0"),{db:r,path:t,close:()=>r.close()}}var JE=`usage: lmbee cron export PATH [--json] -- write all cron job DEFINITIONS (ids preserved) as one JSON document;
605
- refuses if PATH already exists (rm it first; there is no --force). Definitions only, never execution state.`;function _s(e,t,r){if(t.length>1)throw new U("INVALID_ARGUMENT",`cron ${e} takes exactly one PATH argument -- refusing unexpected extra argument ${JSON.stringify(t[1])}`);for(let n of Object.keys(r))if(n!=="json"&&n!=="help")throw new U("INVALID_ARGUMENT",`cron ${e} does not know flag "--${n}" (only --json and --help)`)}function zE(e){let{positionals:t,flags:r}=Tt(e,["json","help"]),n=r.json===!0;try{if(r.help===!0)return{output:JE,exitCode:0};_s("export",t,r);let o=t[0];if(o===void 0)throw new U("INVALID_ARGUMENT",`an export PATH is required
606
- ${JE}`);let s=oM();try{let i=nM(s.db,o,s.path);return n?{output:JSON.stringify({schema_version:1,ok:!0,data:{path:o,exported_from:s.path,jobs:i.jobs.length}}),exitCode:0}:{output:`exported ${i.jobs.length} jobs to ${o}`,exitCode:0}}finally{s.close()}}catch(o){if(o instanceof U)return n?{output:JSON.stringify({schema_version:1,ok:!1,error:{code:o.code,message:o.message}}),exitCode:o.exitCode}:{output:`${o.code}: ${o.message}`,exitCode:o.exitCode};throw o}}function St(e,t){throw new U("INVALID_ARGUMENT",`jobs[${e}]: ${t}`)}function sM(e,t){(typeof e!="object"||e===null||Array.isArray(e))&&St(t,"must be a JSON object");let r=e;for(let l of Object.keys(r))VE.includes(l)||St(t,`unknown key "${l}"`);for(let l of VE)l in r||St(t,`missing key "${l}"`);let{id:n,title:o,schedule_expr:s,action_kind:i,action_payload:a,enabled:c}=r;(typeof n!="number"||!Number.isSafeInteger(n)||n<1)&&St(t,"id must be a positive safe integer"),(typeof o!="string"||o.trim().length===0)&&St(t,"title must be a nonblank string"),typeof s!="string"&&St(t,"schedule_expr must be a string"),typeof i!="string"&&St(t,"action_kind must be a string"),i==="enqueue"&&St(t,"import does not carry enqueue-kind jobs (zero existed when this was designed; refusing rather than risking a payload current validation rejects -- create it manually)"),(i==="session"||i==="miniplayer")&&St(t,`import does not carry ${i}-kind jobs (out of scope -- untested expansion; create it manually)`),i!=="command"&&i!=="script"&&St(t,`action_kind "${i}" is not a known kind; only "command" and "script" are accepted`),typeof a!="string"&&St(t,"action_payload must be a string"),typeof c!="boolean"&&St(t,`enabled must be a JSON boolean (true/false), not ${JSON.stringify(c)}`);for(let l of ZD){let u=r[l];u!==null&&typeof u!="string"&&St(t,`${l} must be a string or null`)}return r}function YE(e){let t;try{t=QD(e,"utf8")}catch(i){throw new U("INVALID_ARGUMENT",`cannot read import file ${e}: ${i instanceof Error?i.message:String(i)}`)}let r;try{r=JSON.parse(t)}catch(i){throw new U("INVALID_ARGUMENT",`import file ${e} is not valid JSON: ${i instanceof Error?i.message:String(i)}`)}if(typeof r!="object"||r===null||Array.isArray(r))throw new U("INVALID_ARGUMENT","import document must be a JSON object");let n=r;for(let i of Object.keys(n))if(!GE.includes(i))throw new U("INVALID_ARGUMENT",`unknown top-level key "${i}"`);for(let i of GE)if(!(i in n))throw new U("INVALID_ARGUMENT",`missing top-level key "${i}"`);if(n.schema_version!==1)throw new U("INVALID_ARGUMENT",`schema_version must be 1, got ${JSON.stringify(n.schema_version)}`);if(n.kind!==id)throw new U("INVALID_ARGUMENT",`kind must be "${id}", got ${JSON.stringify(n.kind)}`);for(let i of["exported_at","exported_from"])if(typeof n[i]!="string")throw new U("INVALID_ARGUMENT",`${i} must be a string, got ${JSON.stringify(n[i])}`);if(!Array.isArray(n.jobs))throw new U("INVALID_ARGUMENT","jobs must be an array");let o=n.jobs.map((i,a)=>sM(i,a)),s=new Set;for(let i of o){if(s.has(i.id))throw new U("INVALID_ARGUMENT",`duplicate id ${i.id} within the document`);s.add(i.id)}return o}function KE(e){return{...e,title:e.title.trim(),timezone:e.timezone===null?null:e.timezone.trim()}}function iM(e,t){let r=KE(t);return e.title===r.title&&e.schedule_expr===r.schedule_expr&&e.action_kind===r.action_kind&&e.action_payload===r.action_payload&&e.provider===r.provider&&e.model===r.model&&e.working_directory===r.working_directory&&e.escalation_owner===r.escalation_owner&&e.timezone===r.timezone&&!!e.enabled===r.enabled}function aM(e){let t=KE(e);return{id:t.id,title:t.title,scheduleExpr:t.schedule_expr,actionKind:t.action_kind,actionPayload:t.action_payload,enabled:t.enabled,...t.provider!==null?{provider:t.provider}:{},...t.model!==null?{model:t.model}:{},...t.working_directory!==null?{workingDirectory:t.working_directory}:{},...t.escalation_owner!==null?{escalationOwner:t.escalation_owner}:{},...t.timezone!==null?{timezone:t.timezone}:{}}}function QE(e){YE(e)}function XE(e,t){let r=YE(t),n=[],o=[];e.transaction(()=>{for(let a of r){let c=Vi(e,a.id);if(c!==null){if(iM(c,a)){n.push({id:a.id,title:a.title});continue}throw new U("CONFLICT",`cron job ${a.id} already exists with a different definition: existing "${c.title}" vs import "${a.title}" -- refusing the whole file, nothing written`,4)}Vn(e,aM(a)),o.push(a)}}).immediate();let i=[];for(let a of o)a.working_directory!==null&&!KD(a.working_directory)&&i.push(`job ${a.id} "${a.title}": working_directory ${a.working_directory} does not exist on this host`);return{imported:o.length,skipped:n,warnings:i}}function ZE(e){let t=[`imported ${e.imported}, skipped ${e.skipped.length} already-present`];for(let r of e.skipped)t.push(`skipped: ${r.id} "${r.title}"`);for(let r of e.warnings)t.push(`warning: ${r}`);return t.join(`
603
+ `);return}_=!0,i?.release(),g(y instanceof Error?y:new Error(String(y)))})})}function Tt(e,t=[]){let r=new Set(t),n=[],o={};for(let s=0;s<e.length;s++){let i=e[s];if(i==="-h")o.help=!0;else if(i.startsWith("--")){let a=i.slice(2),c=e[s+1];!r.has(a)&&c!==void 0&&!c.startsWith("--")?(o[a]=c,s++):o[a]=!0}else n.push(i)}return{positionals:n,flags:o}}function fn(e,t){if(e===void 0)return;if(typeof e!="string")return new Error(`${t} requires a numeric value (milliseconds)`);let r=Number(e);return!Number.isFinite(r)||r<0?new Error(`${t} must be a finite, non-negative number of milliseconds, got "${e}"`):r}function co(e,t){if(e===void 0)return;if(typeof e!="string")return new Error(`${t} requires a numeric value`);let r=Number(e);return!Number.isFinite(r)||r<0?new Error(`${t} must be a finite, non-negative number, got "${e}"`):r}import{existsSync as KD,readFileSync as QD,writeFileSync as XD}from"node:fs";var id="lmbee-cron-export",GE=["schema_version","kind","exported_at","exported_from","jobs"],VE=["id","title","schedule_expr","action_kind","action_payload","provider","model","working_directory","escalation_owner","timezone","enabled"],ZD=["provider","model","working_directory","escalation_owner","timezone"];function eM(e){return{id:e.id,title:e.title,schedule_expr:e.schedule_expr,action_kind:e.action_kind,action_payload:e.action_payload,provider:e.provider,model:e.model,working_directory:e.working_directory,escalation_owner:e.escalation_owner,timezone:e.timezone,enabled:!!e.enabled}}function tM(e){return e instanceof Error&&"code"in e&&typeof e.code=="string"&&e.code.startsWith("SQLITE_BUSY")}function rM(e,t){let r;try{r=e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'cron_jobs'").get()!==void 0?e.prepare("SELECT * FROM cron_jobs ORDER BY id").all():[]}catch(n){throw tM(n)?new P("SOURCE_BUSY","source database is locked by another process -- export never waits on locks (busy_timeout = 0); retry shortly",3):n}for(let n of r)if(n.action_kind!=="command"&&n.action_kind!=="script")throw new P("INVALID_ARGUMENT",`cron job ${n.id} "${n.title}" has action_kind "${n.action_kind}" -- export does not carry ${n.action_kind}-kind jobs, so no file was written (import would refuse it; never produce a transferable payload containing one -- re-create the job manually on the target)`);return{schema_version:1,kind:id,exported_at:new Date().toISOString(),exported_from:t,jobs:r.map(eM)}}function nM(e,t,r){let n=rM(e,r);try{XD(t,`${JSON.stringify(n,null,2)}
604
+ `,{flag:"wx"})}catch(o){throw o&&typeof o=="object"&&"code"in o&&o.code==="EEXIST"?new P("INVALID_ARGUMENT",`export path already exists: ${t} (rm it first; there is no --force)`):new P("INVALID_ARGUMENT",`cannot write export to ${t}: ${o instanceof Error?o.message:String(o)}`)}return n}function oM(e){let t=No(e);ic(t);let r=new wt(t,{readonly:!0,fileMustExist:!0});return r.pragma("busy_timeout = 0"),{db:r,path:t,close:()=>r.close()}}var JE=`usage: lmbee cron export PATH [--json] -- write all cron job DEFINITIONS (ids preserved) as one JSON document;
605
+ refuses if PATH already exists (rm it first; there is no --force). Definitions only, never execution state.`;function _s(e,t,r){if(t.length>1)throw new P("INVALID_ARGUMENT",`cron ${e} takes exactly one PATH argument -- refusing unexpected extra argument ${JSON.stringify(t[1])}`);for(let n of Object.keys(r))if(n!=="json"&&n!=="help")throw new P("INVALID_ARGUMENT",`cron ${e} does not know flag "--${n}" (only --json and --help)`)}function zE(e){let{positionals:t,flags:r}=Tt(e,["json","help"]),n=r.json===!0;try{if(r.help===!0)return{output:JE,exitCode:0};_s("export",t,r);let o=t[0];if(o===void 0)throw new P("INVALID_ARGUMENT",`an export PATH is required
606
+ ${JE}`);let s=oM();try{let i=nM(s.db,o,s.path);return n?{output:JSON.stringify({schema_version:1,ok:!0,data:{path:o,exported_from:s.path,jobs:i.jobs.length}}),exitCode:0}:{output:`exported ${i.jobs.length} jobs to ${o}`,exitCode:0}}finally{s.close()}}catch(o){if(o instanceof P)return n?{output:JSON.stringify({schema_version:1,ok:!1,error:{code:o.code,message:o.message}}),exitCode:o.exitCode}:{output:`${o.code}: ${o.message}`,exitCode:o.exitCode};throw o}}function St(e,t){throw new P("INVALID_ARGUMENT",`jobs[${e}]: ${t}`)}function sM(e,t){(typeof e!="object"||e===null||Array.isArray(e))&&St(t,"must be a JSON object");let r=e;for(let l of Object.keys(r))VE.includes(l)||St(t,`unknown key "${l}"`);for(let l of VE)l in r||St(t,`missing key "${l}"`);let{id:n,title:o,schedule_expr:s,action_kind:i,action_payload:a,enabled:c}=r;(typeof n!="number"||!Number.isSafeInteger(n)||n<1)&&St(t,"id must be a positive safe integer"),(typeof o!="string"||o.trim().length===0)&&St(t,"title must be a nonblank string"),typeof s!="string"&&St(t,"schedule_expr must be a string"),typeof i!="string"&&St(t,"action_kind must be a string"),i==="enqueue"&&St(t,"import does not carry enqueue-kind jobs (zero existed when this was designed; refusing rather than risking a payload current validation rejects -- create it manually)"),(i==="session"||i==="miniplayer")&&St(t,`import does not carry ${i}-kind jobs (out of scope -- untested expansion; create it manually)`),i!=="command"&&i!=="script"&&St(t,`action_kind "${i}" is not a known kind; only "command" and "script" are accepted`),typeof a!="string"&&St(t,"action_payload must be a string"),typeof c!="boolean"&&St(t,`enabled must be a JSON boolean (true/false), not ${JSON.stringify(c)}`);for(let l of ZD){let u=r[l];u!==null&&typeof u!="string"&&St(t,`${l} must be a string or null`)}return r}function YE(e){let t;try{t=QD(e,"utf8")}catch(i){throw new P("INVALID_ARGUMENT",`cannot read import file ${e}: ${i instanceof Error?i.message:String(i)}`)}let r;try{r=JSON.parse(t)}catch(i){throw new P("INVALID_ARGUMENT",`import file ${e} is not valid JSON: ${i instanceof Error?i.message:String(i)}`)}if(typeof r!="object"||r===null||Array.isArray(r))throw new P("INVALID_ARGUMENT","import document must be a JSON object");let n=r;for(let i of Object.keys(n))if(!GE.includes(i))throw new P("INVALID_ARGUMENT",`unknown top-level key "${i}"`);for(let i of GE)if(!(i in n))throw new P("INVALID_ARGUMENT",`missing top-level key "${i}"`);if(n.schema_version!==1)throw new P("INVALID_ARGUMENT",`schema_version must be 1, got ${JSON.stringify(n.schema_version)}`);if(n.kind!==id)throw new P("INVALID_ARGUMENT",`kind must be "${id}", got ${JSON.stringify(n.kind)}`);for(let i of["exported_at","exported_from"])if(typeof n[i]!="string")throw new P("INVALID_ARGUMENT",`${i} must be a string, got ${JSON.stringify(n[i])}`);if(!Array.isArray(n.jobs))throw new P("INVALID_ARGUMENT","jobs must be an array");let o=n.jobs.map((i,a)=>sM(i,a)),s=new Set;for(let i of o){if(s.has(i.id))throw new P("INVALID_ARGUMENT",`duplicate id ${i.id} within the document`);s.add(i.id)}return o}function KE(e){return{...e,title:e.title.trim(),timezone:e.timezone===null?null:e.timezone.trim()}}function iM(e,t){let r=KE(t);return e.title===r.title&&e.schedule_expr===r.schedule_expr&&e.action_kind===r.action_kind&&e.action_payload===r.action_payload&&e.provider===r.provider&&e.model===r.model&&e.working_directory===r.working_directory&&e.escalation_owner===r.escalation_owner&&e.timezone===r.timezone&&!!e.enabled===r.enabled}function aM(e){let t=KE(e);return{id:t.id,title:t.title,scheduleExpr:t.schedule_expr,actionKind:t.action_kind,actionPayload:t.action_payload,enabled:t.enabled,...t.provider!==null?{provider:t.provider}:{},...t.model!==null?{model:t.model}:{},...t.working_directory!==null?{workingDirectory:t.working_directory}:{},...t.escalation_owner!==null?{escalationOwner:t.escalation_owner}:{},...t.timezone!==null?{timezone:t.timezone}:{}}}function QE(e){YE(e)}function XE(e,t){let r=YE(t),n=[],o=[];e.transaction(()=>{for(let a of r){let c=Vi(e,a.id);if(c!==null){if(iM(c,a)){n.push({id:a.id,title:a.title});continue}throw new P("CONFLICT",`cron job ${a.id} already exists with a different definition: existing "${c.title}" vs import "${a.title}" -- refusing the whole file, nothing written`,4)}Vn(e,aM(a)),o.push(a)}}).immediate();let i=[];for(let a of o)a.working_directory!==null&&!KD(a.working_directory)&&i.push(`job ${a.id} "${a.title}": working_directory ${a.working_directory} does not exist on this host`);return{imported:o.length,skipped:n,warnings:i}}function ZE(e){let t=[`imported ${e.imported}, skipped ${e.skipped.length} already-present`];for(let r of e.skipped)t.push(`skipped: ${r.id} "${r.title}"`);for(let r of e.warnings)t.push(`warning: ${r}`);return t.join(`
607
607
  `)}async function eb(e,t={}){let r=t.team===void 0?e.teams:e.teams.filter(c=>c.name===t.team);if(t.team!==void 0){if(r.length===0)throw new Error(`unknown team: ${t.team}`);if(!r.every(B))throw new Error(`stalled verdict requires a local team: ${t.team}`)}let n=r.filter(B),o=await(t.fetchReportImpl??ke)(),s=t.heavyLockImpl?.()??dt(void 0,void 0,void 0,c=>{process.stderr.write(`[stalled] heavy-lock probe failed, treating conservatively as held: ${c.message}
608
- `)}),i=t.nowMs??Date.now(),a=t.config??pe;return{teams:n.map(c=>({team:c.name,stalled:Qc(e.db.db,c,o,s,a,i)}))}}var xa=Ht(Lt(),1);import{readFileSync as cM}from"node:fs";function pn(e,t,r={}){if(e===void 0)return;if(typeof e!="string"||!/^\d+$/.test(e))throw new U("INVALID_ARGUMENT",`${t} must be a nonnegative integer`);let n=Number(e),o=r.minimum??1;if(!Number.isSafeInteger(n)||n<o||r.maximum!==void 0&&n>r.maximum){let s=r.maximum!==void 0?`between ${o} and ${r.maximum}`:`>= ${o}`;throw new U("INVALID_ARGUMENT",`${t} must be an integer ${s}`)}return n}function hr(e,t){let r=pn(e,t,{minimum:1});if(r===void 0)throw new U("INVALID_ARGUMENT",`${t} is required`);return r}function lM(e){return e==="enqueue"||e==="command"||e==="script"||e==="session"||e==="miniplayer"}var uM=["pending","running","succeeded","failed","escalated"];function dM(e){return uM.includes(e)}function tb(e){let t=e.payload,r=e.prompt,n=e["prompt-file"];if([t,r,n].filter(s=>s!==void 0).length>1)throw new U("INVALID_ARGUMENT","provide only one of --payload, --prompt, or --prompt-file");if(n!==void 0){if(typeof n!="string")throw new U("INVALID_ARGUMENT","--prompt-file requires a path");try{return cM(n,"utf8")}catch(s){throw new U("INVALID_ARGUMENT",`cannot read --prompt-file ${n}: ${s instanceof Error?s.message:String(s)}`)}}if(typeof t=="string")return t;if(typeof r=="string")return r}function Ve(e){return typeof e=="string"?e:void 0}function ft(e,t,r={}){return e?JSON.stringify({schema_version:1,ok:!0,data:t,meta:r}):mM(t,r)}function rb(e,t){return e?{output:JSON.stringify({schema_version:1,ok:!1,error:{code:t.code,message:t.message}}),exitCode:t.exitCode}:{output:`${t.code}: ${t.message}`,exitCode:t.exitCode}}function mM(e,t){let r;if(Array.isArray(e)){let o=s=>s!==null&&typeof s=="object"&&"title"in s;r=e.length===0?"(empty)":e.every(o)?(0,xa.formatTable)([["ID","ENABLED","KIND","SCHEDULE","TITLE"],...e.map(s=>["id","enabled","action_kind","schedule_expr","title"].map(i=>(0,xa.escapeCell)(String(s[i]??""))))]):e.map(s=>JSON.stringify(s)).join(`
608
+ `)}),i=t.nowMs??Date.now(),a=t.config??pe;return{teams:n.map(c=>({team:c.name,stalled:Qc(e.db.db,c,o,s,a,i)}))}}var xa=Ht(Lt(),1);import{readFileSync as cM}from"node:fs";function pn(e,t,r={}){if(e===void 0)return;if(typeof e!="string"||!/^\d+$/.test(e))throw new P("INVALID_ARGUMENT",`${t} must be a nonnegative integer`);let n=Number(e),o=r.minimum??1;if(!Number.isSafeInteger(n)||n<o||r.maximum!==void 0&&n>r.maximum){let s=r.maximum!==void 0?`between ${o} and ${r.maximum}`:`>= ${o}`;throw new P("INVALID_ARGUMENT",`${t} must be an integer ${s}`)}return n}function hr(e,t){let r=pn(e,t,{minimum:1});if(r===void 0)throw new P("INVALID_ARGUMENT",`${t} is required`);return r}function lM(e){return e==="enqueue"||e==="command"||e==="script"||e==="session"||e==="miniplayer"}var uM=["pending","running","succeeded","failed","escalated"];function dM(e){return uM.includes(e)}function tb(e){let t=e.payload,r=e.prompt,n=e["prompt-file"];if([t,r,n].filter(s=>s!==void 0).length>1)throw new P("INVALID_ARGUMENT","provide only one of --payload, --prompt, or --prompt-file");if(n!==void 0){if(typeof n!="string")throw new P("INVALID_ARGUMENT","--prompt-file requires a path");try{return cM(n,"utf8")}catch(s){throw new P("INVALID_ARGUMENT",`cannot read --prompt-file ${n}: ${s instanceof Error?s.message:String(s)}`)}}if(typeof t=="string")return t;if(typeof r=="string")return r}function Ve(e){return typeof e=="string"?e:void 0}function ft(e,t,r={}){return e?JSON.stringify({schema_version:1,ok:!0,data:t,meta:r}):mM(t,r)}function rb(e,t){return e?{output:JSON.stringify({schema_version:1,ok:!1,error:{code:t.code,message:t.message}}),exitCode:t.exitCode}:{output:`${t.code}: ${t.message}`,exitCode:t.exitCode}}function mM(e,t){let r;if(Array.isArray(e)){let o=s=>s!==null&&typeof s=="object"&&"title"in s;r=e.length===0?"(empty)":e.every(o)?(0,xa.formatTable)([["ID","ENABLED","KIND","SCHEDULE","TITLE"],...e.map(s=>["id","enabled","action_kind","schedule_expr","title"].map(i=>(0,xa.escapeCell)(String(s[i]??""))))]):e.map(s=>JSON.stringify(s)).join(`
609
609
  `)}else typeof e=="string"?r=e:r=JSON.stringify(e,null,2);let n=t.next_cursor;return n!=null?`${r}
610
610
  More records: --after ${String(n)}`:r}var nb=`usage: lmbee cron create --title TEXT --schedule "m h dom mon dow" --kind enqueue|command|script|session|miniplayer [--payload TEXT | --prompt TEXT | --prompt-file PATH] [--provider P] [--model M] [--cwd DIR] [--owner NAME] [--disabled] [--timezone IANA-name] | show ID | list [--enabled true|false] [--limit N] [--after ID] | update ID [--title T] [--schedule EXPR] [--payload TEXT|--prompt TEXT|--prompt-file PATH] [--provider P] [--model M] [--cwd DIR] [--owner NAME] [--timezone IANA-name|""] [--if-revision N] | enable ID | disable ID | remove ID | reset ID | reset-session ID | export PATH | import PATH | runs [--job ID] [--status pending|running|succeeded|failed|escalated] [--limit N] [--after ID] | run RUN-ID | trigger ID | report RUN-TOKEN --status succeeded|failed|escalated --summary TEXT [--artifact A[,B]] [--requested-action TEXT] [--owner NAME] | resolve RUN-ID [--resolution TEXT] [--actor NAME] [--note TEXT] [--confirm-stopped]
611
611
  NOTE: a job fires at most once per daemon tick interval (default 30 minutes), regardless of how frequent its own schedule expression is -- lmcron catches up a missed window, coalesced to one fire, never one fire per missed minute.
612
- NOTE: export/import carry job DEFINITIONS only (ids preserved), NEVER execution state -- runtime/session columns reset on import, historical timestamps are deliberately omitted, and the overlap fences live in cron_runs, which is not migrated. At scheduler cutover, stop the old daemon BEFORE the new one ticks; never run both schedules concurrently.`;async function ob(e,t,r,n,o=[]){try{let[s,...i]=t;switch(s){case"create":{let a=r.title;if(typeof a!="string")throw new U("INVALID_ARGUMENT","--title is required");let c=r.schedule;if(typeof c!="string")throw new U("INVALID_ARGUMENT","--schedule is required");let l=r.kind;if(typeof l!="string"||!lM(l))throw new U("INVALID_ARGUMENT",'--kind must be "enqueue", "command", "script", "session", or "miniplayer"');let u=tb(r);if(u===void 0)throw new U("INVALID_ARGUMENT",l==="session"||l==="miniplayer"?"--prompt or --prompt-file is required":"--payload is required");let d=Vn(e,{title:a,scheduleExpr:c,actionKind:l,actionPayload:u,enabled:r.disabled!==!0,timezone:typeof r.timezone=="string"?r.timezone:void 0,...Ve(r.provider)!==void 0?{provider:Ve(r.provider)}:{},...Ve(r.model)!==void 0?{model:Ve(r.model)}:{},...Ve(r.cwd)!==void 0?{workingDirectory:Ve(r.cwd)}:{},...Ve(r.owner)!==void 0?{escalationOwner:Ve(r.owner)}:{}});return{output:ft(n,d),exitCode:0}}case"show":{let a=hr(i[0],"id");return{output:ft(n,Le(e,a)),exitCode:0}}case"list":{let a=r.enabled,c;if(a!==void 0){if(a!=="true"&&a!=="false")throw new U("INVALID_ARGUMENT",'--enabled must be "true" or "false"');c=a==="true"}let{rows:l,meta:u}=Ji(e,{enabled:c,limit:pn(r.limit,"--limit",{maximum:Ie})??100,after:pn(r.after,"--after",{minimum:0})??0});return{output:ft(n,l,u),exitCode:0}}case"update":{let a=hr(i[0],"id"),c=tb(r),l=Yh(e,a,{title:typeof r.title=="string"?r.title:void 0,scheduleExpr:typeof r.schedule=="string"?r.schedule:void 0,actionPayload:c,timezone:typeof r.timezone=="string"?r.timezone===""?null:r.timezone:void 0,provider:Ve(r.provider),model:Ve(r.model),workingDirectory:typeof r.cwd=="string"?r.cwd===""?null:r.cwd:void 0,escalationOwner:typeof r.owner=="string"?r.owner===""?null:r.owner:void 0,ifRevision:pn(r["if-revision"],"--if-revision")});return{output:ft(n,l),exitCode:0}}case"enable":case"disable":{let a=hr(i[0],"id"),c=zi(e,a,s==="enable");return{output:ft(n,c),exitCode:0}}case"remove":{let a=hr(i[0],"id"),c=Kh(e,a);return{output:ft(n,c),exitCode:0}}case"reset":{let a=hr(i[0],"id"),c=ng(e,a);return{output:ft(n,c),exitCode:0}}case"reset-session":{let a=hr(i[0],"id"),c=Qh(e,a);return{output:ft(n,c),exitCode:0}}case"runs":{let a=r.status;if(a!==void 0&&(typeof a!="string"||!dM(a)))throw new U("INVALID_ARGUMENT","--status must be one of pending|running|succeeded|failed|escalated");let c=r.job!==void 0?pn(r.job,"--job"):void 0,{rows:l,next_cursor:u}=Hi(e,{...c!==void 0?{jobId:c}:{},...a!==void 0?{status:a}:{},limit:pn(r.limit,"--limit",{maximum:Ie})??100,after:pn(r.after,"--after",{minimum:0})??0});return{output:ft(n,l.map(Yo),{next_cursor:u}),exitCode:0}}case"run":{let a=hr(i[0],"id");return{output:ft(n,Yo(Qe(e,a))),exitCode:0}}case"trigger":{let a=hr(i[0],"id"),c=await rs(e,a,o);return{output:ft(n,{trigger:c.kind,job:c.job}),exitCode:0}}case"report":{let a=i[0];if(a===void 0)throw new U("INVALID_ARGUMENT","a run token is required");let c=r.status;if(typeof c!="string"||c!=="succeeded"&&c!=="failed"&&c!=="escalated")throw new U("INVALID_ARGUMENT",'--status must be "succeeded", "failed", or "escalated"');let l=r.summary;if(typeof l!="string")throw new U("INVALID_ARGUMENT","--summary is required");let u=typeof r.artifact=="string"?r.artifact:void 0,d=u!==void 0?u.split(",").map(p=>p.trim()).filter(p=>p.length>0):void 0,m=typeof r["requested-action"]=="string"?r["requested-action"]:Ve(r.action),f=Ch(e,a,{status:c,summary:l,...d!==void 0?{artifacts:d}:{},...m!==void 0?{action:m}:{},...Ve(r.owner)!==void 0?{owner:Ve(r.owner)}:{},...Ve(r.reason)!==void 0?{reason:Ve(r.reason)}:{}});return{output:ft(n,Yo(f)),exitCode:0}}case"import":{_s("import",i,r);let a=i[0];if(a===void 0)throw new U("INVALID_ARGUMENT","an import PATH is required");let c=XE(e,a);return{output:n?ft(!0,c):ZE(c),exitCode:0}}case"resolve":{let a=hr(i[0],"id"),c=Dh(e,a,{resolution:Ve(r.resolution),actor:Ve(r.actor),note:Ve(r.note),confirmStopped:r["confirm-stopped"]===!0});return{output:ft(n,Yo(c)),exitCode:0}}default:return n?rb(n,new U("INVALID_ARGUMENT",nb)):{output:nb,exitCode:1}}}catch(s){if(s instanceof U)return rb(n,s);throw s}}var sb=["disabled","confirm-stopped"];async function ib(e){let t=e.send??Vt,r=e.config??pe,n=e.nowMs??Date.now(),o=e.maxParallel??4,s=e.readHeavyLockStatusImpl??dt,i=e.teams.filter(l=>!ie(e.db,l.name)?.confirmed_done_ts),a=await fM(i,o,async l=>{if(!await Kc(e.db,l,e.report,e.heavyLock,r,n))return{team:l.name,dispatched:!1,status:null,wake:null};let d;try{d=Q(l)}catch(h){let g=h instanceof Error?h.message:String(h);return ur(e.db,l.name,"ENV-ERROR",n),Mo(e.db,l.name,new Date(n).toISOString()),nt(e.db,l.name,"ENV-ERROR",n,{note:g}),{team:l.name,dispatched:!0,status:"ENV-ERROR",wake:"env"}}let m=s(e.heavyLockStatusPath,e.heavyLockPath,void 0,h=>{process.stderr.write(`[scan] heavy-lock probe failed for ${l.name}, treating conservatively as held: ${h.message}
612
+ NOTE: export/import carry job DEFINITIONS only (ids preserved), NEVER execution state -- runtime/session columns reset on import, historical timestamps are deliberately omitted, and the overlap fences live in cron_runs, which is not migrated. At scheduler cutover, stop the old daemon BEFORE the new one ticks; never run both schedules concurrently.`;async function ob(e,t,r,n,o=[]){try{let[s,...i]=t;switch(s){case"create":{let a=r.title;if(typeof a!="string")throw new P("INVALID_ARGUMENT","--title is required");let c=r.schedule;if(typeof c!="string")throw new P("INVALID_ARGUMENT","--schedule is required");let l=r.kind;if(typeof l!="string"||!lM(l))throw new P("INVALID_ARGUMENT",'--kind must be "enqueue", "command", "script", "session", or "miniplayer"');let u=tb(r);if(u===void 0)throw new P("INVALID_ARGUMENT",l==="session"||l==="miniplayer"?"--prompt or --prompt-file is required":"--payload is required");let d=Vn(e,{title:a,scheduleExpr:c,actionKind:l,actionPayload:u,enabled:r.disabled!==!0,timezone:typeof r.timezone=="string"?r.timezone:void 0,...Ve(r.provider)!==void 0?{provider:Ve(r.provider)}:{},...Ve(r.model)!==void 0?{model:Ve(r.model)}:{},...Ve(r.cwd)!==void 0?{workingDirectory:Ve(r.cwd)}:{},...Ve(r.owner)!==void 0?{escalationOwner:Ve(r.owner)}:{}});return{output:ft(n,d),exitCode:0}}case"show":{let a=hr(i[0],"id");return{output:ft(n,Le(e,a)),exitCode:0}}case"list":{let a=r.enabled,c;if(a!==void 0){if(a!=="true"&&a!=="false")throw new P("INVALID_ARGUMENT",'--enabled must be "true" or "false"');c=a==="true"}let{rows:l,meta:u}=Ji(e,{enabled:c,limit:pn(r.limit,"--limit",{maximum:Ie})??100,after:pn(r.after,"--after",{minimum:0})??0});return{output:ft(n,l,u),exitCode:0}}case"update":{let a=hr(i[0],"id"),c=tb(r),l=Yh(e,a,{title:typeof r.title=="string"?r.title:void 0,scheduleExpr:typeof r.schedule=="string"?r.schedule:void 0,actionPayload:c,timezone:typeof r.timezone=="string"?r.timezone===""?null:r.timezone:void 0,provider:Ve(r.provider),model:Ve(r.model),workingDirectory:typeof r.cwd=="string"?r.cwd===""?null:r.cwd:void 0,escalationOwner:typeof r.owner=="string"?r.owner===""?null:r.owner:void 0,ifRevision:pn(r["if-revision"],"--if-revision")});return{output:ft(n,l),exitCode:0}}case"enable":case"disable":{let a=hr(i[0],"id"),c=zi(e,a,s==="enable");return{output:ft(n,c),exitCode:0}}case"remove":{let a=hr(i[0],"id"),c=Kh(e,a);return{output:ft(n,c),exitCode:0}}case"reset":{let a=hr(i[0],"id"),c=ng(e,a);return{output:ft(n,c),exitCode:0}}case"reset-session":{let a=hr(i[0],"id"),c=Qh(e,a);return{output:ft(n,c),exitCode:0}}case"runs":{let a=r.status;if(a!==void 0&&(typeof a!="string"||!dM(a)))throw new P("INVALID_ARGUMENT","--status must be one of pending|running|succeeded|failed|escalated");let c=r.job!==void 0?pn(r.job,"--job"):void 0,{rows:l,next_cursor:u}=Hi(e,{...c!==void 0?{jobId:c}:{},...a!==void 0?{status:a}:{},limit:pn(r.limit,"--limit",{maximum:Ie})??100,after:pn(r.after,"--after",{minimum:0})??0});return{output:ft(n,l.map(Yo),{next_cursor:u}),exitCode:0}}case"run":{let a=hr(i[0],"id");return{output:ft(n,Yo(Qe(e,a))),exitCode:0}}case"trigger":{let a=hr(i[0],"id"),c=await rs(e,a,o);return{output:ft(n,{trigger:c.kind,job:c.job}),exitCode:0}}case"report":{let a=i[0];if(a===void 0)throw new P("INVALID_ARGUMENT","a run token is required");let c=r.status;if(typeof c!="string"||c!=="succeeded"&&c!=="failed"&&c!=="escalated")throw new P("INVALID_ARGUMENT",'--status must be "succeeded", "failed", or "escalated"');let l=r.summary;if(typeof l!="string")throw new P("INVALID_ARGUMENT","--summary is required");let u=typeof r.artifact=="string"?r.artifact:void 0,d=u!==void 0?u.split(",").map(p=>p.trim()).filter(p=>p.length>0):void 0,m=typeof r["requested-action"]=="string"?r["requested-action"]:Ve(r.action),f=Ch(e,a,{status:c,summary:l,...d!==void 0?{artifacts:d}:{},...m!==void 0?{action:m}:{},...Ve(r.owner)!==void 0?{owner:Ve(r.owner)}:{},...Ve(r.reason)!==void 0?{reason:Ve(r.reason)}:{}});return{output:ft(n,Yo(f)),exitCode:0}}case"import":{_s("import",i,r);let a=i[0];if(a===void 0)throw new P("INVALID_ARGUMENT","an import PATH is required");let c=XE(e,a);return{output:n?ft(!0,c):ZE(c),exitCode:0}}case"resolve":{let a=hr(i[0],"id"),c=Dh(e,a,{resolution:Ve(r.resolution),actor:Ve(r.actor),note:Ve(r.note),confirmStopped:r["confirm-stopped"]===!0});return{output:ft(n,Yo(c)),exitCode:0}}default:return n?rb(n,new P("INVALID_ARGUMENT",nb)):{output:nb,exitCode:1}}}catch(s){if(s instanceof P)return rb(n,s);throw s}}var sb=["disabled","confirm-stopped"];async function ib(e){let t=e.send??Vt,r=e.config??pe,n=e.nowMs??Date.now(),o=e.maxParallel??4,s=e.readHeavyLockStatusImpl??dt,i=e.teams.filter(l=>!ie(e.db,l.name)?.confirmed_done_ts),a=await fM(i,o,async l=>{if(!await Kc(e.db,l,e.report,e.heavyLock,r,n))return{team:l.name,dispatched:!1,status:null,wake:null};let d;try{d=Q(l)}catch(h){let g=h instanceof Error?h.message:String(h);return ur(e.db,l.name,"ENV-ERROR",n),Mo(e.db,l.name,new Date(n).toISOString()),nt(e.db,l.name,"ENV-ERROR",n,{note:g}),{team:l.name,dispatched:!0,status:"ENV-ERROR",wake:"env"}}let m=s(e.heavyLockStatusPath,e.heavyLockPath,void 0,h=>{process.stderr.write(`[scan] heavy-lock probe failed for ${l.name}, treating conservatively as held: ${h.message}
613
613
  `)});if(m.held&&(m.holder===null||m.holder.holder===l.name))return{team:l.name,dispatched:!1,status:null,wake:null};if(Zs(e.db,l.name,l.leadAlias,n))return{team:l.name,dispatched:!1,status:null,wake:null};let f=await t({teamfilePath:d,alias:l.leadAlias},e.resolveNudgeMessage(l)),p=Zn(f);return ur(e.db,l.name,p.status,n),Mo(e.db,l.name,new Date(n).toISOString()),nt(e.db,l.name,p.status,n),{team:l.name,dispatched:!0,status:p.status,wake:p.wake}}),c=a.find(l=>l.wake!==null)?.wake??null;return{results:a,wake:c}}async function fM(e,t,r){let n=new Array(e.length),o=0;async function s(){for(;;){let a=o++;if(a>=e.length)return;n[a]=await r(e[a])}}let i=Math.max(1,Math.min(t,e.length));return await Promise.all(Array.from({length:i},()=>s())),n}async function ws(e,t,r={}){let o=await(r.fetchReport??ke)(),s=r.readHeavyLockStatusImpl??dt,i=s(void 0,void 0,void 0,l=>{process.stderr.write(`[scan] heavy-lock probe failed, treating conservatively as held: ${l.message}
614
614
  `)}),a=na(r.promptsDir);return(r.scanOnceImpl??ib)({db:e,teams:t.filter(B),report:o,heavyLock:i,readHeavyLockStatusImpl:s,resolveNudgeMessage:l=>oa(a,l)})}function ys(e){let t=e.results.map(r=>`${r.team}: ${r.dispatched?r.status:"skipped (not stalled)"}`);return t.length?t.join(`
615
615
  `):"(no eligible teams)"}async function ab(e,t,r={}){if(t.length===0)throw new Error("usage: lmbee nudge <team> [team2 ...]");let n=e.teams.filter(s=>t.includes(s.name));if(n.length===0)throw new Error(`nudge: no matching teams for: ${t.join(", ")}`);let o=await ws(e.db.db,n,r);return ys(o)}function cb(e,t,r){let n=$t(e.db.db,t),o={companionTeam:r.companionTeam,workerAlias:r.workerAlias??"Worker",commitThreshold:r.commitThreshold??bl,hoursThresholdMs:r.hoursThresholdMs??Tl,shiftStartedTs:n?.companionTeam===r.companionTeam?n?.shiftStartedTs??null:null,shiftStartedSha:n?.companionTeam===r.companionTeam?n?.shiftStartedSha??null:null,turnsDispatched:n?.companionTeam===r.companionTeam?n?.turnsDispatched??0:0,lastReviewedTurn:n?.companionTeam===r.companionTeam?n?.lastReviewedTurn??0:0};return Li(e.db.db,t,o),r.json?JSON.stringify({team:t,...o}):`auto-nudge for ${t} now redirects to ${o.companionTeam}:${o.workerAlias} (review due after ${o.commitThreshold} commits or ${(o.hoursThresholdMs/36e5).toFixed(1)}h, whichever first).
@@ -907,8 +907,8 @@ ${yd()}`)}function IF(e){try{return{source:ve({env:e}).source}}catch(t){return t
907
907
  `),await wq(n,t),o=!0}finally{if(!o)try{await yq(n)}catch(s){if(s.code!=="ENOENT")throw s}}}function Sq(e,t,r){if(r!==void 0){for(let[n,o]of Object.entries(e))if(n!==t&&o.alias===r)throw new Error(`peer alias already registered: ${r}`)}}function Sv(e,t){for(let[r,n]of Object.entries(t))if(n.alias===e)return{siteUuid:sr(r,"wire site-uuid"),mailbox:Is(r,n.mailbox)}}function _v(e,t){if(typeof e!="string")throw new Error(t);return e}async function vv(){let e=await Ls(),t=["site-uuid alias mailbox"];for(let r of Object.keys(e).sort()){let n=e[r];t.push(`${r} ${n.alias??""} ${n.mailbox}`)}return t.join(`
908
908
  `)}async function Av(e,t,r){let n=sr(e,"site-uuid"),o=Is(n,t),s=await Ls(),i=s[n],a=r===void 0?i?.alias:bv(r);return Sq(s,n,a),s[n]=a===void 0?{mailbox:o}:{mailbox:o,alias:a},await Tv(s),`peer ${n}${a?` (${a})`:""} -> ${o}`}async function $v(e){let t=sr(e,"site-uuid"),r=await Ls();if(!Object.hasOwn(r,t))throw new Error(`unknown peer site-uuid: ${t}`);return delete r[t],await Tv(r),`removed peer ${t}`}function yo(e){let t=e.env??process.env,r=e.resolveAppkeyImpl??ve,n=e.createMailClientImpl??_t,{appkey:o}=r({env:t});return n({apiUrl:Nt(t),appkey:o})}function xd(e){try{return hc(e)}catch(t){throw new Ue(t instanceof Error?t.message:String(t))}}function vq(e){if(e.includes("..")||e.endsWith(".")||!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(e))throw new Ue("--mailbox must be a valid mailbox name");return e}async function kv(e,t={}){let r=xd(e),n=t.siteUuid===void 0?await ei(dr()):sr(t.siteUuid,"--site-uuid"),o=t.mailbox??Tn(n),s=yo(t),i;try{i=await s.registerSite(r,n,o)}catch(a){throw a instanceof Bt&&a.code==="site_name_taken"?new Error(`site name already registered to a different site in this account: ${r}`):a}return`registered ${i.site_name} -> ${i.site_uuid} (${i.mailbox})`}async function xv(e,t={}){let r=xd(e),n=yo(t),o;try{o=await n.resolveSite(r)}catch(s){if(!(s instanceof Bt&&s.status===404))throw s}return o?{output:`${o.site_name} ${o.site_uuid} ${o.mailbox}`,exitCode:0}:{output:`unknown site name in this account: ${r}`,exitCode:1}}async function Ha(e){let t=new Map,r=new Map,n=new Set,o;do{let s=await e.listSites({limit:50,...o?{cursor:o}:{}});for(let i of s.sites)t.set(i.site_uuid.toLowerCase(),i);for(let i of s.discovered){let a=Rv(i),c=r.get(a);(!c||i.last_seen_at>c.last_seen_at)&&r.set(a,i)}if(o=s.next_cursor,o){if(n.has(o))throw new Error("site listing returned a repeated cursor");n.add(o)}}while(o);return{sites:[...t.values()],discovered:[...r.values()]}}function Rv(e){return e.site_uuid?`uuid#${e.site_uuid.toLowerCase()}`:`mailbox#${e.mailbox}#${e.owner_user_id}`}function Aq(e){let t=[`uuid#${e.site_uuid.toLowerCase()}`],r=e.content_mailbox??e.mailbox,n=e.content_mailbox_owner_user_id??e.mailbox_owner_user_id;return n&&t.push(`mailbox#${r}#${n}`),e.exec_mailbox&&e.exec_mailbox_owner_user_id&&t.push(`mailbox#${e.exec_mailbox}#${e.exec_mailbox_owner_user_id}`),t}function $q(e,t){let r=new Set(e.flatMap(Aq));return t.filter(n=>!r.has(Rv(n))&&!r.has(`mailbox#${n.mailbox}#${n.owner_user_id}`))}function kd(e){return e.display_name??e.registered_name??e.site_name}function kq(e,t){let r=["REGISTERED","display-name registered-name site-uuid content-mailbox exec-mailbox"];for(let n of e.sort((o,s)=>kd(o).localeCompare(kd(s))))r.push([kd(n),n.registered_name??n.site_name,n.site_uuid,n.content_mailbox??n.mailbox,n.exec_mailbox??"-"].join(" "));r.push("","DISCOVERED","display-name site-uuid mailbox owner-user-id last-seen-at");for(let n of t.sort((o,s)=>s.last_seen_at-o.last_seen_at))r.push([n.name??"-",n.site_uuid??"-",n.mailbox,n.owner_user_id,n.last_seen_at].join(" "));return r.join(`
909
909
  `)}async function Nv(e={}){let t=yo(e),r=await Ha(t);return kq(r.sites,$q(r.sites,r.discovered))}async function xq(e,t){let r=await Ha(e),n=[...new Set(r.discovered.filter(o=>o.mailbox===t).map(o=>o.owner_user_id))];if(n.length===0)throw new Error(`mailbox is not present in site discovery: ${t}`);if(n.length>1)throw new Error(`mailbox ownership changed during site discovery; retry: ${t}`);return{kind:"mailbox",value:t,owner_user_id:n[0]}}async function Iv(e,t,r){return t!==void 0?{kind:"uuid",value:sr(t,"--uuid")}:await xq(e,vq(r))}async function Lv(e,t){let r=e.trim();if(!r)throw new Ue("site display name must be non-empty");let n=yo(t),o=await Iv(n,t.uuid,t.mailbox),s=await n.setSiteName(o,r);return`named ${s.site_key} -> ${s.name}`}async function Cv(e){let t=yo(e),r=await Iv(t,e.uuid,e.mailbox);return`cleared ${(await t.deleteSiteName(r)).site_key}`}async function Ov(e,t={}){let r=xd(e);return await yo(t).deleteSite(r),`removed ${r}`}function Gr(){return"usage: lmbee sites register <name> [--site-uuid <uuid>] [--mailbox <name>] | resolve <name> | list | set-name (--uuid <uuid> | --mailbox <name>) <name> | clear-name (--uuid <uuid> | --mailbox <name>) | remove <name>"}var Nq=15,Iq=60,Lq="lmbee status --live --json";async function Dv(e={}){let t=e.env??process.env,r=e.resolveAppkeyImpl??ve,n=e.createMailClientImpl??_t,o=e.now??Date.now,s=e.sleep??(m=>new Promise(f=>setTimeout(f,m))),i=e.username??(()=>process.env.USER??process.env.USERNAME??"user"),a=e.waitSeconds??Nq;if(!Number.isFinite(a)||a<=0)throw new Error("--wait-s must be positive");let{appkey:c}=r({env:t}),l=n({apiUrl:Nt(t),appkey:c}),u=(await Ha(l)).sites.sort((m,f)=>m.site_name.localeCompare(f.site_name)),d=pv(i());await Td(l,d,s);try{let m=u.map(S=>({site:S,execMailbox:$n(S.site_uuid),id:Rq(),sentAt:o()}));await Promise.all(m.map(async S=>{try{await Sd(l,{id:S.id,daemonMailbox:S.execMailbox,command:Lq,replyMailbox:d,timeoutSeconds:Iq})}catch(T){S.sendError=T instanceof Error?T.message:String(T)}}));let f=o()+Math.round(a*1e3),p=new Set(m.filter(S=>S.sendError===void 0).map(S=>S.id)),h=await vd(l,d,p,f,{now:o,sleep:s}),g=m.filter(S=>S.sendError===void 0).length,_=h.size,E=u.length===0?"empty":_===u.length?"all":_===0?"none":"partial";return{verdict:E,exit_code:E==="none"?2:E==="partial"?3:0,sent:g,answered:_,sites:m.map(S=>Cq(S,h.get(S.id))),generated_at:new Date(o()).toISOString()}}finally{await l.deleteMailbox(d)}}function Cq(e,t){let r={site_name:e.site.site_name,site_uuid:e.site.site_uuid,mailbox:e.execMailbox};if(!t)return{...r,liveness:"stale",error:e.sendError??"no_reply"};let n={...r,liveness:"live",latency_ms:Math.max(0,t.receivedAt-e.sentAt)},o=Oq(t);if(o)return{...n,error:o};if(t.result.exit_code!==0)return{...n,error:t.result.timed_out?"remote_timeout":`remote_exit_${t.result.exit_code}`};try{let s=JSON.parse(t.stdout);if(!s||typeof s!="object"||Array.isArray(s))throw new Error("expected JSON object");return{...n,status:s}}catch{return{...n,error:"invalid_status_json"}}}function Oq(e){if(e.result.exit_code===126)try{let t=JSON.parse(e.stderr);return typeof t.error?.code=="string"?t.error.code:"remote_rejected"}catch{return"remote_rejected"}}function Mv(e){let t=["SITE LIVENESS LATENCY_MS TEAMS DAEMON ERROR"];for(let r of e.sites)t.push([r.site_name||r.site_uuid,r.liveness,r.latency_ms??"-",Dq(r.status)??"-",Mq(r.status)??"-",r.error??"-"].join(" "));return t.push(`Fleet: ${e.verdict} (sent ${e.sent}/${e.sites.length}, answered ${e.answered}/${e.sites.length}; exit ${e.exit_code})`),t.join(`
910
- `)}function Dq(e){return Array.isArray(e?.teams)?e.teams.length:void 0}function Mq(e){return typeof e?.live=="boolean"?`live:${e.live}`:void 0}function Pv(){return"usage: lmbee exec <site-uuid-or-mailbox> [--wait-s N] <command...> | lmbee exec <site-uuid-or-mailbox> [--wait-s N] -- <literal command...>"}function Rd(){return"usage: lmbee fleet status [--json] [--wait-s N]"}function Uv(e,t){return wo(e,t,r=>new Mt(r))}function Pq(e){let t=e.indexOf("--"),r=t<0?[...e]:[...e.slice(0,t)],n=t<0?void 0:e.slice(t+1),o=Uv(r,"--wait-s"),s=o===void 0?void 0:Number(o);if(s!==void 0&&(!Number.isFinite(s)||s<=0))throw new Mt("--wait-s must be positive");let i=r.shift();if(!i)throw new Mt(Pv());let a=n??r;if(n&&r.length>0)throw new Mt(`unexpected argument before --: ${r[0]}`);if(a.length===0)throw new Mt(Pv());return{target:i,command:a.join(" "),...s===void 0?{}:{waitSeconds:s}}}async function Fv(e){try{let{target:t,command:r,waitSeconds:n}=Pq(e),o=await hv(t,r,{waitSeconds:n});return{output:`${o.stdout}${o.stderr}`.replace(/\n$/,""),exitCode:o.exitCode}}catch(t){return{output:t instanceof Error?t.message:String(t),exitCode:t instanceof Mt?1:2}}}async function qv(e){let[t,...r]=e;if(t!=="status")return{output:Rd(),exitCode:1};let n=r.includes("--json");try{let o=[...r],s=o.indexOf("--json");n&&o.splice(s,1);let i=Uv(o,"--wait-s"),a=i===void 0?void 0:Number(i);if(a!==void 0&&(!Number.isFinite(a)||a<=0))return{output:Rd(),exitCode:1};if(o.length>0)return{output:Rd(),exitCode:1};let c=await Dv({waitSeconds:a});return{output:n?JSON.stringify(c,null,2):Mv(c),exitCode:c.exit_code}}catch(o){let s=o instanceof Error?o.message:String(o),i=o instanceof Mt?1:2;return{output:n?JSON.stringify({verdict:"error",exit_code:i,error:s},null,2):s,exitCode:i}}}import{cpSync as Ba,existsSync as Vr,mkdirSync as Uq,readFileSync as Nd,readdirSync as Fq,rmSync as jv,statSync as Hv}from"node:fs";import{homedir as Gv}from"node:os";import{join as et,sep as Id}from"node:path";var Eo=class extends Error{constructor(t){super(`migrate-home: refusing to run -- an lmauto daemon appears to be live (${t}). Stop it first (systemctl --user stop lmauto.service if it runs as a service, or kill the pid) before re-running.`),this.name="DaemonLiveError"}},Ld=class extends Error{targetDbPath;sizeBytes;constructor(t,r){super(`migrate-home: refusing to replace an existing target database: ${t} already exists (${r} bytes). migrate-home never deletes a database it did not create this run. If this file is debris from an interrupted migrate-home run, or you are certain it is disposable, re-run with --replace-existing-target-db; otherwise move it aside yourself (e.g. \`mv ${t} ${t}.bak\`) and re-run.`),this.targetDbPath=t,this.sizeBytes=r,this.name="TargetDbExistsError"}};function Vv(){return et(Gv(),".lmauto")}function Jv(){return et(process.env.LMCTL_HOME??et(Gv(),".lmctl"),"lmauto")}function qq(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}async function jq(e){try{return(await fetch(`http://127.0.0.1:${e}/api/teams`,{signal:AbortSignal.timeout(1e3)})).body?.cancel(),!0}catch{return!1}}function Hq(e,t){let r=et(e,"serve.pid");if(!Vr(r))return null;let n=Nd(r,"utf8").trim(),o=Number(n);return!Number.isInteger(o)||o<=0?null:t(o)?o:null}var Bv=["team_state","kv","events","queue","sources","team_progress","mail_ledger","mail_outbound_ledger"];function Wv(e,t){return e.prepare(`SELECT COUNT(*) as n FROM ${t}`).get().n}function Cd(e){if(!Vr(e))return 0;let t=0;for(let r of Fq(e,{withFileTypes:!0}))r.isDirectory()?t+=Cd(et(e,r.name)):t+=1;return t}function Bq(e,t,r){let n=t.endsWith(Id)?t:t+Id,o=e.prepare("SELECT id, prompt_file FROM queue").all(),s=new Map(o.map(l=>[l.id,l.prompt_file])),i=o.filter(l=>l.prompt_file.startsWith(n)),a=e.prepare("UPDATE queue SET prompt_file = ? WHERE id = ?");return e.transaction(l=>{for(let u of l){let d=r+u.prompt_file.slice(t.length);a.run(d,u.id)}})(i),{rewrittenCount:i.length,originalPathById:s}}async function zv(e){let{sourceDir:t,targetDir:r,port:n=4173}=e,o=e.isDaemonAlive??qq,s=e.probeHttpAlive??jq,i=e.checkSiteLock??M_,a=et(t,"state.db"),c=et(r,"state.db"),l=i(a);if(l!==null)throw new Eo(`${l.ownerLabel} pid ${l.pid} (site lock for ${a})`);let u=Hq(t,o);if(u!==null)throw new Eo(`pid ${u}, ${et(t,"serve.pid")}`);if(await s(n))throw new Eo(`something is listening on port ${n}`);if(t===r||r.startsWith(t+Id))throw new Error(`migrate-home: target (${r}) must not be, or be nested inside, source (${t})`);let d=e.acquireSiteLock??_a,m=us(a),f=[];try{f.push(d(m,"migrate-home")),f.push(d(et(t,"site.lock"),"migrate-home"))}catch(p){for(let h of f.splice(0))h.release();throw p instanceof Qn?new Eo(`${p.holder.ownerLabel} pid ${p.holder.pid}, ${p.lockPath}`):p}try{Uq(r,{recursive:!0});let p=!1,h=!1;if(Vr(a)){let oe=Vr(c);if(oe&&e.replaceExistingTargetDb!==!0)throw new Ld(c,Hv(c).size);let V=new wt(a);try{if(V.prepare("SELECT COUNT(*) AS n FROM sqlite_master").get(),oe){process.stderr.write(`migrate-home: replacing existing target database ${c} (${Hv(c).size} bytes) with a snapshot of ${a} (explicit replaceExistingTargetDb consent)
911
- `);for(let se of["","-wal","-shm"])jv(c+se,{force:!0});h=!0}else for(let se of["-wal","-shm"])jv(c+se,{force:!0});V.prepare("VACUUM INTO ?").run(c)}finally{V.close()}p=!0}let g=et(t,"queue"),_=et(r,"queue"),E=Cd(g);E>0&&Ba(g,_,{recursive:!0});let y=et(t,"prompts"),S=et(r,"prompts"),T=Cd(y);T>0&&Ba(y,S,{recursive:!0});let R=et(t,"site-uuid"),A=et(r,"site-uuid"),I=!1,x=!1;Vr(R)&&(Ba(R,A),I=!0,x=Nd(R,"utf8")!==Nd(A,"utf8"));let H=et(t,"lmt-peers.json"),C=et(r,"lmt-peers.json"),w=!1;Vr(H)&&(Ba(H,C),w=!0);let b=0,N=0,P=[],J=[],ee={};if(p){let oe=new wt(a,{readonly:!0});try{for(let se of Bv)ee[se]={source:Wv(oe,se),target:0}}finally{oe.close()}let V=new wt(c);try{for(let $ of Bv)ee[$].target=Wv(V,$);let{rewrittenCount:se,originalPathById:k}=Bq(V,g,_);b=se;let O=V.prepare("SELECT id, prompt_file FROM queue").all();N=O.length;for(let $ of O){if(Vr($.prompt_file))continue;let q=k.get($.id);Vr(q)?P.push(`#${$.id} -> ${$.prompt_file}`):J.push(`#${$.id} -> ${$.prompt_file}`)}}finally{V.close()}}return{sourceDir:t,targetDir:r,stateDbCopied:p,replacedExistingTargetDb:h,queueFilesCopied:E,promptFilesCopied:T,rewrittenPromptPaths:b,queueRowCount:N,missingPromptFiles:P,preExistingMissingPromptFiles:J,siteIdentityCopied:I,siteIdentityMismatch:x,lmtPeersCopied:w,rowCountParity:ee}}finally{for(let p of f.splice(0))p.release()}}async function Yv(e={}){let t=e.source??Vv(),r=e.target??Jv(),n=await zv({sourceDir:t,targetDir:r,replaceExistingTargetDb:e.replaceExistingTargetDb});return{output:Jq(n),exitCode:Wq(n)}}function Wq(e){return e.missingPromptFiles.length>0||e.siteIdentityMismatch||Gq(e)?1:0}function Gq(e){return Object.values(e.rowCountParity).some(t=>t.source!==t.target)}function Vq(e){let t=Object.entries(e).filter(([,r])=>r.source!==r.target);return t.length===0?` table row-count parity: OK (${Object.keys(e).length} table(s) checked, all match)`:` PARITY CHECK FAILED -- ${t.length} table(s) with a source/target row-count mismatch:
910
+ `)}function Dq(e){return Array.isArray(e?.teams)?e.teams.length:void 0}function Mq(e){return typeof e?.live=="boolean"?`live:${e.live}`:void 0}function Pv(){return"usage: lmbee exec <site-uuid-or-mailbox> [--wait-s N] <command...> | lmbee exec <site-uuid-or-mailbox> [--wait-s N] -- <literal command...>"}function Rd(){return"usage: lmbee fleet status [--json] [--wait-s N]"}function Uv(e,t){return wo(e,t,r=>new Mt(r))}function Pq(e){let t=e.indexOf("--"),r=t<0?[...e]:[...e.slice(0,t)],n=t<0?void 0:e.slice(t+1),o=Uv(r,"--wait-s"),s=o===void 0?void 0:Number(o);if(s!==void 0&&(!Number.isFinite(s)||s<=0))throw new Mt("--wait-s must be positive");let i=r.shift();if(!i)throw new Mt(Pv());let a=n??r;if(n&&r.length>0)throw new Mt(`unexpected argument before --: ${r[0]}`);if(a.length===0)throw new Mt(Pv());return{target:i,command:a.join(" "),...s===void 0?{}:{waitSeconds:s}}}async function Fv(e){try{let{target:t,command:r,waitSeconds:n}=Pq(e),o=await hv(t,r,{waitSeconds:n});return{output:`${o.stdout}${o.stderr}`.replace(/\n$/,""),exitCode:o.exitCode}}catch(t){return{output:t instanceof Error?t.message:String(t),exitCode:t instanceof Mt?1:2}}}async function qv(e){let[t,...r]=e;if(t!=="status")return{output:Rd(),exitCode:1};let n=r.includes("--json");try{let o=[...r],s=o.indexOf("--json");n&&o.splice(s,1);let i=Uv(o,"--wait-s"),a=i===void 0?void 0:Number(i);if(a!==void 0&&(!Number.isFinite(a)||a<=0))return{output:Rd(),exitCode:1};if(o.length>0)return{output:Rd(),exitCode:1};let c=await Dv({waitSeconds:a});return{output:n?JSON.stringify(c,null,2):Mv(c),exitCode:c.exit_code}}catch(o){let s=o instanceof Error?o.message:String(o),i=o instanceof Mt?1:2;return{output:n?JSON.stringify({verdict:"error",exit_code:i,error:s},null,2):s,exitCode:i}}}import{cpSync as Ba,existsSync as Vr,mkdirSync as Uq,readFileSync as Nd,readdirSync as Fq,rmSync as jv,statSync as Hv}from"node:fs";import{homedir as Gv}from"node:os";import{join as et,sep as Id}from"node:path";var Eo=class extends Error{constructor(t){super(`migrate-home: refusing to run -- an lmauto daemon appears to be live (${t}). Stop it first (systemctl --user stop lmauto.service if it runs as a service, or kill the pid) before re-running.`),this.name="DaemonLiveError"}},Ld=class extends Error{targetDbPath;sizeBytes;constructor(t,r){super(`migrate-home: refusing to replace an existing target database: ${t} already exists (${r} bytes). migrate-home never deletes a database it did not create this run. If this file is debris from an interrupted migrate-home run, or you are certain it is disposable, re-run with --replace-existing-target-db; otherwise move it aside yourself (e.g. \`mv ${t} ${t}.bak\`) and re-run.`),this.targetDbPath=t,this.sizeBytes=r,this.name="TargetDbExistsError"}};function Vv(){return et(Gv(),".lmauto")}function Jv(){return et(process.env.LMCTL_HOME??et(Gv(),".lmctl"),"lmauto")}function qq(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}async function jq(e){try{return(await fetch(`http://127.0.0.1:${e}/api/teams`,{signal:AbortSignal.timeout(1e3)})).body?.cancel(),!0}catch{return!1}}function Hq(e,t){let r=et(e,"serve.pid");if(!Vr(r))return null;let n=Nd(r,"utf8").trim(),o=Number(n);return!Number.isInteger(o)||o<=0?null:t(o)?o:null}var Bv=["team_state","kv","events","queue","sources","team_progress","mail_ledger","mail_outbound_ledger"];function Wv(e,t){return e.prepare(`SELECT COUNT(*) as n FROM ${t}`).get().n}function Cd(e){if(!Vr(e))return 0;let t=0;for(let r of Fq(e,{withFileTypes:!0}))r.isDirectory()?t+=Cd(et(e,r.name)):t+=1;return t}function Bq(e,t,r){let n=t.endsWith(Id)?t:t+Id,o=e.prepare("SELECT id, prompt_file FROM queue").all(),s=new Map(o.map(l=>[l.id,l.prompt_file])),i=o.filter(l=>l.prompt_file.startsWith(n)),a=e.prepare("UPDATE queue SET prompt_file = ? WHERE id = ?");return e.transaction(l=>{for(let u of l){let d=r+u.prompt_file.slice(t.length);a.run(d,u.id)}})(i),{rewrittenCount:i.length,originalPathById:s}}async function zv(e){let{sourceDir:t,targetDir:r,port:n=4173}=e,o=e.isDaemonAlive??qq,s=e.probeHttpAlive??jq,i=e.checkSiteLock??M_,a=et(t,"state.db"),c=et(r,"state.db"),l=i(a);if(l!==null)throw new Eo(`${l.ownerLabel} pid ${l.pid} (site lock for ${a})`);let u=Hq(t,o);if(u!==null)throw new Eo(`pid ${u}, ${et(t,"serve.pid")}`);if(await s(n))throw new Eo(`something is listening on port ${n}`);if(t===r||r.startsWith(t+Id))throw new Error(`migrate-home: target (${r}) must not be, or be nested inside, source (${t})`);let d=e.acquireSiteLock??_a,m=us(a),f=[];try{f.push(d(m,"migrate-home")),f.push(d(et(t,"site.lock"),"migrate-home"))}catch(p){for(let h of f.splice(0))h.release();throw p instanceof Qn?new Eo(`${p.holder.ownerLabel} pid ${p.holder.pid}, ${p.lockPath}`):p}try{Uq(r,{recursive:!0});let p=!1,h=!1;if(Vr(a)){let oe=Vr(c);if(oe&&e.replaceExistingTargetDb!==!0)throw new Ld(c,Hv(c).size);let J=new wt(a);try{if(J.prepare("SELECT COUNT(*) AS n FROM sqlite_master").get(),oe){process.stderr.write(`migrate-home: replacing existing target database ${c} (${Hv(c).size} bytes) with a snapshot of ${a} (explicit replaceExistingTargetDb consent)
911
+ `);for(let se of["","-wal","-shm"])jv(c+se,{force:!0});h=!0}else for(let se of["-wal","-shm"])jv(c+se,{force:!0});J.prepare("VACUUM INTO ?").run(c)}finally{J.close()}p=!0}let g=et(t,"queue"),_=et(r,"queue"),E=Cd(g);E>0&&Ba(g,_,{recursive:!0});let y=et(t,"prompts"),S=et(r,"prompts"),T=Cd(y);T>0&&Ba(y,S,{recursive:!0});let R=et(t,"site-uuid"),A=et(r,"site-uuid"),I=!1,x=!1;Vr(R)&&(Ba(R,A),I=!0,x=Nd(R,"utf8")!==Nd(A,"utf8"));let H=et(t,"lmt-peers.json"),C=et(r,"lmt-peers.json"),w=!1;Vr(H)&&(Ba(H,C),w=!0);let b=0,N=0,M=[],W=[],ee={};if(p){let oe=new wt(a,{readonly:!0});try{for(let se of Bv)ee[se]={source:Wv(oe,se),target:0}}finally{oe.close()}let J=new wt(c);try{for(let $ of Bv)ee[$].target=Wv(J,$);let{rewrittenCount:se,originalPathById:k}=Bq(J,g,_);b=se;let O=J.prepare("SELECT id, prompt_file FROM queue").all();N=O.length;for(let $ of O){if(Vr($.prompt_file))continue;let q=k.get($.id);Vr(q)?M.push(`#${$.id} -> ${$.prompt_file}`):W.push(`#${$.id} -> ${$.prompt_file}`)}}finally{J.close()}}return{sourceDir:t,targetDir:r,stateDbCopied:p,replacedExistingTargetDb:h,queueFilesCopied:E,promptFilesCopied:T,rewrittenPromptPaths:b,queueRowCount:N,missingPromptFiles:M,preExistingMissingPromptFiles:W,siteIdentityCopied:I,siteIdentityMismatch:x,lmtPeersCopied:w,rowCountParity:ee}}finally{for(let p of f.splice(0))p.release()}}async function Yv(e={}){let t=e.source??Vv(),r=e.target??Jv(),n=await zv({sourceDir:t,targetDir:r,replaceExistingTargetDb:e.replaceExistingTargetDb});return{output:Jq(n),exitCode:Wq(n)}}function Wq(e){return e.missingPromptFiles.length>0||e.siteIdentityMismatch||Gq(e)?1:0}function Gq(e){return Object.values(e.rowCountParity).some(t=>t.source!==t.target)}function Vq(e){let t=Object.entries(e).filter(([,r])=>r.source!==r.target);return t.length===0?` table row-count parity: OK (${Object.keys(e).length} table(s) checked, all match)`:` PARITY CHECK FAILED -- ${t.length} table(s) with a source/target row-count mismatch:
912
912
  `+t.map(([r,n])=>` ${r}: source=${n.source}, target=${n.target}`).join(`
913
913
  `)}function Jq(e){return[`migrate-home: ${e.sourceDir} -> ${e.targetDir}`,e.replacedExistingTargetDb?" REPLACED an existing target database: the previous state.db in the target dir was DELETED (explicit --replace-existing-target-db consent) and replaced by the source snapshot":null,` state.db copied: ${e.stateDbCopied?"yes":"no (no source state.db found)"}`,` queue files copied: ${e.queueFilesCopied}`,` prompt files copied: ${e.promptFilesCopied}`,` prompt_file paths rewritten (new DB only): ${e.rewrittenPromptPaths}`,` queue rows in new DB: ${e.queueRowCount}`,e.missingPromptFiles.length>0?` PARITY CHECK FAILED -- ${e.missingPromptFiles.length} missing prompt file(s) that existed in source but not in the new copy:
914
914
  `+e.missingPromptFiles.map(r=>` ${r}`).join(`
@@ -997,12 +997,12 @@ Stop it with: kill ${s.pid??"<pid>"}
997
997
  `),1;let A=fn(r["maintainer-stale-threshold-ms"],"--maintainer-stale-threshold-ms");if(A instanceof Error)return process.stderr.write(`error: ${A.message}
998
998
  `),1;let I=fn(r["maintainer-activity-freshness-ms"],"--maintainer-activity-freshness-ms");if(I instanceof Error)return process.stderr.write(`error: ${I.message}
999
999
  `),1;if(I!==void 0&&y===void 0)return process.stderr.write(`error: --maintainer-activity-freshness-ms requires --maintainer-team and --maintainer-prompt-file
1000
- `),1;let x=y!==void 0&&S!==void 0?{teamName:y,promptFile:S,...T!==void 0?{sessionAlivePath:T}:{},...R!==void 0?{sessionAliveFreshnessMs:R}:{},...I!==void 0?{activityFreshnessMs:I}:{},...A!==void 0?{maintainerStaleThresholdMs:A}:{}}:void 0,H=r["auto-continue"]===!0?{}:void 0,C=r["miniplayer-verify"]===!0?{}:void 0,w=r["hung-holder-check"]===!0?{}:void 0,b=r["epic-review"]===!0?{}:void 0,N=r["orphan-reconciler-dry-run"]===!0,P=r["orphan-reconciler"]===!0||N?{dryRun:N}:void 0,J=r["hang-probe-collect"]===!0?{}:void 0,ee=r["auto-nudge-redirect-review"]===!0?!0:void 0,oe=r["rate-limit-collect"]===!0?{}:void 0,V=r["rate-limit-policy"]===!0?{}:void 0,se=r["rate-limit-automation"]===!0?{}:void 0,k=fn(r["idle-threshold-ms"],"--idle-threshold-ms"),O=fn(r["cooldown-ms"],"--cooldown-ms");if(k instanceof Error)return process.stderr.write(`error: ${k.message}
1000
+ `),1;let x=y!==void 0&&S!==void 0?{teamName:y,promptFile:S,...T!==void 0?{sessionAlivePath:T}:{},...R!==void 0?{sessionAliveFreshnessMs:R}:{},...I!==void 0?{activityFreshnessMs:I}:{},...A!==void 0?{maintainerStaleThresholdMs:A}:{}}:void 0,H=r["auto-continue"]===!0?{}:void 0,C=r["miniplayer-verify"]===!0?{}:void 0,w=r["hung-holder-check"]===!0?{}:void 0,b=r["epic-review"]===!0?{}:void 0,N=r["orphan-reconciler-dry-run"]===!0,M=r["orphan-reconciler"]===!0||N?{dryRun:N}:void 0,W=r["hang-probe-collect"]===!0?{}:void 0,ee=r["auto-nudge-redirect-review"]===!0?!0:void 0,oe=r["rate-limit-collect"]===!0?{}:void 0,J=r["rate-limit-policy"]===!0?{}:void 0,se=r["rate-limit-automation"]===!0?{}:void 0,k=fn(r["idle-threshold-ms"],"--idle-threshold-ms"),O=fn(r["cooldown-ms"],"--cooldown-ms");if(k instanceof Error)return process.stderr.write(`error: ${k.message}
1001
1001
  `),1;if(O instanceof Error)return process.stderr.write(`error: ${O.message}
1002
1002
  `),1;let $=co(r["min-memory-percent"],"--min-memory-percent");if($ instanceof Error)return process.stderr.write(`error: ${$.message}
1003
- `),1;let q=$??Cc,M=k!==void 0||O!==void 0?{idleThresholdMs:k??pe.idleThresholdMs,cooldownMs:O??pe.cooldownMs}:void 0,Z;try{Z=await WE({context:n,...f!==void 0?{port:f}:{},...p!==void 0?{publish:p}:{},...h!==void 0?{hostname:h}:{},..._!==void 0?{intervalMs:_}:{},...E!==void 0?{queueIntervalMs:E}:{},...M!==void 0?{config:M}:{},...x!==void 0?{maintainerWake:x}:{},...b!==void 0?{epicReview:b}:{},...P!==void 0?{orphanReconciler:P}:{},...J!==void 0?{hangProbeCollect:J}:{},...ee!==void 0?{autoNudgeRedirectReview:ee}:{},...oe!==void 0?{rateLimitCollect:oe}:{},...V!==void 0?{rateLimitPolicy:V}:{},...se!==void 0?{rateLimitAutomation:se}:{},...H!==void 0?{autoContinue:H}:{},...C!==void 0?{miniplayerVerify:C}:{},...w!==void 0?{hungHolderCheck:w}:{},...i!==void 0?{remoteMail:i}:{},...m!==void 0?{execWorker:m}:{},...g!==void 0?{webDistDir:g}:{},minMemoryPercent:q})}catch(ne){return process.stderr.write(`${ne instanceof Error?ne.message:String(ne)}
1003
+ `),1;let q=$??Cc,U=k!==void 0||O!==void 0?{idleThresholdMs:k??pe.idleThresholdMs,cooldownMs:O??pe.cooldownMs}:void 0,Z;try{Z=await WE({context:n,...f!==void 0?{port:f}:{},...p!==void 0?{publish:p}:{},...h!==void 0?{hostname:h}:{},..._!==void 0?{intervalMs:_}:{},...E!==void 0?{queueIntervalMs:E}:{},...U!==void 0?{config:U}:{},...x!==void 0?{maintainerWake:x}:{},...b!==void 0?{epicReview:b}:{},...M!==void 0?{orphanReconciler:M}:{},...W!==void 0?{hangProbeCollect:W}:{},...ee!==void 0?{autoNudgeRedirectReview:ee}:{},...oe!==void 0?{rateLimitCollect:oe}:{},...J!==void 0?{rateLimitPolicy:J}:{},...se!==void 0?{rateLimitAutomation:se}:{},...H!==void 0?{autoContinue:H}:{},...C!==void 0?{miniplayerVerify:C}:{},...w!==void 0?{hungHolderCheck:w}:{},...i!==void 0?{remoteMail:i}:{},...m!==void 0?{execWorker:m}:{},...g!==void 0?{webDistDir:g}:{},minMemoryPercent:q})}catch(ne){return process.stderr.write(`${ne instanceof Error?ne.message:String(ne)}
1004
1004
  `),n.db.close(),1}process.stdout.write(`lmbee serve: listening on http://${Z.hostname}:${Z.port}
1005
- `);let W=el();process.stdout.write(`lmbee serve: build ${W.sha}${W.dirty?" (dirty)":""}, built ${W.builtAt}
1005
+ `);let G=el();process.stdout.write(`lmbee serve: build ${G.sha}${G.dirty?" (dirty)":""}, built ${G.builtAt}
1006
1006
  `);let ae=!1,be=()=>{ae||(ae=!0,Z.shutdown().catch(ne=>{process.stderr.write(`lmbee serve: error during graceful shutdown: ${ne instanceof Error?ne.message:String(ne)}
1007
1007
  `)}).finally(()=>{n.db.close(),process.exit(0)}))};return process.on("SIGINT",be),process.on("SIGTERM",be),new Promise(()=>{})}if(e[0]==="whoami"){let{flags:r}=Tt(e.slice(1),["json"]),{output:n,exitCode:o}=await Wy({json:r.json===!0});return n&&process.stdout.write(`${n}
1008
1008
  `),o}if(e[0]==="peers"||e[0]==="tell"||e[0]==="sites"){let r=e.slice(1),{output:n,exitCode:o}=e[0]==="peers"?await AA(r):e[0]==="tell"?await $A(r):await kA(r);return n&&process.stdout.write(`${n}
@@ -1014,7 +1014,7 @@ Stop it with: kill ${s.pid??"<pid>"}
1014
1014
  `),1;let o=typeof r.source=="string"?r.source:void 0,s=typeof r.target=="string"?r.target:void 0;try{let{output:i,exitCode:a}=await Yv({source:o,target:s,replaceExistingTargetDb:r["replace-existing-target-db"]===!0});return i&&process.stdout.write(`${i}
1015
1015
  `),a}catch(i){return process.stderr.write(Ao(i)),1}}if(e[0]==="shutdown"){let{flags:r}=Tt(e.slice(1),["help","force"]);if(r.help===!0)return process.stdout.write(`${Hr}
1016
1016
  `),0;let{output:n,exitCode:o}=await xA({force:r.force===!0});return n&&process.stdout.write(n),o}if(e[0]==="cron"&&e[1]==="export")try{let{output:r,exitCode:n}=zE(e.slice(2));return r&&process.stdout.write(`${r}
1017
- `),n}catch(r){return process.stderr.write(Ao(r)),1}if(e[0]==="cron"&&e[1]==="import"){let{positionals:r,flags:n}=Tt(e.slice(2),["json","help"]);if(n.help!==!0){let o=n.json===!0;try{_s("import",r,n);let s=r[0];if(s===void 0)throw new U("INVALID_ARGUMENT","an import PATH is required");QE(s)}catch(s){if(s instanceof U)return process.stdout.write(o?`${JSON.stringify({schema_version:1,ok:!1,error:{code:s.code,message:s.message}})}
1017
+ `),n}catch(r){return process.stderr.write(Ao(r)),1}if(e[0]==="cron"&&e[1]==="import"){let{positionals:r,flags:n}=Tt(e.slice(2),["json","help"]);if(n.help!==!0){let o=n.json===!0;try{_s("import",r,n);let s=r[0];if(s===void 0)throw new P("INVALID_ARGUMENT","an import PATH is required");QE(s)}catch(s){if(s instanceof P)return process.stdout.write(o?`${JSON.stringify({schema_version:1,ok:!1,error:{code:s.code,message:s.message}})}
1018
1018
  `:`${s.code}: ${s.message}
1019
1019
  `),s.exitCode;throw s}}}let t;try{t=Ni({readOnly:lT(e)});let{output:r,exitCode:n}=await uT(t,e);return r&&process.stdout.write(`${r}
1020
1020
  `),n}catch(r){return process.stderr.write(Ao(r)),1}finally{t?.db.close()}}j1().then(e=>{process.exitCode=e});